test/tools/javac/lambda/TestSelfRef.java

changeset 1415
01c9d4161882
child 2148
c4292590fc70
equal deleted inserted replaced
1414:843d3b191773 1415:01c9d4161882
1 /*
2 * Copyright (c) 2012, 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 8003280
27 * @summary Add lambda tests
28 * Check that self/forward references from lambda expressions behave
29 * consistently w.r.t. local inner classes
30 */
31
32 import com.sun.source.util.JavacTask;
33 import java.net.URI;
34 import java.util.Arrays;
35 import javax.tools.Diagnostic;
36 import javax.tools.JavaCompiler;
37 import javax.tools.JavaFileObject;
38 import javax.tools.SimpleJavaFileObject;
39 import javax.tools.StandardJavaFileManager;
40 import javax.tools.ToolProvider;
41
42 public class TestSelfRef {
43
44 static int checkCount = 0;
45
46 enum RefKind {
47 SELF_LAMBDA("SAM s = x->{ System.out.println(s); };", true, false),
48 FORWARD_LAMBDA("SAM s = x->{ System.out.println(f); };\nObject f = null;", false, true),
49 SELF_ANON("Object s = new Object() { void test() { System.out.println(s); } };", true, false),
50 FORWARD_ANON("Object s = new Object() { void test() { System.out.println(f); } }; Object f = null;", false, true);
51
52 String refStr;
53 boolean selfRef;
54 boolean forwardRef;
55
56 private RefKind(String refStr, boolean selfRef, boolean forwardRef) {
57 this.refStr = refStr;
58 this.selfRef = selfRef;
59 this.forwardRef = forwardRef;
60 }
61 }
62
63 enum EnclosingKind {
64 TOPLEVEL("class C { #S }"),
65 MEMBER_INNER("class Outer { class C { #S } }"),
66 NESTED_INNER("class Outer { static class C { #S } }");
67
68 String enclStr;
69
70 private EnclosingKind(String enclStr) {
71 this.enclStr = enclStr;
72 }
73 }
74
75 enum InnerKind {
76 NONE("#R"),
77 LOCAL_NONE("class Local { #R }"),
78 LOCAL_MTH("class Local { void test() { #R } }"),
79 ANON_NONE("new Object() { #R };"),
80 ANON_MTH("new Object() { void test() { #R } };");
81
82 String innerStr;
83
84 private InnerKind(String innerStr) {
85 this.innerStr = innerStr;
86 }
87
88 boolean inMethodContext(SiteKind sk) {
89 switch (this) {
90 case LOCAL_MTH:
91 case ANON_MTH: return true;
92 case NONE: return sk != SiteKind.NONE;
93 default:
94 return false;
95 }
96 }
97 }
98
99 enum SiteKind {
100 NONE("#I"),
101 STATIC_INIT("static { #I }"),
102 INSTANCE_INIT("{ #I }"),
103 CONSTRUCTOR("C() { #I }"),
104 METHOD("void test() { #I }");
105
106 String siteStr;
107
108 private SiteKind(String siteStr) {
109 this.siteStr = siteStr;
110 }
111 }
112
113 public static void main(String... args) throws Exception {
114
115 //create default shared JavaCompiler - reused across multiple compilations
116 JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
117 StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
118
119 for (EnclosingKind ek : EnclosingKind.values()) {
120 for (SiteKind sk : SiteKind.values()) {
121 if (sk == SiteKind.STATIC_INIT && ek == EnclosingKind.MEMBER_INNER)
122 continue;
123 for (InnerKind ik : InnerKind.values()) {
124 if (ik != InnerKind.NONE && sk == SiteKind.NONE)
125 break;
126 for (RefKind rk : RefKind.values()) {
127 new TestSelfRef(ek, sk, ik, rk).run(comp, fm);
128 }
129 }
130 }
131 }
132 System.out.println("Total check executed: " + checkCount);
133 }
134
135 EnclosingKind ek;
136 SiteKind sk;
137 InnerKind ik;
138 RefKind rk;
139 JavaSource source;
140 DiagnosticChecker diagChecker;
141
142 TestSelfRef(EnclosingKind ek, SiteKind sk, InnerKind ik, RefKind rk) {
143 this.ek = ek;
144 this.sk = sk;
145 this.ik = ik;
146 this.rk = rk;
147 this.source = new JavaSource();
148 this.diagChecker = new DiagnosticChecker();
149 }
150
151 class JavaSource extends SimpleJavaFileObject {
152
153 String bodyTemplate = "interface SAM { void test(Object o); }\n#B";
154 String source;
155
156 public JavaSource() {
157 super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
158 source = bodyTemplate.replace("#B",
159 ek.enclStr.replace("#S", sk.siteStr.replace("#I", ik.innerStr.replace("#R", rk.refStr))));
160 }
161
162 @Override
163 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
164 return source;
165 }
166 }
167
168 void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
169 JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
170 null, null, Arrays.asList(source));
171 try {
172 ct.analyze();
173 } catch (Throwable ex) {
174 throw new AssertionError("Error thron when compiling the following code:\n" + source.getCharContent(true));
175 }
176 check();
177 }
178
179 void check() {
180 //illegal forward ref
181 boolean errorExpected = ik.inMethodContext(sk) &&
182 (rk.selfRef || rk.forwardRef);
183 if (diagChecker.errorFound != errorExpected) {
184 throw new Error("invalid diagnostics for source:\n" +
185 source.getCharContent(true) +
186 "\nFound error: " + diagChecker.errorFound +
187 "\nExpected error: " + errorExpected);
188 }
189 }
190
191 static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
192
193 boolean errorFound;
194
195 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
196 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
197 errorFound = true;
198 }
199 }
200 }
201 }

mercurial