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 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); }