public override TO2Type ResultType(IBlockContext context) { TO2Type targetType = target.ResultType(context); IMethodInvokeFactory method = targetType.FindMethod(context.ModuleContext, methodName); if (method != null) { IMethodInvokeEmitter methodInvoker = method.Create(context, arguments.Select(arg => arg.ResultType(context)).ToList(), this); if (methodInvoker != null) { return(methodInvoker.ResultType); } } IFieldAccessFactory field = targetType.FindField(context.ModuleContext, methodName); if (field != null) { IFieldAccessEmitter fieldAccess = field.Create(context.ModuleContext); FunctionType functionType = fieldAccess.FieldType as FunctionType; if (functionType == null) { context.AddError(new StructuralError( StructuralError.ErrorType.NoSuchMethod, $"Field '{methodName}' of type '{targetType.Name}' is neither a method or a function", Start, End )); return(BuiltinType.Unit); } else { return(functionType.returnType); } } context.AddError(new StructuralError( StructuralError.ErrorType.NoSuchMethod, $"Type '{targetType.Name}' does not have a method or field '{methodName}'", Start, End )); return(BuiltinType.Unit); }
public MethodCall(Expression target, string methodName, List <Expression> arguments, Position start = new Position(), Position end = new Position()) : base(start, end) { this.target = target; this.methodName = methodName; this.arguments = arguments; for (int j = 0; j < this.arguments.Count; j++) { int i = j; // Copy for lambda this.arguments[i].TypeHint = context => { TO2Type targetType = this.target.ResultType(context); IMethodInvokeFactory methodInvoker = targetType.FindMethod(context.ModuleContext, this.methodName); return(methodInvoker?.ArgumentHint(i)?.Invoke(context)); }; } }
public override void Prepare(IBlockContext context) { if (preparedResult != null) { return; } TO2Type targetType = target.ResultType(context); IMethodInvokeEmitter methodInvoker = targetType.FindMethod(context.ModuleContext, methodName) ?.Create(context, arguments.Select(arg => arg.ResultType(context)).ToList(), this); if (methodInvoker == null || !methodInvoker.IsAsync || !context.IsAsync) { return; } EmitCode(context, false); preparedResult = context.DeclareHiddenLocal(methodInvoker.ResultType.GeneratedType(context.ModuleContext)); preparedResult.EmitStore(context); }
public override void EmitCode(IBlockContext context, bool dropResult) { if (preparedResult != null) { if (!dropResult) { preparedResult.EmitLoad(context); } preparedResult = null; return; } TO2Type targetType = target.ResultType(context); IMethodInvokeFactory method = targetType.FindMethod(context.ModuleContext, methodName); if (method != null) { EmitCodeMethodCall(context, targetType, method, dropResult); return; } IFieldAccessFactory field = targetType.FindField(context.ModuleContext, methodName); if (field != null) { EmitCodeDelegateCall(context, targetType, field, dropResult); return; } context.AddError(new StructuralError( StructuralError.ErrorType.NoSuchMethod, $"Type '{targetType.Name}' does not have a method or field '{methodName}'", Start, End )); }
public override IMethodInvokeFactory FindMethod(ModuleContext context, string methodName) => aliasedType.FindMethod(declaredModule, methodName);