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
186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport android.databinding.parser.BindingExpressionBaseVisitor;
1974f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionLexer;
2074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser;
2174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.AndOrOpContext;
2274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BinaryOpContext;
2374f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BindingSyntaxContext;
2474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.BitShiftOpContext;
2574f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ComparisonOpContext;
2674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.DefaultsContext;
2774f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.DotOpContext;
2874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ExpressionContext;
2974f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.GroupingContext;
3074f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.LiteralContext;
3174f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.MathOpContext;
3274f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.PrimaryContext;
3374f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.PrimitiveTypeContext;
3474f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.QuestionQuestionOpContext;
3574f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.ResourceContext;
3674f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.StringLiteralContext;
3774f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.TernaryOpContext;
3874f72d77b1db2b78ee6422da2ec94de12edcb6dcYigit Boyarimport android.databinding.parser.BindingExpressionParser.UnaryOpContext;
39d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
40d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.ANTLRInputStream;
41d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.CommonTokenStream;
42d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.Token;
436047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarimport org.antlr.v4.runtime.misc.NotNull;
44d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport org.antlr.v4.runtime.tree.TerminalNode;
452c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport org.junit.Test;
46d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
47d071769a3dc21fa36b55eb727d1f54474fb76b00George Mountimport java.io.StringReader;
48d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
492c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertEquals;
502c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertNotNull;
512c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertNull;
522c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountimport static org.junit.Assert.assertTrue;
532c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount
542c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mountpublic class BindingExpressionParserTest {
552c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount
562c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
57d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testSingleQuoteStringLiteral() throws Exception {
58d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "`test`";
59d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
60d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNotNull(literal);
61d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
62d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertNotNull(stringLiteral);
63d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.SingleQuoteString();
64d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
65d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("`test`", token.getText());
66d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
67d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
682c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
69d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDoubleQuoteStringLiteral() throws Exception {
70d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "\"test\"";
71d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
72d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
73d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
74d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.DoubleQuoteString();
75d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
76d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("\"test\"", token.getText());
77d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
78d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
792c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
80d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testSingleQuoteEscapeStringLiteral() throws Exception {
81d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String expr = "`\"t\\`est\"`";
82d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(expr);
83d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        StringLiteralContext stringLiteral = literal.stringLiteral();
84d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TerminalNode singleQuote = stringLiteral.SingleQuoteString();
85d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        Token token = singleQuote.getSymbol();
86d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("`\"t\\`est\"`", token.getText());
87d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
88d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
892c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
90d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testCharLiteral() throws Exception {
91d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral("'c'");
92d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'c'", literal.getText());
93d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        literal = parseLiteral("'\\u0054'");
94d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'\\u0054'", literal.getText());
95d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        literal = parseLiteral("'\\''");
96d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("'\\''", literal.getText());
97d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
98d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
992c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
100d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testIntLiterals() throws Exception {
101d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123");
102d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123l");
103d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("1_2_3l");
104d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("123L");
105d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdeadbeef");
106d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdeadbeefl");
107d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0Xdeadbeef");
108d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdead_beefl");
109d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0xdead_beefL");
110d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567");
111d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567L");
112d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("01234567l");
113d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0123_45_67l");
114d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0b0101");
115d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0b0101_0101");
116d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101");
117d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101L");
118d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareIntLiteral("0B0101_0101l");
119d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
120d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1212c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
122d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testFloatLiterals() throws Exception {
123d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345");
124d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345f");
125d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("0.12345F");
126d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.12345F");
127d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.12345");
128d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450e123");
129d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareFloatLiteral("132450.4e123");
130d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
131d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1322c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
133d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBoolLiterals() throws Exception {
134d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBoolLiteral("true");
135d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBoolLiteral("false");
136d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
137d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1382c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
139d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testNullLiteral() throws Exception {
140d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral("null");
141d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.getText();
142d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("null", token);
143d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
144d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1452c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
146d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testPrimitiveClassExtraction() throws Exception {
147d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimaryContext primary = parsePrimary("int.class");
148d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimitiveTypeContext type = primary.classExtraction().type().primitiveType();
149d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("int", type.getText());
150d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
151d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1522c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
153d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testIdentifier() throws Exception {
154d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        PrimaryContext primary = parsePrimary("abcdEfg");
155d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("abcdEfg", primary.identifier().getText());
156d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
157d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1582c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
159d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testUnaryOperators() throws Exception {
160d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("+");
161d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("-");
162d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("!");
163d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareUnaryOperators("~");
164d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
165d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1662c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
167d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testMathOperators() throws Exception {
168d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("+");
169d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("-");
170d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("*");
171d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("/");
172d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareMathOperators("%");
173d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
174d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1752c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
176d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBitShiftOperators() throws Exception {
177d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators(">>>");
178d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators("<<");
179d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBitShiftOperators(">>");
180d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
181d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1822c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
183d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testComparisonShiftOperators() throws Exception {
184d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("<");
185d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators(">");
186d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("<=");
187d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators(">=");
188d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("==");
189d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareComparisonOperators("!=");
190d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
191d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1922c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
193d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testAndOrOperators() throws Exception {
194d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareAndOrOperators("&&");
195d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareAndOrOperators("||");
196d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
197d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
1982c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
199d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testBinaryOperators() throws Exception {
200d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("&");
201d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("|");
202d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareBinaryOperators("^");
203d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
204d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2052c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
206d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testTernaryOperator() throws Exception {
207d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        TernaryOpContext expression = parseExpression("true ? 1 : 0");
208d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(5, expression.getChildCount());
209d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("true",
210d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.left).literal().javaLiteral().getText());
211d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("?", expression.op.getText());
212d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1",
213d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.iftrue).literal().javaLiteral().getText());
214d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(":", expression.getChild(3).getText());
2152c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("0", ((PrimaryContext) expression.iffalse).literal().javaLiteral().getText());
216d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
217d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2182c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
219d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDot() throws Exception {
220d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        DotOpContext expression = parseExpression("one.two.three");
221d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
222d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("three", expression.Identifier().getText());
223d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(".", expression.getChild(1).getText());
224d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        DotOpContext left = (DotOpContext) expression.expression();
225d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("two", left.Identifier().getText());
226d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(".", left.getChild(1).getText());
227d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("one", ((PrimaryContext) left.expression()).identifier().getText());
228d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
229d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2302c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
231d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testQuestionQuestion() throws Exception {
232d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        QuestionQuestionOpContext expression = parseExpression("one ?? two");
233d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
2342c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("one", ((PrimaryContext) expression.left).identifier().getText());
2352c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        assertEquals("two", ((PrimaryContext) expression.right).identifier().getText());
236d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("??", expression.op.getText());
237d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
238d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2392c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
240d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testResourceReference() throws Exception {
241d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@id/foo_bar");
242d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@transition/foo_bar");
243d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@anim/foo_bar");
244d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@animator/foo_bar");
245d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@android:id/foo_bar");
246d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        compareResource("@app:id/foo_bar");
247d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
248d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2492c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
250d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testDefaults() throws Exception {
251d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingSyntaxContext syntax = parseExpressionString("foo.bar, default = @id/foo_bar");
2526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        BindingExpressionParser.DefaultsContext defaults = syntax
2536047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                .accept(new BindingExpressionBaseVisitor<DefaultsContext>() {
2546047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    @Override
2556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    public BindingExpressionParser.DefaultsContext visitDefaults(
2566047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                            @NotNull BindingExpressionParser.DefaultsContext ctx) {
2576047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                        return ctx;
2586047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    }
2596047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                });
260d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("@id/foo_bar", defaults.constantValue().ResourceReference().getText());
261d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
262d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
2632c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount    @Test
264d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    public void testParentheses() throws Exception {
265d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        GroupingContext grouping = parseExpression("(1234)");
266d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1234", grouping.expression().getText());
267d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
268d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
269d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    // ---------------------- Helpers --------------------
270d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
271d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareResource(String value) throws Exception {
272ae7cb82316e351c488ee3b9c7226602321f34301George Mount        ResourceContext resourceContext = parseExpression(value);
273ae7cb82316e351c488ee3b9c7226602321f34301George Mount        assertEquals(value, resourceContext.getText());
274d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
275d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
276d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareUnaryOperators(String op) throws Exception {
277d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        UnaryOpContext expression = parseExpression(op + " 2");
278d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(2, expression.getChildCount());
279d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
280d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2",
281d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                ((PrimaryContext) expression.expression()).literal().javaLiteral()
282d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount                        .getText());
283d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
284d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
285d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBinaryOperators(String op) throws Exception {
286d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BinaryOpContext expression = parseExpression("1 " + op + " 2");
287d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
288d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
2892c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
290d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
291d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
292d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
2932c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
294d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
295d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
296d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
297d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareMathOperators(String op) throws Exception {
298d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        MathOpContext expression = parseExpression("1 " + op + " 2");
299d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
300d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3012c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
302d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
303d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
304d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3052c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
306d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
307d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
308d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
309d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBitShiftOperators(String op) throws Exception {
310d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BitShiftOpContext expression = parseExpression("1 " + op + " 2");
311d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
312d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3132c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
314d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
315d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
316d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3172c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
318d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
319d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
320d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
321d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareComparisonOperators(String op) throws Exception {
322d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        ComparisonOpContext expression = parseExpression("1 " + op + " 2");
323d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
324d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3252c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
326d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
327d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
328d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3292c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
330d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
331d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
332d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
333d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareAndOrOperators(String op) throws Exception {
334d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        AndOrOpContext expression = parseExpression("1 " + op + " 2");
335d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(3, expression.getChildCount());
336d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.left instanceof ExpressionContext);
3372c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String one = ((PrimaryContext) expression.left).literal().javaLiteral().getText();
338d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("1", one);
339d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(op, expression.op.getText());
340d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertTrue(expression.right instanceof ExpressionContext);
3412c86cdbaf189e2b1774af7f64a2974de9321673fGeorge Mount        String two = ((PrimaryContext) expression.right).literal().javaLiteral().getText();
342d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals("2", two);
343d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
344d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
345d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareIntLiteral(String constant) throws Exception {
346d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
347d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
348d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
349d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
350d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
351d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareFloatLiteral(String constant) throws Exception {
352d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
353d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
354d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
355d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
356d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
357d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private void compareBoolLiteral(String constant) throws Exception {
358d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        LiteralContext literal = parseLiteral(constant);
359d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        String token = literal.javaLiteral().getText();
360d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        assertEquals(constant, token);
361d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
362d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
363d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private BindingSyntaxContext parse(String value) throws Exception {
364d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parseExpressionString(value);
365d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
366d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
367d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private <T extends ExpressionContext> T parseExpression(String value) throws Exception {
3686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        return (T) parse(value).accept(new BindingExpressionBaseVisitor<ExpressionContext>() {
3696047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            @Override
3706047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            public ExpressionContext visitRootExpr(
3716047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                    @NotNull BindingExpressionParser.RootExprContext ctx) {
3726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar                return ctx.expression();
3736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar            }
3746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar        });
375d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
376d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
377d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private PrimaryContext parsePrimary(String value) throws Exception {
378d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parseExpression(value);
379d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
380d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
381d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    private LiteralContext parseLiteral(String value) throws Exception {
382d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parsePrimary(value).literal();
383d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
384d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount
385d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    BindingExpressionParser.BindingSyntaxContext parseExpressionString(String s) throws Exception {
386d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        ANTLRInputStream input = new ANTLRInputStream(new StringReader(s));
387d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingExpressionLexer lexer = new BindingExpressionLexer(input);
388d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        CommonTokenStream tokens = new CommonTokenStream(lexer);
389d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        BindingExpressionParser parser = new BindingExpressionParser(tokens);
390d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount        return parser.bindingSyntax();
391d071769a3dc21fa36b55eb727d1f54474fb76b00George Mount    }
392b1356339eaa6c8e967e4fc1dc283b82909a1208dYigit Boyar}