1b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar/*
2b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * Copyright (C) 2015 The Android Open Source Project
3b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar *
4b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
5b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * you may not use this file except in compliance with the License.
6b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * You may obtain a copy of the License at
7b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar *
8b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
9b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar *
10b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * Unless required by applicable law or agreed to in writing, software
11b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
12b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * See the License for the specific language governing permissions and
14b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar * limitations under the License.
15b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar */
16fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mountpackage android.databinding;
17fead9ca09b117136b35bc5bf137340a754f9edddGeorge Mount
1874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionLexer;
1974f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser;
2074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.AndOrOpContext;
2174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BinaryOpContext;
2274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BindingSyntaxContext;
2374f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BitShiftOpContext;
2474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ComparisonOpContext;
2574f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.DefaultsContext;
2674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.DotOpContext;
2774f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ExpressionContext;
2874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.GroupingContext;
2974f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.LiteralContext;
3074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.MathOpContext;
3174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.PrimaryContext;
3274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.PrimitiveTypeContext;
3374f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.QuestionQuestionOpContext;
3474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ResourceContext;
3574f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.StringLiteralContext;
3674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.TernaryOpContext;
3774f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.UnaryOpContext;
38d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
39d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.ANTLRInputStream;
40d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.CommonTokenStream;
41d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.Token;
42d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.tree.TerminalNode;
432c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport org.junit.Test;
44d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
45d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport java.io.StringReader;
46d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
472c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertEquals;
482c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertNotNull;
492c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertNull;
502c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertTrue;
512c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount
522c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountpublic class BindingExpressionParserTest {
532c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount
542c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
55d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testSingleQuoteStringLiteral() throws Exception {
56d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "`test`";
57d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
58d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNotNull(literal);
59d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
60d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNotNull(stringLiteral);
61d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.SingleQuoteString();
62d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
63d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("`test`", token.getText());
64d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
65d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
662c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
67d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDoubleQuoteStringLiteral() throws Exception {
68d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "\"test\"";
69d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
70d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
71d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
72d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.DoubleQuoteString();
73d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
74d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("\"test\"", token.getText());
75d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
76d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
772c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
78d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testSingleQuoteEscapeStringLiteral() throws Exception {
79d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "`\"t\\`est\"`";
80d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
81d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
82d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.SingleQuoteString();
83d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
84d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("`\"t\\`est\"`", token.getText());
85d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
86d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
872c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
88d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testCharLiteral() throws Exception {
89d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral("'c'");
90d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'c'", literal.getText());
91d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        literal = parseLiteral("'\\u0054'");
92d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'\\u0054'", literal.getText());
93d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        literal = parseLiteral("'\\''");
94d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'\\''", literal.getText());
95d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
96d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
972c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
98d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testIntLiterals() throws Exception {
99d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123");
100d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123l");
101d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("1_2_3l");
102d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123L");
103d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdeadbeef");
104d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdeadbeefl");
105d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0Xdeadbeef");
106d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdead_beefl");
107d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdead_beefL");
108d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567");
109d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567L");
110d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567l");
111d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0123_45_67l");
112d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0b0101");
113d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0b0101_0101");
114d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101");
115d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101L");
116d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101l");
117d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
118d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1192c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
120d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testFloatLiterals() throws Exception {
121d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345");
122d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345f");
123d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345F");
124d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.12345F");
125d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.12345");
126d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450e123");
127d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.4e123");
128d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
129d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1302c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
131d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBoolLiterals() throws Exception {
132d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBoolLiteral("true");
133d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBoolLiteral("false");
134d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
135d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1362c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
137d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testNullLiteral() throws Exception {
138d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral("null");
139d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.getText();
140d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("null", token);
141d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
142d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1432c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
144d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testVoidExtraction() throws Exception {
145d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimaryContext primary = parsePrimary("void.class");
146d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNotNull(primary.classExtraction());
147d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNull(primary.classExtraction().type());
148d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("void", primary.classExtraction().getChild(0).getText());
149d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
150d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1512c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
152d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testPrimitiveClassExtraction() throws Exception {
153d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimaryContext primary = parsePrimary("int.class");
154d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimitiveTypeContext type = primary.classExtraction().type().primitiveType();
155d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("int", type.getText());
156d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
157d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1582c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
159d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testIdentifier() throws Exception {
160d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimaryContext primary = parsePrimary("abcdEfg");
161d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("abcdEfg", primary.identifier().getText());
162d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
163d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1642c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
165d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testUnaryOperators() throws Exception {
166d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("+");
167d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("-");
168d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("!");
169d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("~");
170d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
171d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1722c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
173d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testMathOperators() throws Exception {
174d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("+");
175d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("-");
176d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("*");
177d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("/");
178d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("%");
179d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
180d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1812c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
182d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBitShiftOperators() throws Exception {
183d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators(">>>");
184d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators("<<");
185d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators(">>");
186d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
187d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1882c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
189d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testComparisonShiftOperators() throws Exception {
190d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("<");
191d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators(">");
192d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("<=");
193d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators(">=");
194d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("==");
195d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("!=");
196d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
197d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1982c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
199d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testAndOrOperators() throws Exception {
200d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareAndOrOperators("&&");
201d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareAndOrOperators("||");
202d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
203d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2042c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
205d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBinaryOperators() throws Exception {
206d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("&");
207d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("|");
208d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("^");
209d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
210d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2112c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
212d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testTernaryOperator() throws Exception {
213d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TernaryOpContext expression = parseExpression("true ? 1 : 0");
214d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(5, expression.getChildCount());
215d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("true",
216d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.left).literal().javaLiteral().getText());
217d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("?", expression.op.getText());
218d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1",
219d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.iftrue).literal().javaLiteral().getText());
220d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(":", expression.getChild(3).getText());
2212c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("0", ((PrimaryContext) expression.iffalse).literal().javaLiteral().getText());
222d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
223d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2242c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
225d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDot() throws Exception {
226d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        DotOpContext expression = parseExpression("one.two.three");
227d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
228d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("three", expression.Identifier().getText());
229d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(".", expression.getChild(1).getText());
230d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        DotOpContext left = (DotOpContext) expression.expression();
231d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("two", left.Identifier().getText());
232d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(".", left.getChild(1).getText());
233d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("one", ((PrimaryContext) left.expression()).identifier().getText());
234d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
235d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2362c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
237d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testQuestionQuestion() throws Exception {
238d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        QuestionQuestionOpContext expression = parseExpression("one ?? two");
239d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
2402c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("one", ((PrimaryContext) expression.left).identifier().getText());
2412c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("two", ((PrimaryContext) expression.right).identifier().getText());
242d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("??", expression.op.getText());
243d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
244d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2452c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
246d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testResourceReference() throws Exception {
247d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@id/foo_bar");
248d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@transition/foo_bar");
249d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@anim/foo_bar");
250d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@animator/foo_bar");
251d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@android:id/foo_bar");
252d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@app:id/foo_bar");
253d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
254d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2552c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
256d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDefaults() throws Exception {
257d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingSyntaxContext syntax = parseExpressionString("foo.bar, default = @id/foo_bar");
258d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        DefaultsContext defaults = syntax.defaults();
259d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("@id/foo_bar", defaults.constantValue().ResourceReference().getText());
260d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
261d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2622c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
263d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testParentheses() throws Exception {
264d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        GroupingContext grouping = parseExpression("(1234)");
265d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1234", grouping.expression().getText());
266d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
267d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
268d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    // ---------------------- Helpers --------------------
269d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
270d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareResource(String value) throws Exception {
271ae7cb82316e351c488ee3b9c7226602321f34301George Mount        ResourceContext resourceContext = parseExpression(value);
272ae7cb82316e351c488ee3b9c7226602321f34301George Mount        assertEquals(value, resourceContext.getText());
273d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
274d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
275d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareUnaryOperators(String op) throws Exception {
276d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        UnaryOpContext expression = parseExpression(op + " 2");
277d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(2, expression.getChildCount());
278d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
279d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2",
280d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.expression()).literal().javaLiteral()
281d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                        .getText());
282d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
283d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
284d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBinaryOperators(String op) throws Exception {
285d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BinaryOpContext expression = parseExpression("1 " + op + " 2");
286d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
287d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
2882c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
289d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
290d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
291d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
2922c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
293d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
294d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
295d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
296d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareMathOperators(String op) throws Exception {
297d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        MathOpContext expression = parseExpression("1 " + op + " 2");
298d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
299d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3002c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
301d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
302d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
303d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3042c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
305d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
306d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
307d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
308d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBitShiftOperators(String op) throws Exception {
309d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BitShiftOpContext expression = parseExpression("1 " + op + " 2");
310d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
311d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3122c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
313d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
314d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
315d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3162c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
317d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
318d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
319d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
320d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareComparisonOperators(String op) throws Exception {
321d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        ComparisonOpContext expression = parseExpression("1 " + op + " 2");
322d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
323d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3242c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
325d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
326d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
327d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3282c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
329d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
330d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
331d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
332d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareAndOrOperators(String op) throws Exception {
333d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        AndOrOpContext expression = parseExpression("1 " + op + " 2");
334d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
335d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3362c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
337d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
338d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
339d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3402c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
341d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
342d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
343d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
344d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareIntLiteral(String constant) throws Exception {
345d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
346d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
347d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
348d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
349d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
350d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareFloatLiteral(String constant) throws Exception {
351d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
352d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
353d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
354d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
355d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
356d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBoolLiteral(String constant) throws Exception {
357d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
358d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
359d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
360d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
361d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
362d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private BindingSyntaxContext parse(String value) throws Exception {
363d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parseExpressionString(value);
364d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
365d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
366d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private <T extends ExpressionContext> T parseExpression(String value) throws Exception {
367d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        ExpressionContext expressionContext = parse(value).expression();
368d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return (T) expressionContext;
369d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
370d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
371d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private PrimaryContext parsePrimary(String value) throws Exception {
372d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parseExpression(value);
373d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
374d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
375d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private LiteralContext parseLiteral(String value) throws Exception {
376d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parsePrimary(value).literal();
377d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
378d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
379d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    BindingExpressionParser.BindingSyntaxContext parseExpressionString(String s) throws Exception {
380d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        ANTLRInputStream input = new ANTLRInputStream(new StringReader(s));
381d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingExpressionLexer lexer = new BindingExpressionLexer(input);
382d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        CommonTokenStream tokens = new CommonTokenStream(lexer);
383d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingExpressionParser parser = new BindingExpressionParser(tokens);
384d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parser.bindingSyntax();
385d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
386b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar}