use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition in project legend-pure by finos.
the class FunctionDefinitionProcessor method process.
public static void process(FunctionDefinition<?> functionDefinition, ProcessorState state, Matcher matcher, ModelRepository repository) {
ProcessorSupport processorSupport = state.getProcessorSupport();
VariableContext variableContext = state.getVariableContext();
FunctionType functionType = (FunctionType) processorSupport.function_getFunctionType(functionDefinition);
state.getObserver().startProcessingFunction(functionDefinition, functionType);
URLPatternLibrary urlPatternLibrary = state.getURLPatternLibrary();
if (urlPatternLibrary != null) {
urlPatternLibrary.possiblyRegister(functionDefinition, processorSupport);
}
boolean shouldSetTypeInferenceContext = (functionDefinition instanceof ConcreteFunctionDefinition) && (functionDefinition._classifierGenericType() != null) && (functionDefinition._classifierGenericType()._rawTypeCoreInstance() != null) && "ConcreteFunctionDefinition".equals(functionDefinition._classifierGenericType()._rawTypeCoreInstance().getName());
if (shouldSetTypeInferenceContext) {
state.newTypeInferenceContext(functionType);
}
functionType._parameters().forEach(var -> {
try {
variableContext.registerValue(var._name(), var);
} catch (VariableNameConflictException e) {
throw new PureCompilationException(functionDefinition.getSourceInformation(), e.getMessage());
}
GenericType propertyType = var._genericType();
// The property type may be null if it's a lambda expression...
if (propertyType != null) {
// We resolve because we want to fail fast if a given type is unknown...
org.finos.legend.pure.m3.navigation.generictype.GenericType.resolveGenericTypeUsingImports(propertyType, repository, processorSupport);
}
});
ListIterable<? extends ValueSpecification> expressions = functionDefinition._expressionSequence().toList();
if (expressions.isEmpty()) {
throw new PureCompilationException(functionDefinition.getSourceInformation(), "Function definition must contain at least one expression");
}
// The function is going to be processed again after inference
if (TypeInference.canProcessLambda(functionDefinition, state, processorSupport)) {
state.getObserver().shiftTab();
state.getObserver().startProcessingFunctionBody();
processExpressions(functionDefinition, expressions, matcher, state, processorSupport);
findReturnTypesForLambda(functionDefinition, functionType, processorSupport);
FunctionDefinitionValidator.validateFunctionReturnType(functionDefinition, functionType, processorSupport);
state.getObserver().finishedProcessingFunctionBody();
state.getObserver().unShiftTab();
state.addFunctionDefinition(functionDefinition);
}
if (shouldSetTypeInferenceContext) {
state.deleteTypeInferenceContext();
}
state.getVariableContext().buildAndRegister("return", functionType._returnType(), functionType._returnMultiplicity(), processorSupport);
RichIterable<? extends Constraint> constraints = functionDefinition._preConstraints();
if (constraints.notEmpty()) {
processConstraints(functionDefinition, constraints.toList(), matcher, state, processorSupport);
}
RichIterable<? extends Constraint> postConstraints = functionDefinition._postConstraints();
if (postConstraints.notEmpty()) {
processConstraints(functionDefinition, postConstraints.toList(), matcher, state, processorSupport);
}
state.getObserver().finishedProcessingFunction(functionType);
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition in project legend-pure by finos.
the class TestMultiplicity method testSingleLiteralMultiplicity.
@Test
public void testSingleLiteralMultiplicity() {
compileTestSource("fromString.pure", "function test::testFn():Any[*]\n" + "{\n" + " 1\n" + "}");
ConcreteFunctionDefinition testFn = (ConcreteFunctionDefinition) this.runtime.getFunction("test::testFn():Any[*]");
Assert.assertNotNull(testFn);
ListIterable<ValueSpecification> expressions = (ListIterable<ValueSpecification>) testFn._expressionSequence();
Verify.assertSize(1, expressions);
ValueSpecification expression = expressions.get(0);
CoreInstance multiplicity = expression._multiplicity();
Assert.assertEquals(1, Multiplicity.multiplicityLowerBoundToInt(multiplicity));
Assert.assertEquals(1, Multiplicity.multiplicityUpperBoundToInt(multiplicity));
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition in project legend-pure by finos.
the class TestMultiplicity method testSingleFunctionExpressionMultiplicity.
@Test
public void testSingleFunctionExpressionMultiplicity() {
compileTestSource("fromString.pure", "function test::testFn():Any[*]\n" + "{\n" + " [1, 2, 3]->first();\n" + "}");
ConcreteFunctionDefinition testFn = (ConcreteFunctionDefinition) this.runtime.getFunction("test::testFn():Any[*]");
Assert.assertNotNull(testFn);
ListIterable<ValueSpecification> expressions = (ListIterable<ValueSpecification>) testFn._expressionSequence();
Verify.assertSize(1, expressions);
ValueSpecification expression = expressions.get(0);
CoreInstance multiplicity = expression._multiplicity();
Assert.assertEquals(0, Multiplicity.multiplicityLowerBoundToInt(multiplicity));
Assert.assertEquals(1, Multiplicity.multiplicityUpperBoundToInt(multiplicity));
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition in project legend-pure by finos.
the class TestMultiplicity method testSingleFunctionExpressionCollectionMultiplicity.
@Test
public void testSingleFunctionExpressionCollectionMultiplicity() {
compileTestSource("fromString.pure", "function test::testFn():Any[*]\n" + "{\n" + " [[1, 2, 3]->first()];\n" + "}");
ConcreteFunctionDefinition testFn = (ConcreteFunctionDefinition) this.runtime.getFunction("test::testFn():Any[*]");
Assert.assertNotNull(testFn);
ListIterable<ValueSpecification> expressions = (ListIterable<ValueSpecification>) testFn._expressionSequence();
Verify.assertSize(1, expressions);
ValueSpecification expression = expressions.get(0);
CoreInstance multiplicity = expression._multiplicity();
Assert.assertEquals(0, Multiplicity.multiplicityLowerBoundToInt(multiplicity));
Assert.assertEquals(1, Multiplicity.multiplicityUpperBoundToInt(multiplicity));
}
use of org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition in project legend-pure by finos.
the class TestMultiplicity method testLiteralCollectionMultiplicity.
@Test
public void testLiteralCollectionMultiplicity() {
compileTestSource("fromString.pure", "function test::testFn():Any[*]\n" + "{\n" + " [1, 2, 3]\n" + "}");
ConcreteFunctionDefinition testFn = (ConcreteFunctionDefinition) this.runtime.getFunction("test::testFn():Any[*]");
Assert.assertNotNull(testFn);
ListIterable<ValueSpecification> expressions = (ListIterable<ValueSpecification>) testFn._expressionSequence();
Verify.assertSize(1, expressions);
ValueSpecification expression = expressions.get(0);
CoreInstance multiplicity = expression._multiplicity();
Assert.assertEquals(3, Multiplicity.multiplicityLowerBoundToInt(multiplicity));
Assert.assertEquals(3, Multiplicity.multiplicityUpperBoundToInt(multiplicity));
}
Aggregations