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)); } } }
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)); }
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); }
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)); } } }
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); }
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); } } } }
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); } } }
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)); } } }
public void AddOverloadData(OverloadChooser overload) { overloads.Add(overload); }
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); }