21 * questions. |
21 * questions. |
22 */ |
22 */ |
23 |
23 |
24 /* |
24 /* |
25 * @test |
25 * @test |
26 * @bug 8205418 |
26 * @bug 8205418 8207229 8207230 |
27 * @summary Test the outcomes from Trees.getScope |
27 * @summary Test the outcomes from Trees.getScope |
28 * @modules jdk.compiler |
28 * @modules jdk.compiler/com.sun.tools.javac.api |
|
29 * jdk.compiler/com.sun.tools.javac.comp |
|
30 * jdk.compiler/com.sun.tools.javac.tree |
|
31 * jdk.compiler/com.sun.tools.javac.util |
29 */ |
32 */ |
30 |
33 |
31 import java.io.IOException; |
34 import java.io.IOException; |
32 import java.net.URI; |
35 import java.net.URI; |
33 import java.util.ArrayList; |
36 import java.util.ArrayList; |
40 import javax.tools.ToolProvider; |
43 import javax.tools.ToolProvider; |
41 |
44 |
42 import com.sun.source.tree.CompilationUnitTree; |
45 import com.sun.source.tree.CompilationUnitTree; |
43 import com.sun.source.tree.LambdaExpressionTree; |
46 import com.sun.source.tree.LambdaExpressionTree; |
44 import com.sun.source.tree.Scope; |
47 import com.sun.source.tree.Scope; |
|
48 import com.sun.source.tree.VariableTree; |
45 import com.sun.source.util.JavacTask; |
49 import com.sun.source.util.JavacTask; |
46 import com.sun.source.util.TreePath; |
50 import com.sun.source.util.TreePath; |
47 import com.sun.source.util.TreePathScanner; |
51 import com.sun.source.util.TreePathScanner; |
48 import com.sun.source.util.Trees; |
52 import com.sun.source.util.Trees; |
49 |
53 |
|
54 import com.sun.tools.javac.api.JavacTool; |
|
55 import com.sun.tools.javac.comp.Analyzer; |
|
56 import com.sun.tools.javac.comp.AttrContext; |
|
57 import com.sun.tools.javac.comp.Env; |
|
58 import com.sun.tools.javac.tree.JCTree.JCStatement; |
|
59 import com.sun.tools.javac.util.Context; |
|
60 import com.sun.tools.javac.util.Context.Factory; |
|
61 |
50 import static javax.tools.JavaFileObject.Kind.SOURCE; |
62 import static javax.tools.JavaFileObject.Kind.SOURCE; |
51 |
63 |
52 public class TestGetScopeResult { |
64 public class TestGetScopeResult { |
53 public static void main(String... args) throws IOException { |
65 public static void main(String... args) throws IOException { |
54 new TestGetScopeResult().run(); |
66 new TestGetScopeResult().run(); |
|
67 new TestGetScopeResult().testAnalyzerDisabled(); |
55 } |
68 } |
56 |
69 |
57 public void run() throws IOException { |
70 public void run() throws IOException { |
58 String[] simpleLambda = { |
71 String[] simpleLambda = { |
59 "s:java.lang.String", |
72 "s:java.lang.String", |
107 "super:java.lang.Object", |
120 "super:java.lang.Object", |
108 "this:Test" |
121 "this:Test" |
109 }; |
122 }; |
110 doTest("class Test { void test() { cand1(s -> { }); } void cand1(I1 i) { } void cand1(I2 i, int i) { } interface I1 { public String test(String s); } interface I2 { public int test(CharSequence s); } }", |
123 doTest("class Test { void test() { cand1(s -> { }); } void cand1(I1 i) { } void cand1(I2 i, int i) { } interface I1 { public String test(String s); } interface I2 { public int test(CharSequence s); } }", |
111 multipleCandidates2); |
124 multipleCandidates2); |
|
125 |
|
126 String[] implicitExplicitConflict1 = { |
|
127 ":t", |
|
128 "s:java.lang.String", |
|
129 "super:java.lang.Object", |
|
130 "this:Test" |
|
131 }; |
|
132 |
|
133 doTest("class Test { void test() { cand((var s, t) -> \"\"); } void cand(I i) { } interface I { public String test(String s); } }", |
|
134 implicitExplicitConflict1); |
|
135 |
|
136 String[] implicitExplicitConflict2 = { |
|
137 "s:<any>", |
|
138 ":t", |
|
139 "super:java.lang.Object", |
|
140 "this:Test" |
|
141 }; |
|
142 |
|
143 doTest("class Test { void test() { cand((t, var s) -> \"\"); } void cand(I i) { } interface I { public String test(String s); } }", |
|
144 implicitExplicitConflict2); |
112 } |
145 } |
113 |
146 |
114 public void doTest(String code, String... expected) throws IOException { |
147 public void doTest(String code, String... expected) throws IOException { |
115 JavaCompiler c = ToolProvider.getSystemJavaCompiler(); |
148 JavaCompiler c = ToolProvider.getSystemJavaCompiler(); |
116 try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { |
149 try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { |
149 throw new IllegalStateException("Unexpected scope content: " + actual); |
182 throw new IllegalStateException("Unexpected scope content: " + actual); |
150 } |
183 } |
151 } |
184 } |
152 } |
185 } |
153 |
186 |
|
187 void testAnalyzerDisabled() throws IOException { |
|
188 JavacTool c = JavacTool.create(); |
|
189 try (StandardJavaFileManager fm = c.getStandardFileManager(null, null, null)) { |
|
190 class MyFileObject extends SimpleJavaFileObject { |
|
191 MyFileObject() { |
|
192 super(URI.create("myfo:///Test.java"), SOURCE); |
|
193 } |
|
194 @Override |
|
195 public String getCharContent(boolean ignoreEncodingErrors) { |
|
196 return "class Test {" + |
|
197 " void test() { cand(() -> { System.err.println(); }); }" + |
|
198 " Runnable r = new Runnable() { public void test() { System.err.println(); } };" + |
|
199 " void cand(Runnable r) { }" + |
|
200 "}"; |
|
201 } |
|
202 } |
|
203 Context ctx = new Context(); |
|
204 TestAnalyzer.preRegister(ctx); |
|
205 JavacTask t = (JavacTask) c.getTask(null, fm, null, List.of("-XDfind=lambda"), null, |
|
206 List.of(new MyFileObject()), ctx); |
|
207 CompilationUnitTree cut = t.parse().iterator().next(); |
|
208 t.analyze(); |
|
209 |
|
210 TestAnalyzer analyzer = (TestAnalyzer) TestAnalyzer.instance(ctx); |
|
211 |
|
212 if (!analyzer.analyzeCalled) { |
|
213 throw new IllegalStateException("Analyzer didn't run!"); |
|
214 } |
|
215 |
|
216 new TreePathScanner<Void, Void>() { |
|
217 @Override |
|
218 public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { |
|
219 analyzer.analyzeCalled = false; |
|
220 Trees.instance(t).getScope(new TreePath(getCurrentPath(), node.getBody())); |
|
221 if (analyzer.analyzeCalled) { |
|
222 throw new IllegalStateException("Analyzer was run during getScope!"); |
|
223 } |
|
224 return super.visitLambdaExpression(node, p); |
|
225 } |
|
226 |
|
227 @Override |
|
228 public Void visitVariable(VariableTree node, Void p) { |
|
229 if (node.getInitializer() != null) { |
|
230 analyzer.analyzeCalled = false; |
|
231 TreePath tp = new TreePath(getCurrentPath(), node.getInitializer()); |
|
232 Trees.instance(t).getScope(tp); |
|
233 if (analyzer.analyzeCalled) { |
|
234 throw new IllegalStateException("Analyzer was run during getScope!"); |
|
235 } |
|
236 } |
|
237 return super.visitVariable(node, p); |
|
238 } |
|
239 }.scan(cut, null); |
|
240 } |
|
241 } |
|
242 |
|
243 private static final class TestAnalyzer extends Analyzer { |
|
244 |
|
245 public static void preRegister(Context context) { |
|
246 context.put(analyzerKey, (Factory<Analyzer>) ctx -> new TestAnalyzer(ctx)); |
|
247 } |
|
248 |
|
249 private boolean analyzeCalled; |
|
250 |
|
251 public TestAnalyzer(Context context) { |
|
252 super(context); |
|
253 } |
|
254 |
|
255 @Override |
|
256 protected void analyze(JCStatement statement, Env<AttrContext> env) { |
|
257 analyzeCalled = true; |
|
258 super.analyze(statement, env); |
|
259 } |
|
260 } |
154 } |
261 } |
155 |
262 |