コード例 #1
0
        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);
        }
コード例 #2
0
        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));
                };
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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
                                 ));
        }
コード例 #5
0
 public override IMethodInvokeFactory FindMethod(ModuleContext context, string methodName) =>
 aliasedType.FindMethod(declaredModule, methodName);