Ejemplo n.º 1
0
        public Ust VisitExpression(JavaParser.ExpressionContext context)
        {
            var        textSpan       = context.GetTextSpan();
            var        child0Terminal = context.GetChild(0) as ITerminalNode;
            Expression target;
            Expression result;

            if (child0Terminal != null)
            {
                switch (child0Terminal.Symbol.Type)
                {
                case JavaParser.NEW:
                    result = (Expression)Visit(context.creator());
                    return(result);

                case JavaParser.LPAREN:     // '(' type ')' expression
                    var type = (TypeToken)Visit(context.typeType());
                    target = (Expression)Visit(context.expression(0));
                    result = new CastExpression(type, target, textSpan);
                    return(result);

                default:     // unary operator ('+', '-', '++', '--', '~', '!')
                    UnaryOperator op        = UnaryOperatorLiteral.PrefixTextUnaryOperator[child0Terminal.GetText()];
                    var           opLiteral = new UnaryOperatorLiteral(op, child0Terminal.GetTextSpan());
                    target = (Expression)Visit(context.expression(0));
                    result = new UnaryOperatorExpression(opLiteral, target, textSpan);
                    return(result);
                }
            }

            ArgsUst args;
            var     child1Terminal = context.GetChild(1) as ITerminalNode;

            if (child1Terminal != null)
            {
                switch (child1Terminal.Symbol.Type)
                {
                case JavaParser.DOT:     // '.'
                    target = (Expression)Visit(context.expression(0));

                    if (context.methodCall() != null)
                    {
                        var invocation = (InvocationExpression)Visit(context.methodCall());
                        return(new InvocationExpression(
                                   new MemberReferenceExpression(target, invocation.Target, target.TextSpan.Union(invocation.Target.TextSpan)),
                                   invocation.Arguments,
                                   textSpan));
                    }

                    // TODO: implement base processing

                    Expression rightPart = null;
                    if (context.IDENTIFIER() != null)
                    {
                        rightPart = (IdToken)Visit(context.IDENTIFIER());
                    }
                    else if (context.THIS() != null)
                    {
                        rightPart = new ThisReferenceToken(context.THIS().GetTextSpan());
                    }

                    if (rightPart != null)
                    {
                        return(new MemberReferenceExpression(target, rightPart, textSpan));
                    }

                    if (context.innerCreator() != null)
                    {
                        return(Visit(context.innerCreator()));
                    }

                    if (context.explicitGenericInvocation() != null)
                    {
                        return(VisitChildren(context.explicitGenericInvocation()).ToExpressionIfRequired());
                    }

                    break;

                case JavaParser.LBRACK:     // '['
                    target = (Expression)Visit(context.expression(0));
                    Expression expr = (Expression)Visit(context.expression(1));
                    args = new ArgsUst(new Expression[] { expr }, expr.TextSpan);

                    result = new IndexerExpression(target, args, textSpan);
                    return(result);

                case JavaParser.INSTANCEOF:     // x instanceof y -> (y)x != null
                    var expression = (Expression)Visit(context.expression(0));
                    var type       = (TypeToken)Visit(context.typeType());
                    result = new BinaryOperatorExpression(context.GetTextSpan())
                    {
                        Left     = new CastExpression(type, expression, context.GetTextSpan()),
                        Operator = new BinaryOperatorLiteral(BinaryOperator.NotEqual, default),
                        Right    = new NullLiteral(default),
                        Root     = root
                    };
                    return(result);

                case JavaParser.QUESTION:     // '?'
                    var condition = (Expression)Visit(context.expression(0));
                    var trueExpr  = (Expression)Visit(context.expression(1));
                    var falseExpr = (Expression)Visit(context.expression(2));

                    result = new ConditionalExpression(condition, trueExpr, falseExpr, textSpan);
                    return(result);

                case JavaParser.COLONCOLON:
                    return(VisitChildren(context));

                default:     // binary operator
                    var left = (Expression)Visit(context.expression(0));
                    JavaParser.ExpressionContext expr1 = context.expression(1);

                    if (expr1 != null)
                    {
                        string opText = string.Concat(context.children.Skip(1).Take(context.children.Count - 2));
                        var    right  = (Expression)Visit(expr1);

                        // TODO: fix via grammar refactoring (alternative labels).
                        if (opText == "=" ||
                            (opText.EndsWith("=") && BinaryOperatorLiteral.TextBinaryOperator.ContainsKey(opText.Remove(opText.Length - 1))))
                        {
                            result = UstUtils.CreateAssignExpr(left, right, context.GetTextSpan(),
                                                               opText, child1Terminal.GetTextSpan());
                        }
                        else
                        {
                            BinaryOperator op        = BinaryOperatorLiteral.TextBinaryOperator[opText];
                            var            opLiteral = new BinaryOperatorLiteral(op, child1Terminal.GetTextSpan());
                            result = new BinaryOperatorExpression(left, opLiteral, right, textSpan);
                        }
                    }
                    else
                    {
                        // post increment or decrement.
                        UnaryOperator op        = UnaryOperatorLiteral.PostfixTextUnaryOperator[context.postfix.Text];
                        var           opLiteral = new UnaryOperatorLiteral(op, child1Terminal.GetTextSpan());

                        result = new UnaryOperatorExpression(opLiteral, left, textSpan);
                        return(result);
                    }
                    return(result);
                }
            }

            return(VisitChildren(context));
        }
Ejemplo n.º 2
0
        public UstNode VisitExpression(JavaParser.ExpressionContext context)
        {
            var        textSpan       = context.GetTextSpan();
            var        child0Terminal = context.GetChild(0) as ITerminalNode;
            Expression target;
            Expression result;

            if (child0Terminal != null)
            {
                switch (child0Terminal.Symbol.Type)
                {
                case JavaParser.NEW:
                    result = (Expression)Visit(context.creator());
                    return(result);

                case JavaParser.LPAREN:     // '(' type ')' expression
                    var type = (TypeToken)Visit(context.typeType());
                    target = (Expression)Visit(context.expression(0));
                    result = new CastExpression(type, target, textSpan, FileNode);
                    return(result);

                default:     // unary operator ('+', '-', '++', '--', '~', '!')
                    UnaryOperator op        = UnaryOperatorLiteral.PrefixTextUnaryOperator[child0Terminal.GetText()];
                    var           opLiteral = new UnaryOperatorLiteral(op, child0Terminal.GetTextSpan(), FileNode);
                    target = (Expression)Visit(context.expression(0));
                    result = new UnaryOperatorExpression(opLiteral, target, textSpan, FileNode);
                    return(result);
                }
            }

            ArgsNode args;
            var      child1Terminal = context.GetChild(1) as ITerminalNode;

            if (child1Terminal != null)
            {
                switch (child1Terminal.Symbol.Type)
                {
                case JavaParser.DOT:     // '.'
                    target = (Expression)Visit(context.expression(0));
                    var id = context.IDENTIFIER();
                    if (id != null)
                    {
                        result = new MemberReferenceExpression(target, (IdToken)Visit(id), textSpan, FileNode);
                        return(result);
                    }

                    var explicitGenericInvocation = context.explicitGenericInvocation();
                    if (explicitGenericInvocation != null)
                    {
                        return(VisitChildren(context).ToExpressionIfRequired());
                    }

                    var child2Terminal = context.GetChild <ITerminalNode>(1);
                    // TODO: implement
                    switch (child2Terminal.Symbol.Type)
                    {
                    case JavaParser.THIS:
                        break;

                    case JavaParser.NEW:
                        break;

                    case JavaParser.SUPER:
                        break;
                    }
                    break;

                case JavaParser.LBRACK:     // '['
                    target = (Expression)Visit(context.expression(0));
                    Expression expr = (Expression)Visit(context.expression(1));
                    args = new ArgsNode(new Expression[] { expr }, expr.TextSpan, FileNode);

                    result = new IndexerExpression(target, args, textSpan, FileNode);
                    return(result);

                case JavaParser.LPAREN:     // '('
                    target = (Expression)Visit(context.expression(0));
                    // TODO: fix with ArgsNode
                    JavaParser.ExpressionListContext expressionList = context.expressionList();

                    if (expressionList != null)
                    {
                        args = (ArgsNode)Visit(expressionList);
                    }
                    else
                    {
                        args = new ArgsNode();
                    }

                    result = new InvocationExpression(target, args, textSpan, FileNode);
                    return(result);

                case JavaParser.INSTANCEOF:     // x instanceof y -> (y)x != null
                    var expression = (Expression)Visit(context.expression(0));
                    var type       = (TypeToken)Visit(context.typeType());
                    result = new BinaryOperatorExpression
                    {
                        Left     = new CastExpression(type, expression, context.GetTextSpan(), FileNode),
                        Operator = new BinaryOperatorLiteral(BinaryOperator.NotEqual, default(TextSpan), FileNode),
                        Right    = new NullLiteral(default(TextSpan), FileNode),
                        TextSpan = context.GetTextSpan(),
                        FileNode = FileNode
                    };
                    return(result);

                case JavaParser.QUESTION:     // '?'
                    var condition = (Expression)Visit(context.expression(0));
                    var trueExpr  = (Expression)Visit(context.expression(1));
                    var falseExpr = (Expression)Visit(context.expression(2));

                    result = new ConditionalExpression(condition, trueExpr, falseExpr, textSpan, FileNode);
                    return(result);

                default:     // binary operator
                    string text = child1Terminal.GetText();
                    var    left = (Expression)Visit(context.expression(0));
                    JavaParser.ExpressionContext expr1 = context.expression(1);

                    if (expr1 != null)
                    {
                        var right = (Expression)Visit(expr1);

                        if (text == "=")
                        {
                            result = new AssignmentExpression(left, right, textSpan, FileNode);
                        }
                        else if (BinaryOperatorLiteral.TextBinaryAssignmentOperator.Contains(text))
                        {
                            BinaryOperator op;
                            if (text == ">>>=")
                            {
                                op = BinaryOperator.ShiftRight;     // TODO: fix shift operator.
                            }
                            else
                            {
                                op = BinaryOperatorLiteral.TextBinaryOperator[text.Remove(text.Length - 1)];
                            }

                            result = ConverterHelper.ConvertToAssignmentExpression(left, op, child1Terminal.GetTextSpan(), right,
                                                                                   context.GetTextSpan(), FileNode);
                        }
                        else
                        {
                            BinaryOperator op;
                            if (text == ">>>")
                            {
                                op = BinaryOperator.ShiftRight;      // TODO: fix shift operator.
                            }
                            else
                            {
                                op = BinaryOperatorLiteral.TextBinaryOperator[text];
                            }
                            var opLiteral = new BinaryOperatorLiteral(op, child1Terminal.GetTextSpan(), FileNode);

                            result = new BinaryOperatorExpression(left, opLiteral, right, textSpan, FileNode);
                        }
                    }
                    else
                    {
                        // post increment or decrement.
                        UnaryOperator op        = UnaryOperatorLiteral.PostfixTextUnaryOperator[text];
                        var           opLiteral = new UnaryOperatorLiteral(op, child1Terminal.GetTextSpan(), FileNode);

                        result = new UnaryOperatorExpression(opLiteral, left, textSpan, FileNode);
                        return(result);
                    }

                    return(result);
                }
            }

            return(Visit(context.GetChild(0)));
        }