use of org.finos.legend.engine.language.pure.compiler.toPureGraph.handlers.UserDefinedFunctionHandler in project legend-engine by finos.
the class PackageableElementFirstPassBuilder method visit.
@Override
public PackageableElement visit(Function function) {
// NOTE: in the protocol, we still store the function name as is, but in the function index, we will store the function based on its function signature
String functionSignature = HelperModelBuilder.getSignature(function);
String functionFullName = this.context.pureModel.buildPackageString(function._package, functionSignature);
String functionName = this.context.pureModel.buildPackageString(function._package, HelperModelBuilder.getFunctionNameWithoutSignature(function));
final org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition<?> targetFunc = new Root_meta_pure_metamodel_function_ConcreteFunctionDefinition_Impl<>(functionSignature, SourceInformationHelper.toM3SourceInformation(function.sourceInformation), null);
this.context.pureModel.functionsIndex.put(functionFullName, targetFunc);
ProcessingContext ctx = new ProcessingContext("Function '" + functionFullName + "' First Pass");
org.finos.legend.pure.m3.coreinstance.Package pack = this.context.pureModel.getOrCreatePackage(function._package);
org.finos.legend.pure.m3.coreinstance.meta.pure.metamodel.function.ConcreteFunctionDefinition<?> res = targetFunc._name(// function signature here - e.g. isAfterDay_Date_1__Date_1__Boolean_1_
HelperModelBuilder.getTerseSignature(function))._functionName(// function name to be used in the handler map -> meta::pure::functions::date::isAfterDay
functionName)._classifierGenericType(new Root_meta_pure_metamodel_type_generics_GenericType_Impl("")._rawType(this.context.pureModel.getType("meta::pure::metamodel::function::ConcreteFunctionDefinition"))._typeArguments(Lists.fixedSize.of(PureModel.buildFunctionType(ListIterate.collect(function.parameters, p -> (VariableExpression) p.accept(new ValueSpecificationBuilder(this.context, Lists.mutable.empty(), ctx))), this.context.resolveGenericType(function.returnType, function.sourceInformation), this.context.pureModel.getMultiplicity(function.returnMultiplicity)))))._stereotypes(ListIterate.collect(function.stereotypes, s -> this.context.resolveStereotype(s.profile, s.value, s.profileSourceInformation, s.sourceInformation)))._taggedValues(ListIterate.collect(function.taggedValues, t -> new Root_meta_pure_metamodel_extension_TaggedValue_Impl("")._tag(this.context.resolveTag(t.tag.profile, t.tag.value, t.tag.profileSourceInformation, t.sourceInformation))._value(t.value)))._package(pack);
HelperModelBuilder.processFunctionConstraints(function, this.context, res, ctx);
pack._childrenAdd(res);
this.context.pureModel.handlers.register(new UserDefinedFunctionHandler(functionFullName, res, ps -> new TypeAndMultiplicity(this.context.resolveGenericType(function.returnType, function.sourceInformation), this.context.pureModel.getMultiplicity(function.returnMultiplicity)), ps -> {
List<ValueSpecification> vs = ListIterate.collect(function.parameters, p -> p.accept(new ValueSpecificationBuilder(this.context, Lists.mutable.empty(), ctx)));
if (ps.size() == function.parameters.size()) {
int size = ps.size();
// TODO clean up the check....
try {
for (int i = 0; i < size; i++) {
HelperModelBuilder.checkCompatibility(this.context, ps.get(i)._genericType()._rawType(), ps.get(i)._multiplicity(), vs.get(i)._genericType()._rawType(), vs.get(i)._multiplicity(), "Error in function '" + functionFullName + "'", function.body.get(function.body.size() - 1).sourceInformation);
}
} catch (Exception e) {
return false;
}
return true;
}
return false;
}));
return res;
}
Aggregations