1 /*
2  * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug 7080267
27  * @summary Call to toString() from an ExpressionStatementTree doesn't take in
28  *      consideration the ";" at the end
29  * @modules jdk.compiler/com.sun.tools.javac.api
30  *          jdk.compiler/com.sun.tools.javac.file
31  */
32 
33 import com.sun.source.tree.BlockTree;
34 import com.sun.source.tree.CompilationUnitTree;
35 import com.sun.source.tree.StatementTree;
36 import com.sun.source.tree.Tree;
37 import java.io.IOException;
38 import java.net.URI;
39 import java.util.Arrays;
40 import java.util.Collections;
41 import java.util.List;
42 import javax.tools.JavaFileObject;
43 import javax.tools.SimpleJavaFileObject;
44 import javax.tools.StandardJavaFileManager;
45 
46 import com.sun.source.util.JavacTask;
47 import com.sun.source.util.TreeScanner;
48 import com.sun.tools.javac.api.JavacTool;
49 
50 public class TestToString {
51     String[] statements = {
52         "i = i + 1;",
53         "i++;",
54         "m();",
55         ";",
56         "if (i == 0) return;",
57         "while (i > 0) i--;",
58         "{ }",
59         "{ i++; }",
60         "class C { }"
61     };
62 
main(String... args)63     public static void main(String... args) throws Exception {
64         new TestToString().run();
65     }
66 
run()67     void run() throws Exception {
68         try {
69             for (String s: statements) {
70                 test(s);
71             }
72 
73             if (errors > 0)
74                 throw new Exception(errors + " errors found");
75         } finally {
76             fm.close();
77         }
78     }
79 
test(String stmt)80     void test(String stmt) throws IOException {
81         System.err.println("Test: " + stmt);
82         List<String> options = Collections.<String>emptyList();
83         List<? extends JavaFileObject> files = Arrays.asList(new JavaSource(stmt));
84         JavacTask t = tool.getTask(null, fm, null, options, null, files);
85         checkEqual(scan(t.parse()), stmt);
86     }
87 
scan(Iterable<? extends CompilationUnitTree> trees)88     String scan(Iterable<? extends CompilationUnitTree> trees) {
89         class Scanner extends TreeScanner<Void,StringBuilder> {
90             String scan(Iterable<? extends Tree> trees) {
91                 StringBuilder sb = new StringBuilder();
92                 scan(trees, sb);
93                 return sb.toString();
94             }
95             @Override
96             public Void scan(Tree tree, StringBuilder sb) {
97                 if (print && tree instanceof StatementTree) {
98                     sb.append(PREFIX);
99                     sb.append(tree);
100                     sb.append(SUFFIX);
101                     return null;
102                 } else {
103                     return super.scan(tree, sb);
104                 }
105             }
106             @Override
107             public Void visitBlock(BlockTree tree, StringBuilder sb) {
108                 print = true;
109                 try {
110                     return super.visitBlock(tree, sb);
111                 } finally {
112                     print = false;
113                 }
114             }
115             boolean print = false;
116         }
117         return new Scanner().scan(trees);
118     }
119 
checkEqual(String found, String expect)120     void checkEqual(String found, String expect) {
121         boolean match = (found == null) ? (expect == null) :
122             expect.equals(found
123                 .replaceAll("^\\Q" + PREFIX + "\\E\\s*", "")
124                 .replaceAll("\\s*\\Q" + SUFFIX + "\\E$", "")
125                 .replaceAll("\\s+", " "));
126 
127         if (!match)
128             error("Mismatch: expected: " + expect + " found: " + found);
129     }
130 
131 
132 
error(String msg)133     void error(String msg) {
134         System.err.println("Error: " + msg);
135         errors++;
136     }
137 
138     static final String PREFIX = "#<";
139     static final String SUFFIX = "#>";
140 
141     JavacTool tool = JavacTool.create();
142     StandardJavaFileManager fm = tool.getStandardFileManager(null, null, null);
143     int errors = 0;
144 
145     static class JavaSource extends SimpleJavaFileObject {
146 
147         String source =
148                 "class Test {\n" +
149                 "    int i;\n" +
150                 "    void m() {\n" +
151                 "        #S\n" +
152                 "    }\n" +
153                 "}";
154 
JavaSource(String stmt)155         public JavaSource(String stmt) {
156             super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
157             source = source.replace("#S", stmt);
158         }
159 
160         @Override
getCharContent(boolean ignoreEncodingErrors)161         public CharSequence getCharContent(boolean ignoreEncodingErrors) {
162             return source;
163         }
164     }
165 }
166