private static IFunctionSignature BuildFunctionAndPutItToDictionary( UserFunctionDefinitionSyntaxNode functionSyntaxNode, IConstantList constants, ScopeFunctionDictionary functionsDictionary) { #if DEBUG TraceLog.WriteLine($"\r\n====BUILD {functionSyntaxNode.Id}(..) ===="); #endif ////introduce function variable var graphBuider = new GraphBuilder(); var resultsBuilder = new TypeInferenceResultsBuilder(); ITicResults types; try { if (!TicSetupVisitor.SetupTicForUserFunction( userFunctionNode: functionSyntaxNode, ticGraph: graphBuider, functions: functionsDictionary, constants: constants, results: resultsBuilder)) { throw FunParseException.ErrorStubToDo($"Function '{functionSyntaxNode.Id}' is not solved"); } // solve the types types = graphBuider.Solve(); } catch (TicException e) { throw ErrorFactory.TranslateTicError(e, functionSyntaxNode); } resultsBuilder.SetResults(types); var typeInferenceResuls = resultsBuilder.Build(); if (!types.HasGenerics) { #region concreteFunction //set types to nodes functionSyntaxNode.ComeOver( enterVisitor: new ApplyTiResultEnterVisitor( solving: typeInferenceResuls, tiToLangTypeConverter: TicTypesConverter.Concrete), exitVisitor: new ApplyTiResultsExitVisitor()); var funType = TicTypesConverter.Concrete.Convert( typeInferenceResuls.GetVariableType(functionSyntaxNode.Id + "'" + functionSyntaxNode.Args.Count)); var returnType = funType.FunTypeSpecification.Output; var argTypes = funType.FunTypeSpecification.Inputs; if (TraceLog.IsEnabled) { TraceLog.WriteLine($"\r\n=====> Generic {functionSyntaxNode.Id} {funType}"); } //make function prototype var prototype = new ConcreteUserFunctionPrototype(functionSyntaxNode.Id, returnType, argTypes); //add prototype to dictionary for future use functionsDictionary.Add(prototype); var function = functionSyntaxNode.BuildConcrete( argTypes: argTypes, returnType: returnType, functionsDictionary: functionsDictionary, results: typeInferenceResuls, converter: TicTypesConverter.Concrete); prototype.SetActual(function, functionSyntaxNode.Interval); return(function); #endregion } else { var function = GenericUserFunction.Create(typeInferenceResuls, functionSyntaxNode, functionsDictionary); functionsDictionary.Add(function); if (TraceLog.IsEnabled) { TraceLog.WriteLine($"\r\n=====> Concrete {functionSyntaxNode.Id} {function}"); } return(function); } }