package jetbrains.mps.core.aspects.behaviour.api;/*
* Copyright 2003-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
import org.jetbrains.mps.openapi.model.SNode;
/**
* Represents a behavior method for a given {@link org.jetbrains.mps.openapi.language.SAbstractConcept}
* It has a {@link SMethodId} which uniquely identifies the instance of {@link SMethod}.
*
* The supposed way to call behavior methods is as follows.
* If it is possible to get SMethod directly (from the generated fields of {@link BHDescriptor}) then one needs to
* take the method from there and invoke it via {@link #invoke} or {@link #invokeSpecial} or others.
*
* If it is not possible then one needs to get method by reflection from the {@link BHDescriptor} (via #getMethod).
* Currently there are handy invocation methods in the
* {@link jetbrains.mps.smodel.behaviour.BHReflection} facade.
*
* T -- java runtime return type (for compile-time checking)
*
* @see BHDescriptor
*/
public interface SMethod<T> extends SExecutable {
/**
* @return {@link SMethodId} which uniquely identifies the behavior methods within the concept
* NB: all inherited methods count as well
*/
@NotNull SMethodId getId();
/**
* @return the return type of the SMethod
*/
@NotNull SAbstractType getReturnType();
/**
* invokes the method (trying to resolve the right method on runtime if it is virtual)
* essentially invokes the #invoke0 method with the concept of the operand
*/
T invoke(@Nullable SNode operand, Object... parameters);
/**
* invokes the method in the case it is static (trying to resolve the right method on runtime if it is virtual)
*/
T invoke(@Nullable SAbstractConcept operand, Object... parameters);
/**
* invokes the virtual method as if applied to the node of the concreteConcept
*/
T invoke0(@Nullable SNode operand, @NotNull SAbstractConcept concreteConcept, Object... parameters);
T invoke0(@Nullable SAbstractConcept operand, @NotNull SAbstractConcept concreteConcept, Object... parameters);
/**
* invokes private method (no dynamic method resolve)
*/
T invokeSpecial(@Nullable SNode operand, Object... parameters);
/**
* invokes private method (no dynamic method resolve)
*/
T invokeSpecial(@Nullable SAbstractConcept operand, Object... parameters);
/**
* invokes virtual method looking for the ancestors of the node's concept (dynamic method resolve)
* @param concreteConcept is the concept from which the #invokeSuper is intended to be executed
*/
T invokeSuper(@Nullable SNode operand, @NotNull SAbstractConcept concreteConcept, Object... parameters);
/**
* invokes virtual method looking for the ancestors of the concept (dynamic method resolve)
* @param concreteConcept is the concept from which the #invokeSuper is intended to be executed
*/
T invokeSuper(@Nullable SAbstractConcept operand, @NotNull SAbstractConcept concreteConcept, Object... parameters);
/**
* @return true iff the method has a virtual modifier
* @see #getModifiers()
*/
boolean isVirtual();
/**
* abstract => virtual
* @return true iff the method has an abstract modifier
*/
boolean isAbstract();
/**
* @return true iff the method has a static modifier
* @see #getModifiers()
*/
boolean isStatic();
}