Example #1
0
 /// <summary>
 /// Creates an appropriate setter for GetMemberNode.
 /// From: expr.a
 /// To:   expr.a = ...
 /// </summary>
 private SetMemberNode SetterOf(GetMemberNode node)
 {
     return(new SetMemberNode
     {
         Expression = node.Expression,
         StaticType = node.StaticType,
         MemberName = node.MemberName
     });
 }
Example #2
0
        public void FieldWithTypeParameters()
        {
            var src    = "Enumerable::Empty<int>";
            var result = new GetMemberNode
            {
                StaticType = new TypeSignature("Enumerable"),
                MemberName = "Empty",
                TypeHints  = { new TypeSignature("int") }
            };

            TestParser(src, result);
        }
Example #3
0
        /// <summary>
        /// Resolves the method if the expression was a member getter (obj.field or type::field).
        /// </summary>
        private void resolveGetMember(Context ctx, GetMemberNode node)
        {
            _InvocationSource = node.Expression;
            var type = _InvocationSource != null
                ? _InvocationSource.Resolve(ctx)
                : ctx.ResolveType(node.StaticType);

            checkTypeInSafeMode(ctx, type);

            if (node.TypeHints != null && node.TypeHints.Count > 0)
                _TypeHints = node.TypeHints.Select(x => ctx.ResolveType(x, true)).ToArray();

            try
            {
                // resolve a normal method
                try
                {
                    _Method = ctx.ResolveMethod(
                        type,
                        node.MemberName,
                        _ArgTypes,
                        _TypeHints,
                        (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                    );

                    if (_Method.IsStatic)
                        _InvocationSource = null;

                    return;
                }
                catch (KeyNotFoundException)
                {
                    if (_InvocationSource == null)
                        throw;
                }

                // resolve a callable field
                try
                {
                    ctx.ResolveField(type, node.MemberName);
                    resolveExpression(ctx, node);
                    return;
                }
                catch (KeyNotFoundException) { }

                // resolve a callable property
                try
                {
                    ctx.ResolveProperty(type, node.MemberName);
                    resolveExpression(ctx, node);
                    return;
                }
                catch (KeyNotFoundException) { }

                Arguments = (Arguments[0] is UnitNode)
                    ? new List<NodeBase> {_InvocationSource}
                    : new[] {_InvocationSource}.Union(Arguments).ToList();

                var oldArgTypes = _ArgTypes;
                _ArgTypes = Arguments.Select(a => a.Resolve(ctx)).ToArray();
                _InvocationSource = null;

                try
                {
                    // resolve a local function that is implicitly used as an extension method
                    _Method = ctx.ResolveMethod(
                        ctx.MainType.TypeInfo,
                        node.MemberName,
                        _ArgTypes,
                        resolver: (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                    );

                    return;
                }
                catch (KeyNotFoundException) { }

                // resolve a declared extension method
                // most time-consuming operation, therefore is last checked
                try
                {
                    if(!ctx.Options.AllowExtensionMethods)
                        throw new KeyNotFoundException();

                    _Method = ctx.ResolveExtensionMethod(
                        type,
                        node.MemberName,
                        oldArgTypes,
                        _TypeHints,
                        (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                    );
                }
                catch (KeyNotFoundException)
                {
                    var msg = node.StaticType != null
                        ? CompilerMessages.TypeStaticMethodNotFound
                        : CompilerMessages.TypeMethodNotFound;

                    error(msg, type, node.MemberName);
                }
            }
            catch (AmbiguousMatchException)
            {
                error(CompilerMessages.TypeMethodInvocationAmbiguous, type, node.MemberName);
            }
        }
Example #4
0
        /// <summary>
        /// Resolves the method if the expression was a member getter (obj.field or type::field).
        /// </summary>
        private void ResolveGetMember(Context ctx, GetMemberNode node)
        {
            _invocationSource = node.Expression;
            var type = _invocationSource != null
                ? _invocationSource.Resolve(ctx)
                : ctx.ResolveType(node.StaticType);

            CheckTypeInSafeMode(ctx, type);

            if (node.TypeHints != null && node.TypeHints.Count > 0)
            {
                _typeHints = node.TypeHints.Select(x => ctx.ResolveType(x, true)).ToArray();
            }

            try
            {
                // resolve a normal method
                try
                {
                    _method = ctx.ResolveMethod(
                        type,
                        node.MemberName,
                        ArgTypes,
                        _typeHints,
                        (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                        );

                    if (_method.IsStatic)
                    {
                        _invocationSource = null;
                    }

                    return;
                }
                catch (KeyNotFoundException)
                {
                    if (_invocationSource == null)
                    {
                        throw;
                    }
                }

                // resolve a callable field
                try
                {
                    ctx.ResolveField(type, node.MemberName);
                    ResolveExpression(ctx, node);
                    return;
                }
                catch (KeyNotFoundException)
                {
                }

                // resolve a callable property
                try
                {
                    ctx.ResolveProperty(type, node.MemberName);
                    ResolveExpression(ctx, node);
                    return;
                }
                catch (KeyNotFoundException)
                {
                }

                Arguments = (Arguments[0] is UnitNode)
                    ? new List <NodeBase> {
                    _invocationSource
                }
                    : new[] { _invocationSource }.Union(Arguments).ToList();

                var oldArgTypes = ArgTypes;
                ArgTypes          = Arguments.Select(a => a.Resolve(ctx)).ToArray();
                _invocationSource = null;

                try
                {
                    // resolve a local function that is implicitly used as an extension method
                    _method = ctx.ResolveMethod(
                        ctx.MainType.TypeInfo,
                        node.MemberName,
                        ArgTypes,
                        resolver: (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                        );

                    return;
                }
                catch (KeyNotFoundException)
                {
                }

                // resolve a declared extension method
                // most time-consuming operation, therefore is last checked
                try
                {
                    if (!ctx.Options.AllowExtensionMethods)
                    {
                        throw new KeyNotFoundException();
                    }

                    _method = ctx.ResolveExtensionMethod(
                        type,
                        node.MemberName,
                        oldArgTypes,
                        _typeHints,
                        (idx, types) => ctx.ResolveLambda(Arguments[idx] as LambdaNode, types)
                        );
                }
                catch (KeyNotFoundException)
                {
                    var msg = node.StaticType != null
                        ? CompilerMessages.TypeStaticMethodNotFound
                        : CompilerMessages.TypeMethodNotFound;

                    Error(msg, type, node.MemberName);
                }
            }
            catch (AmbiguousMatchException)
            {
                Error(CompilerMessages.TypeMethodInvocationAmbiguous, type, node.MemberName);
            }
        }
Example #5
0
        /// <summary>
        /// accessor_mbr                                = "." identifier [ type_args ]
        /// </summary>
        private GetMemberNode parseAccessorMbr()
        {
            if (!check(LexemType.Dot))
                return null;

            var node = new GetMemberNode();
            node.MemberName = ensure(LexemType.Identifier, ParserMessages.MemberNameExpected).Value;

            var args = attempt(parseTypeArgs);
            if (args != null)
                node.TypeHints = args;

            return node;
        }
Example #6
0
        /// <summary>
        /// invoke_pass                                 = "******" identifier [ type_args ] ( invoke_block_args | invoke_line_args )
        /// </summary>
        private InvocationNode parseInvokePass()
        {
            if (!check(LexemType.PassRight))
                return null;

            var getter = new GetMemberNode();
            var invoker = new InvocationNode { Expression = getter };

            getter.MemberName = ensure(LexemType.Identifier, ParserMessages.MemberNameExpected).Value;

            var hints = attempt(parseTypeArgs);
            if(hints != null)
                getter.TypeHints = hints;

            var lambda = attempt(parseLambdaLineExpr);
            if (lambda != null)
            {
                invoker.Arguments = new List<NodeBase> { lambda };
            }
            else
            {
                invoker.Arguments = parseInvokeBlockArgs().ToList();
                if (invoker.Arguments.Count == 0)
                    invoker.Arguments = parseInvokeLineArgs().ToList();

                if (invoker.Arguments.Count == 0)
                    error(ParserMessages.ArgumentsExpected);
            }

            return invoker;
        }
Example #7
0
        /// <summary>
        /// lvalue_stmbr_expr                           = type "::" identifier
        /// </summary>
        private GetMemberNode parseLvalueStmbrExpr()
        {
            var type = attempt(parseType);
            if (type == null || !check(LexemType.DoubleŠ”olon))
                return null;

            var node = new GetMemberNode();
            node.StaticType = type;
            node.MemberName = ensure(LexemType.Identifier, ParserMessages.MemberNameExpected).Value;
            return node;
        }
Example #8
0
        public void FieldWithTypeParameters()
        {
            var src = "Enumerable::Empty<int>";
            var result = new GetMemberNode
            {
                StaticType = new TypeSignature("Enumerable"),
                MemberName = "Empty",
                TypeHints = { new TypeSignature("int") }
            };

            TestParser(src, result);
        }