aoqi@0: /* aoqi@0: * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: /* aoqi@0: * @test aoqi@0: * @bug 8024415 aoqi@0: * @summary Pretty printing of JCConditional does not follow the precedence and aoqi@0: * associativity rules of JCConditional aoqi@0: * @run testng T8024415 aoqi@0: */ aoqi@0: aoqi@0: aoqi@0: import static org.testng.Assert.assertEquals; aoqi@0: aoqi@0: import java.io.IOException; aoqi@0: import java.io.StringWriter; aoqi@0: aoqi@0: import org.testng.annotations.Test; aoqi@0: aoqi@0: import com.sun.tools.javac.file.JavacFileManager; aoqi@0: import com.sun.tools.javac.tree.JCTree; aoqi@0: import com.sun.tools.javac.tree.JCTree.JCExpression; aoqi@0: import com.sun.tools.javac.tree.Pretty; aoqi@0: import com.sun.tools.javac.tree.TreeMaker; aoqi@0: import com.sun.tools.javac.util.Context; aoqi@0: import com.sun.tools.javac.util.Names; aoqi@0: aoqi@0: aoqi@0: /* aoqi@0: * Test verifies that the precedence rules of conditional expressions aoqi@0: * (JCConditional) are correct. aoqi@0: */ aoqi@0: @Test aoqi@0: public class T8024415 { aoqi@0: aoqi@0: TreeMaker maker; aoqi@0: JCExpression x; aoqi@0: aoqi@0: aoqi@0: public T8024415() { aoqi@0: Context ctx = new Context(); aoqi@0: JavacFileManager.preRegister(ctx); aoqi@0: maker = TreeMaker.instance(ctx); aoqi@0: Names names = Names.instance(ctx); aoqi@0: x = maker.Ident(names.fromString("x")); aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // JLS 15.25: The conditional operator is syntactically right-associative aoqi@0: // (it groups right-to-left). Thus, a?b:c?d:e?f:g means the same as aoqi@0: // a?b:(c?d:(e?f:g)). aoqi@0: public void testAssociativity() throws IOException { aoqi@0: aoqi@0: JCTree left = maker.Conditional(maker.Conditional(x, x, x), x, x); aoqi@0: JCTree right = maker.Conditional(x, x, maker.Conditional(x, x, x)); aoqi@0: aoqi@0: String prettyLeft = prettyPrint(left); aoqi@0: String prettyRight = prettyPrint(right); aoqi@0: aoqi@0: assertEquals(prettyLeft.replaceAll("\\s", ""), "(x?x:x)?x:x"); aoqi@0: assertEquals(prettyRight.replaceAll("\\s", ""), "x?x:x?x:x"); aoqi@0: aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // The true-part of of a conditional expression is surrounded by ? and : aoqi@0: // and can thus always be parsed unambiguously without surrounding aoqi@0: // parentheses. aoqi@0: public void testPrecedence() throws IOException { aoqi@0: aoqi@0: JCTree left = maker.Conditional(maker.Assign(x, x), x, x); aoqi@0: JCTree middle = maker.Conditional(x, maker.Assign(x, x), x); aoqi@0: JCTree right = maker.Conditional(x, x, maker.Assign(x, x)); aoqi@0: aoqi@0: String prettyLeft = prettyPrint(left); aoqi@0: String prettyMiddle = prettyPrint(middle); aoqi@0: String prettyRight = prettyPrint(right); aoqi@0: aoqi@0: assertEquals(prettyLeft.replaceAll("\\s", ""), "(x=x)?x:x"); aoqi@0: assertEquals(prettyMiddle.replaceAll("\\s", ""), "x?x=x:x"); aoqi@0: assertEquals(prettyRight.replaceAll("\\s", ""), "x?x:(x=x)"); aoqi@0: aoqi@0: } aoqi@0: aoqi@0: aoqi@0: // Helper method aoqi@0: private static String prettyPrint(JCTree tree) throws IOException { aoqi@0: StringWriter sw = new StringWriter(); aoqi@0: new Pretty(sw, true).printExpr(tree); aoqi@0: return sw.toString(); aoqi@0: } aoqi@0: aoqi@0: }