/*
* Copyright 2003-2017 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.
*/
package jetbrains.mps.smodel.runtime;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mps.openapi.language.SAbstractConcept;
/**
* Presents a constraint function.
*
* Constraint function supplies a {@link Context} in which constraint function are applied.
* Resulting constraint contains a "sequence" of objects that are applicable/valid in this context.
*
* In case, when result has {@code boolean} type, it means that supplied context is valid if function returns true.
*
* If constraint function returns {@code null}, it means that this constraint function doesn't provide any restrictions
* for these context. Basically, it means that any "object" is valid in this context.
*
* INHERITANCE NOTES:
*
* If constraint isn't defined externally, it should be calculated as composition of constraints defined in super concepts.
* For boolean-returning constraints it means that constraint composition returns true only if all super-concept constraints returns true.
* For scope-returning constraints it means that constraint composition returns a scope that contains nodes which are contained in all scopes
* provided via super-concept constraints.
* For other kinds it depends on implementation.
*
* Example:
*
* Assuming, there is concepts A, B, C, D:
* A extends B, C;
* B extends D;
* C extends D.
*
* There is no externally-defined 'can be child' constraint function (from now, CF) in concept A. Let predict calculated constraint function for cases:
* 1) CF defined only in B => CF for A returns same as CF for B
* 2) CF defined only in D => CF for A returns same as CF for D
* 3) CF defined in B and C => CF for A returns true only if CF for B & C returns true
* 4) CF defined in D and redefined in B => CF for A returns true only if CF for B & D returns true (but not only CF for B)
*
*
* @param <Context> constraint function context type.
* @param <Result> resulting constraint type.
*
* @see ConstraintFunctions
* @author Radimir.Sorokin
* @since 3.5
*/
public interface ConstraintFunction<Context, Result> {
@Nullable
Result invoke(@NotNull Context context, @Nullable CheckingNodeContext checkingNodeContext);
}