示例#1
0
        public CreateObjectAction(ParseInfo parseInfo, Scope scope, NewExpression context)
        {
            if (context.ClassIdentifier == null)
            {
                return;
            }

            // Get the type. Syntax error if there is no type name.
            CreatingObjectOf = parseInfo.TranslateInfo.Types.GetCodeType(context.ClassIdentifier.Text, parseInfo.Script.Diagnostics, context.ClassIdentifier.Range);

            if (CreatingObjectOf != null)
            {
                DocRange nameRange = context.ClassIdentifier.Range;

                // Get the constructor to use.
                OverloadChooser = new OverloadChooser(
                    CreatingObjectOf.Constructors, parseInfo, CreatingObjectOf.ReturningScope(), scope, nameRange, context.Range, new OverloadError("type " + CreatingObjectOf.Name)
                    );
                OverloadChooser.Apply(context.Parameters);

                Constructor       = (Constructor)OverloadChooser.Overload;
                ConstructorValues = OverloadChooser.Values ?? new IExpression[0];

                if (Constructor != null)
                {
                    parseInfo.TranslateInfo.GetComponent <SymbolLinkComponent>().AddSymbolLink(Constructor, new Location(parseInfo.Script.Uri, nameRange));
                    Constructor.Call(parseInfo, nameRange);
                    parseInfo.Script.AddHover(context.Range, Constructor.GetLabel(true));
                }
            }
        }
示例#2
0
        public IInvokeResult Invoke(InvokeData invokeInfo)
        {
            var parseInfo = invokeInfo.ParseInfo;

            // Create the overload chooser for the invoke function.
            var overloadChooser = new OverloadChooser(
                new MethodOverload[] { new MethodOverload(_lambdaType.InvokeFunction) },
                parseInfo,
                invokeInfo.Scope,
                invokeInfo.Getter,
                invokeInfo.TargetRange,
                invokeInfo.CallRange,
                invokeInfo.FullRange,
                new OverloadError("lambda '" + _lambdaType.GetName() + "'")
                );

            // Apply the parameters.
            overloadChooser.Apply(invokeInfo.Context.Parameters, false, null);

            var invoke = (LambdaInvoke)overloadChooser.Overload;

            invoke?.CheckRecursionAndRestricted(parseInfo, invokeInfo.TargetRange, invokeInfo.Target);

            if (invokeInfo.UsedAsExpression && !invoke.LambdaType.ReturnsValue)
            {
                parseInfo.Script.Diagnostics.Error("The lambda '" + invoke.LambdaType.GetName() + "' does not return a value", invokeInfo.TargetRange);
            }

            return(new LambdaInvokeResult(parseInfo.TranslateInfo, invoke, overloadChooser.ParameterResults, invokeInfo.Target));
        }
示例#3
0
        public CreateObjectAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Create_objectContext context)
        {
            // Get the type. Syntax error if there is no type name.
            if (context.type == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected a type name.", DocRange.GetRange(context.NEW()));
            }
            else
            {
                CreatingObjectOf = parseInfo.TranslateInfo.Types.GetCodeType(context.type.Text, parseInfo.Script.Diagnostics, DocRange.GetRange(context.type));
            }

            if (CreatingObjectOf != null)
            {
                DocRange nameRange = DocRange.GetRange(context.type);

                // Get the constructor to use.
                OverloadChooser = new OverloadChooser(
                    CreatingObjectOf.Constructors, parseInfo, CreatingObjectOf.ReturningScope(), scope, nameRange, DocRange.GetRange(context), new OverloadError("type " + CreatingObjectOf.Name)
                    );
                OverloadChooser.Apply(context.call_parameters());

                Constructor       = (Constructor)OverloadChooser.Overload;
                ConstructorValues = OverloadChooser.Values ?? new IExpression[0];

                if (Constructor != null)
                {
                    parseInfo.TranslateInfo.GetComponent <SymbolLinkComponent>().AddSymbolLink(Constructor, new Location(parseInfo.Script.Uri, nameRange));
                    Constructor.Call(parseInfo, DocRange.GetRange(context.type));
                    parseInfo.Script.AddHover(DocRange.GetRange(context), Constructor.GetLabel(true));
                }
            }
        }
        public IInvokeResult Invoke(InvokeData invokeInfo)
        {
            var parseInfo = invokeInfo.ParseInfo;

            // Create the overload chooser for the invoke function.
            var overloadChooser = new OverloadChooser(
                new IParameterCallable[] { _lambdaType.InvokeFunction },
                parseInfo,
                invokeInfo.Scope,
                invokeInfo.Getter,
                invokeInfo.TargetRange,
                invokeInfo.CallRange,
                new OverloadError("lambda '" + _lambdaType.GetName() + "'")
                );

            // Apply the parameters.
            overloadChooser.Apply(invokeInfo.Context.Parameters);

            var invoke = (LambdaInvoke)overloadChooser.Overload;

            invoke?.Call(parseInfo, invokeInfo.TargetRange);

            return(new LambdaInvokeResult(invoke, overloadChooser.Values, invokeInfo.Target));
            // return new FunctionInvokeResult(parseInfo, invokeInfo.TargetRange, invokeInfo.UsedAsExpression, invoke, overloadChooser.Values, overloadChooser.AdditionalParameterData, overloadChooser.Match);
        }
示例#5
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.parseInfo = parseInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            UsedAsExpression = usedAsExpression;

            if (methodContext.ASYNC() != null)
            {
                if (methodContext.NOT() == null)
                {
                    Parallel = CallParallel.AlreadyRunning_RestartRule;
                }
                else
                {
                    Parallel = CallParallel.AlreadyRunning_DoNothing;
                }
            }

            var options = scope.GetMethodsByName(methodName);

            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                OverloadChooser = new OverloadChooser(options, parseInfo, scope, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));
                OverloadChooser.Apply(methodContext.call_parameters());

                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                if (CallingMethod != null)
                {
                    CallingMethod.Call(parseInfo, NameRange);

                    // Todo: move this to DefinedFunction.Call.
                    if (CallingMethod is DefinedFunction definedFunction)
                    {
                        definedFunction.OnBlockApply(this);
                        parseInfo.CurrentCallInfo?.Call(definedFunction, NameRange);
                    }

                    if (Parallel != CallParallel.NoParallel && !CallingMethod.Attributes.Parallelable)
                    {
                        parseInfo.Script.Diagnostics.Error($"The method '{CallingMethod.Name}' cannot be called in parallel.", NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));
                }
            }
        }
示例#6
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.translateInfo = parseInfo.TranslateInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            var options = scope.GetMethodsByName(methodName);

            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                OverloadChooser = new OverloadChooser(options, parseInfo, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));

                if (methodContext.call_parameters() != null)
                {
                    OverloadChooser.SetContext(methodContext.call_parameters());
                }
                else if (methodContext.picky_parameters() != null)
                {
                    OverloadChooser.SetContext(methodContext.picky_parameters());
                }
                else
                {
                    OverloadChooser.SetContext();
                }

                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                if (CallingMethod != null)
                {
                    if (CallingMethod is DefinedFunction)
                    {
                        var definedFunction = (DefinedFunction)CallingMethod;
                        definedFunction.Call(parseInfo.Script, NameRange);
                        parseInfo.CurrentCallInfo?.Call(definedFunction, NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));

                    if (usedAsExpression && !CallingMethod.DoesReturnValue())
                    {
                        parseInfo.Script.Diagnostics.Error("The chosen overload for " + methodName + " does not return a value.", NameRange);
                    }
                }
            }
        }
        public IInvokeResult Invoke(InvokeData invokeInfo)
        {
            var         parseInfo = invokeInfo.ParseInfo;
            MethodGroup group     = ((CallMethodGroup)invokeInfo.Target).Group;

            // Make an OverloadChooser to choose an Overload.
            var overloadChooser = new OverloadChooser(group.Functions.ToArray(), parseInfo, invokeInfo.Scope, invokeInfo.Getter, invokeInfo.TargetRange, invokeInfo.CallRange, new OverloadError("method '" + group.Name + "'"));

            // Apply the parameters.
            overloadChooser.Apply(invokeInfo.Context.Parameters);

            // Get the best function.
            var callingMethod = (IMethod)overloadChooser.Overload;
            var result        = new FunctionInvokeResult(parseInfo, invokeInfo.TargetRange, invokeInfo.UsedAsExpression, callingMethod, overloadChooser.Values, overloadChooser.AdditionalParameterData, overloadChooser.Match);

            // CallingMethod may be null if no good functions are found.
            if (callingMethod != null)
            {
                callingMethod.Call(parseInfo, invokeInfo.TargetRange);

                // If the function's block needs to be applied, check optional restricted calls when 'Applied()' runs.
                if (callingMethod is IApplyBlock applyBlock)
                {
                    applyBlock.OnBlockApply(result);
                }
                else // Otherwise, the optional restricted calls can be resolved right away.
                {
                    // Get optional parameter's restricted calls.
                    overloadChooser.Match?.CheckOptionalsRestrictedCalls(parseInfo, invokeInfo.TargetRange);
                }

                // Check if the function can be called in parallel.
                if (parseInfo.AsyncInfo != null)
                {
                    if (!callingMethod.Attributes.Parallelable)
                    {
                        parseInfo.AsyncInfo.Reject($"The method '{callingMethod.Name}' cannot be called in parallel");
                    }
                    else
                    {
                        parseInfo.AsyncInfo.Accept();
                    }
                }

                parseInfo.Script.AddHover(invokeInfo.Context.Range, callingMethod.GetLabel(true));
            }

            return(result);
        }
示例#8
0
        public CreateObjectAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Create_objectContext context)
        {
            // Get the type. Syntax error if there is no type name.
            if (context.type == null)
            {
                parseInfo.Script.Diagnostics.Error("Expected a type name.", DocRange.GetRange(context.NEW()));
            }
            else
            {
                CreatingObjectOf = parseInfo.TranslateInfo.GetCodeType(context.type.Text, parseInfo.Script.Diagnostics, DocRange.GetRange(context.type));
            }

            if (CreatingObjectOf != null)
            {
                DocRange nameRange = DocRange.GetRange(context.type);

                // Get the constructor to use.
                OverloadChooser = new OverloadChooser(
                    CreatingObjectOf.Constructors, parseInfo, scope, nameRange, DocRange.GetRange(context), new OverloadError("type " + CreatingObjectOf.Name)
                    );

                if (context.call_parameters() != null)
                {
                    OverloadChooser.SetContext(context.call_parameters());
                }
                else
                {
                    OverloadChooser.SetContext();
                }

                Constructor       = (Constructor)OverloadChooser.Overload;
                ConstructorValues = OverloadChooser.Values ?? new IExpression[0];

                if (Constructor != null)
                {
                    Constructor.Call(parseInfo.Script, DocRange.GetRange(context.type));
                    parseInfo.Script.AddHover(DocRange.GetRange(context), Constructor.GetLabel(true));

                    if (Constructor is DefinedConstructor)
                    {
                        parseInfo.CurrentCallInfo.Call((DefinedConstructor)Constructor, nameRange);
                    }
                }
            }
        }
示例#9
0
        public CreateObjectAction(ParseInfo parseInfo, Scope scope, NewExpression context)
        {
            if (!context.Type.Valid)
            {
                CreatingObjectOf = parseInfo.Types.Any();
                return;
            }

            // Get the type. Syntax error if there is no type name.
            CreatingObjectOf = TypeFromContext.GetCodeTypeFromContext(parseInfo, scope, context.Type);

            DocRange nameRange = context.Type.GenericToken.Range;

            // Get the constructor to use.
            OverloadChooser = new OverloadChooser(
                CreatingObjectOf.Constructors.Select(c => new ConstructorOverload(c)).ToArray(),
                parseInfo,
                CreatingObjectOf.ReturningScope(),
                scope,
                nameRange,
                context.Range,
                context.Range,
                new OverloadError("type " + CreatingObjectOf.Name)
                );
            OverloadChooser.Apply(context.Parameters, false, null);

            Constructor = (Constructor)OverloadChooser.Overload;

            if (Constructor != null)
            {
                Constructor.Call(parseInfo, nameRange);
                parseInfo.Script.AddHover(context.Range, Constructor.GetLabel(parseInfo.TranslateInfo, LabelInfo.Hover));

                // Default restricted parameter values.
                OverloadChooser.Match.CheckOptionalsRestrictedCalls(parseInfo, nameRange);

                // Bridge other restricted values.
                if (Constructor.CallInfo != null)
                {
                    RestrictedCall.BridgeMethodCall(parseInfo, Constructor.CallInfo, nameRange, context.Type.GenericToken.Text, Constructor.RestrictedValuesAreFatal);
                }
            }
        }
示例#10
0
        public CallMethodAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.MethodContext methodContext, bool usedAsExpression, Scope getter)
        {
            this.parseInfo = parseInfo;
            string methodName = methodContext.PART().GetText();

            NameRange = DocRange.GetRange(methodContext.PART());

            UsedAsExpression = usedAsExpression;

            if (methodContext.ASYNC() != null)
            {
                if (methodContext.NOT() == null)
                {
                    Parallel = CallParallel.AlreadyRunning_RestartRule;
                }
                else
                {
                    Parallel = CallParallel.AlreadyRunning_DoNothing;
                }
            }

            // Get all functions with the same name in the current scope.
            var options = scope.GetMethodsByName(methodName);

            // If none are found, throw a syntax error.
            if (options.Length == 0)
            {
                parseInfo.Script.Diagnostics.Error($"No method by the name of '{methodName}' exists in the current context.", NameRange);
            }
            else
            {
                // Make an OverloadChooser to choose an Overload.
                OverloadChooser = new OverloadChooser(options, parseInfo, scope, getter, NameRange, DocRange.GetRange(methodContext), new OverloadError("method '" + methodName + "'"));
                // Apply the parameters.
                OverloadChooser.Apply(methodContext.call_parameters());

                // Get the best function.
                CallingMethod   = (IMethod)OverloadChooser.Overload;
                ParameterValues = OverloadChooser.Values;

                // CallingMethod may be null if no good functions are found.
                if (CallingMethod != null)
                {
                    CallingMethod.Call(parseInfo, NameRange);

                    // If the function's block needs to be applied, check optional restricted calls when 'Applied()' runs.
                    if (CallingMethod is IApplyBlock applyBlock)
                    {
                        applyBlock.OnBlockApply(this);
                    }
                    else // Otherwise, the optional restricted calls can be resolved right away.
                    {
                        // Get optional parameter's restricted calls.
                        OverloadChooser.Match?.CheckOptionalsRestrictedCalls(parseInfo, NameRange);
                    }

                    // Check if the function can be called in parallel.
                    if (Parallel != CallParallel.NoParallel && !CallingMethod.Attributes.Parallelable)
                    {
                        parseInfo.Script.Diagnostics.Error($"The method '{CallingMethod.Name}' cannot be called in parallel.", NameRange);
                    }

                    parseInfo.Script.AddHover(DocRange.GetRange(methodContext), CallingMethod.GetLabel(true));
                }
            }
        }
示例#11
0
 public void AddOverloadData(OverloadChooser overload)
 {
     overloads.Add(overload);
 }
示例#12
0
        public IInvokeResult Invoke(InvokeData invokeInfo)
        {
            var parseInfo = invokeInfo.ParseInfo;

            if (invokeInfo.Target is CallMethodGroup == false)
            {
                parseInfo.Script.Diagnostics.Error("Method name expected", invokeInfo.TargetRange);
                CallMethodAction.DiscardParameters(parseInfo, invokeInfo.Getter, invokeInfo.Context.Parameters);
                return(null);
            }

            var groupCall = (CallMethodGroup)invokeInfo.Target;
            var group     = groupCall.Group;

            // Make an OverloadChooser to choose an Overload.
            var overloadChooser = new OverloadChooser(
                group.Functions.Select(f => new MethodOverload(f)).ToArray(),
                parseInfo,
                invokeInfo.Scope,
                invokeInfo.Getter,
                invokeInfo.TargetRange,
                invokeInfo.CallRange,
                invokeInfo.FullRange,
                new OverloadError("method '" + group.Name + "'")
                );

            // Apply the parameters.
            overloadChooser.Apply(invokeInfo.Context.Parameters, groupCall.TypeArgs.Length > 0, groupCall.TypeArgs);

            // Get the best function.
            var callingMethod = (IMethod)overloadChooser.Overload;
            var result        = new FunctionInvokeResult(parseInfo, invokeInfo.TargetRange, invokeInfo.UsedAsExpression, callingMethod, overloadChooser.AdditionalData, overloadChooser.ParameterResults, overloadChooser.Match);
            var typeArgLinker = overloadChooser.Match?.TypeArgLinker;

            // CallingMethod may be null if no good functions are found.
            if (callingMethod != null)
            {
                result.ReturnType = callingMethod.CodeType?.GetCodeType(parseInfo.TranslateInfo).GetRealType(typeArgLinker);

                // Do not track if any of the generics are null.
                if (overloadChooser.Match.TypeArgs.All(t => t != null))
                {
                    // Track the generics used in the function.
                    parseInfo.Script.Elements.AddTypeArgCall(new TypeArgCall(callingMethod.MethodInfo.Tracker, overloadChooser.Match.TypeArgs));
                }

                if (callingMethod.Attributes.CallInfo != null)
                {
                    // Restricted calls.
                    RestrictedCall.BridgeMethodCall(parseInfo, callingMethod.Attributes.CallInfo, invokeInfo.TargetRange, callingMethod.Name, overloadChooser.Match.Option.RestrictedValuesAreFatal);

                    // Apply
                    callingMethod.Attributes.CallInfo.OnCompleted.OnReady(result.Apply);
                }
                else
                {
                    result.Apply();
                }

                // Check if the function can be called in parallel.
                if (parseInfo.AsyncInfo != null)
                {
                    if (!callingMethod.Attributes.Parallelable)
                    {
                        parseInfo.AsyncInfo.Reject($"The method '{callingMethod.Name}' cannot be called in parallel");
                    }
                    else
                    {
                        parseInfo.AsyncInfo.Accept();
                    }
                }

                // Add the function hover.
                parseInfo.Script.AddHover(invokeInfo.Context.Range, callingMethod.GetLabel(parseInfo.TranslateInfo, new LabelInfo()
                {
                    IncludeDocumentation  = true,
                    IncludeParameterNames = true,
                    IncludeParameterTypes = true,
                    IncludeReturnType     = true,
                    AnonymousLabelInfo    = new AnonymousLabelInfo(typeArgLinker)
                }));
            }

            return(result);
        }