Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/langtools/tools/javac/6889255/T6889255.java
41152 views
1
/*
2
* Copyright (c) 2009, 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 6889255
27
* @summary ClassReader does not read parameter names correctly
28
* @modules jdk.compiler/com.sun.tools.javac.code
29
* jdk.compiler/com.sun.tools.javac.file
30
* jdk.compiler/com.sun.tools.javac.jvm
31
* jdk.compiler/com.sun.tools.javac.util
32
*/
33
34
import java.io.*;
35
import java.util.*;
36
import javax.tools.StandardLocation;
37
import com.sun.tools.javac.code.Flags;
38
import com.sun.tools.javac.code.Symbol;
39
import com.sun.tools.javac.code.Symbol.*;
40
import com.sun.tools.javac.code.Symtab;
41
import com.sun.tools.javac.code.Type;
42
import com.sun.tools.javac.code.Type.ClassType;
43
import com.sun.tools.javac.code.TypeTag;
44
import com.sun.tools.javac.file.JavacFileManager;
45
import com.sun.tools.javac.jvm.ClassReader;
46
import com.sun.tools.javac.util.Context;
47
import com.sun.tools.javac.util.Names;
48
49
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
50
51
public class T6889255 {
52
boolean testInterfaces = true;
53
boolean testSyntheticMethods = true;
54
55
// The following enums control the generation of the test methods to be compiled.
56
enum GenericKind {
57
NOT_GENERIC,
58
GENERIC
59
};
60
61
enum ClassKind {
62
CLASS("Clss"),
63
INTERFACE("Intf"),
64
ENUM("Enum");
65
final String base;
66
ClassKind(String base) { this.base = base; }
67
};
68
69
enum NestedKind {
70
/** Declare methods inside the outermost container. */
71
NONE,
72
/** Declare methods inside a container with a 'static' modifier. */
73
NESTED,
74
/** Declare methods inside a container without a 'static' modifier. */
75
INNER,
76
/** Declare methods inside a local class in an initializer. */
77
INIT_LOCAL,
78
/** Declare methods inside an anonymous class in an initializer. */
79
INIT_ANON,
80
/** Declare methods inside a local class in a method. */
81
METHOD_LOCAL,
82
/** Declare methods inside an anonymous class in a method. */
83
METHOD_ANON
84
};
85
86
enum MethodKind {
87
ABSTRACT,
88
CONSTRUCTOR,
89
METHOD,
90
STATIC_METHOD,
91
BRIDGE_METHOD
92
};
93
94
enum FinalKind {
95
/** Method body does not reference external final variables. */
96
NO_FINAL,
97
/** Method body references external final variables. */
98
USE_FINAL
99
};
100
101
public static void main(String... args) throws Exception {
102
new T6889255().run();
103
}
104
105
void run() throws Exception {
106
genTest();
107
108
test("no-args", false);
109
test("g", true, "-g");
110
111
if (errors > 0)
112
throw new Exception(errors + " errors found");
113
}
114
115
/**
116
* Create a file containing lots of method definitions to be tested.
117
* There are 3 sets of nested loops that generate the methods.
118
* 1. The outermost set declares [generic] (class | interface | enum)
119
* 2. The middle set declares [(nested | inner | anon | local)] class
120
* 3. The innermost set declares
121
* [generic] (constructor|method|static-method|bridge-method) [using final variables in outer scope]
122
* Invalid combinations are filtered out.
123
*/
124
void genTest() throws Exception {
125
BufferedWriter out = new BufferedWriter(new FileWriter("Test.java"));
126
127
// This interface is used to force bridge methods to be generated, by
128
// implementing its methods with subtypes of Object
129
out.write("interface Base {\n");
130
out.write(" Object base_m1(int i1);\n");
131
out.write(" Object base_m2(int i1);\n");
132
out.write("}\n");
133
134
int outerNum = 0;
135
// Outermost set of loops, to generate a top level container
136
for (GenericKind outerGenericKind: GenericKind.values()) {
137
for (ClassKind outerClassKind: ClassKind.values()) {
138
if (outerGenericKind == GenericKind.GENERIC && outerClassKind == ClassKind.ENUM)
139
continue;
140
String outerClassName = outerClassKind.base + (outerNum++);
141
String outerTypeArg = outerClassKind.toString().charAt(0) + "T";
142
if (outerClassKind == ClassKind.CLASS)
143
out.write("abstract ");
144
out.write(outerClassKind.toString().toLowerCase() + " " + outerClassName);
145
if (outerGenericKind == GenericKind.GENERIC)
146
out.write("<" + outerTypeArg + ">");
147
if (outerClassKind == ClassKind.INTERFACE)
148
out.write(" extends Base");
149
else
150
out.write(" implements Base");
151
out.write(" {\n");
152
if (outerClassKind == ClassKind.ENUM) {
153
out.write(" E1(0,0,0), E2(0,0,0), E3(0,0,0);\n");
154
out.write(" " + outerClassName + "(int i1, int i2, int i3) { }\n");
155
}
156
// Middle set of loops, to generate an optional nested container
157
int nestedNum = 0;
158
int methodNum = 0;
159
for (GenericKind nestedGenericKind: GenericKind.values()) {
160
nextNestedKind:
161
for (NestedKind nestedKind: NestedKind.values()) {
162
// if the nested kind is none, there is no point iterating over all
163
// nested generic kinds, so arbitarily limit it to just one kind
164
if (nestedKind == NestedKind.NONE && nestedGenericKind != GenericKind.NOT_GENERIC)
165
continue;
166
if ((nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.INIT_ANON)
167
&& nestedGenericKind == GenericKind.GENERIC)
168
continue;
169
String indent = " ";
170
boolean haveFinal = false;
171
switch (nestedKind) {
172
case METHOD_ANON: case METHOD_LOCAL:
173
if (outerClassKind == ClassKind.INTERFACE)
174
continue nextNestedKind;
175
out.write(indent + "void m" + + (nestedNum++) + "() {\n");
176
indent += " ";
177
out.write(indent + "final int fi1 = 0;\n");
178
haveFinal = true;
179
break;
180
case INIT_ANON: case INIT_LOCAL:
181
if (outerClassKind == ClassKind.INTERFACE)
182
continue nextNestedKind;
183
out.write(indent + "{\n");
184
indent += " ";
185
break;
186
}
187
for (ClassKind nestedClassKind: ClassKind.values()) {
188
if ((nestedGenericKind == GenericKind.GENERIC)
189
&& (nestedClassKind == ClassKind.ENUM))
190
continue;
191
if ((nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.METHOD_LOCAL
192
|| nestedKind == NestedKind.INIT_ANON || nestedKind == NestedKind.INIT_LOCAL)
193
&& nestedClassKind != ClassKind.CLASS)
194
continue;
195
// if the nested kind is none, there is no point iterating over all
196
// nested class kinds, so arbitarily limit it to just one kind
197
if (nestedKind == NestedKind.NONE && nestedClassKind != ClassKind.CLASS)
198
continue;
199
200
ClassKind methodClassKind;
201
String methodClassName;
202
boolean allowAbstractMethods;
203
boolean allowStaticMethods;
204
switch (nestedKind) {
205
case NONE:
206
methodClassKind = outerClassKind;
207
methodClassName = outerClassName;
208
allowAbstractMethods = (outerClassKind == ClassKind.CLASS);
209
allowStaticMethods = (outerClassKind != ClassKind.INTERFACE);
210
break;
211
case METHOD_ANON:
212
case INIT_ANON:
213
out.write(indent + "new Base() {\n");
214
indent += " ";
215
methodClassKind = ClassKind.CLASS;
216
methodClassName = null;
217
allowAbstractMethods = false;
218
allowStaticMethods = false;
219
break;
220
default: { // INNER, NESTED, LOCAL
221
String nestedClassName = "N" + nestedClassKind.base + (nestedNum++);
222
String nestedTypeArg = nestedClassKind.toString().charAt(0) + "T";
223
out.write(indent);
224
if (nestedKind == NestedKind.NESTED)
225
out.write("static ");
226
if (nestedClassKind == ClassKind.CLASS)
227
out.write("abstract ");
228
out.write(nestedClassKind.toString().toLowerCase() + " " + nestedClassName);
229
if (nestedGenericKind == GenericKind.GENERIC)
230
out.write("<" + nestedTypeArg + ">");
231
if (nestedClassKind == ClassKind.INTERFACE)
232
out.write(" extends Base ");
233
else
234
out.write(" implements Base ");
235
out.write(" {\n");
236
indent += " ";
237
if (nestedClassKind == ClassKind.ENUM) {
238
out.write(indent + "E1(0,0,0), E2(0,0,0), E3(0,0,0);\n");
239
out.write(indent + nestedClassName + "(int i1, int i2, int i3) { }\n");
240
}
241
methodClassKind = nestedClassKind;
242
methodClassName = nestedClassName;
243
allowAbstractMethods = (nestedClassKind == ClassKind.CLASS);
244
allowStaticMethods = (nestedKind == NestedKind.NESTED && nestedClassKind != ClassKind.INTERFACE);
245
break;
246
}
247
}
248
249
// Innermost loops, to generate methods
250
for (GenericKind methodGenericKind: GenericKind.values()) {
251
for (FinalKind finalKind: FinalKind.values()) {
252
for (MethodKind methodKind: MethodKind.values()) {
253
// out.write("// " + outerGenericKind
254
// + " " + outerClassKind
255
// + " " + nestedKind
256
// + " " + nestedGenericKind
257
// + " " + nestedClassKind
258
// + " " + methodGenericKind
259
// + " " + finalKind
260
// + " " + methodKind
261
// + "\n");
262
switch (methodKind) {
263
case CONSTRUCTOR:
264
if (nestedKind == NestedKind.METHOD_ANON || nestedKind == NestedKind.INIT_ANON)
265
break;
266
if (methodClassKind != ClassKind.CLASS)
267
break;
268
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
269
break;
270
out.write(indent);
271
if (methodGenericKind == GenericKind.GENERIC) {
272
out.write("<CT> " + methodClassName + "(CT c1, CT c2");
273
} else {
274
out.write(methodClassName + "(boolean b1, char c2");
275
}
276
if (finalKind == FinalKind.USE_FINAL) {
277
// add a dummy parameter to avoid duplicate declaration
278
out.write(", int i3) { int i = fi1; }\n");
279
} else
280
out.write(") { }\n");
281
break;
282
case ABSTRACT:
283
if (!allowAbstractMethods)
284
continue;
285
// fallthrough
286
case METHOD:
287
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
288
break;
289
out.write(indent);
290
if (methodKind == MethodKind.ABSTRACT)
291
out.write("abstract ");
292
if (methodGenericKind == GenericKind.GENERIC)
293
out.write("<MT> ");
294
out.write("void m" + (methodNum++) + "(int i1, long l2, float f3)");
295
if (methodKind == MethodKind.ABSTRACT || methodClassKind == ClassKind.INTERFACE)
296
out.write(";\n");
297
else {
298
out.write(" {");
299
if (finalKind == FinalKind.USE_FINAL)
300
out.write(" int i = fi1;");
301
out.write(" }\n");
302
}
303
break;
304
case BRIDGE_METHOD:
305
if (methodGenericKind == GenericKind.GENERIC)
306
break;
307
out.write(indent);
308
// methods Base.base_m1 and Base.base_m2 are declared for the
309
// benefit of bridge methods. They need to be implemented
310
// whether or not a final variable is used.
311
String methodName = (finalKind == FinalKind.NO_FINAL ? "base_m1" : "base_m2");
312
out.write("public String " + methodName + "(int i1)");
313
if (methodClassKind == ClassKind.INTERFACE)
314
out.write(";\n");
315
else {
316
out.write(" {");
317
if (finalKind == FinalKind.USE_FINAL && haveFinal)
318
out.write(" int i = fi1;");
319
out.write(" return null; }\n");
320
}
321
break;
322
case STATIC_METHOD:
323
if (!allowStaticMethods)
324
break;
325
if (finalKind == FinalKind.USE_FINAL && !haveFinal)
326
break;
327
out.write(indent + "static ");
328
if (methodGenericKind == GenericKind.GENERIC)
329
out.write("<MT> ");
330
out.write("void m" + (methodNum++) + "(int i1, long l2, float f3) {");
331
if (finalKind == FinalKind.USE_FINAL)
332
out.write(" int i = fi1;");
333
out.write(" }\n");
334
break;
335
}
336
337
}
338
}
339
}
340
if (nestedKind != NestedKind.NONE) {
341
indent = indent.substring(0, indent.length() - 4);
342
out.write(indent + "};\n");
343
}
344
}
345
switch (nestedKind) {
346
case METHOD_ANON: case METHOD_LOCAL:
347
case INIT_ANON: case INIT_LOCAL:
348
indent = indent.substring(0, indent.length() - 4);
349
out.write(indent + "}\n\n");
350
}
351
}
352
}
353
out.write("}\n\n");
354
}
355
}
356
out.close();
357
}
358
359
360
void test(String testName, boolean expectNames, String... opts) throws Exception {
361
System.err.println("Test " + testName
362
+ ": expectNames:" + expectNames
363
+ " javacOpts:" + Arrays.asList(opts));
364
365
File outDir = new File(testName);
366
outDir.mkdirs();
367
compile(outDir, opts);
368
369
Context ctx = new Context();
370
JavacFileManager fm = new JavacFileManager(ctx, true, null);
371
fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(outDir));
372
Symtab syms = Symtab.instance(ctx);
373
ClassReader cr = ClassReader.instance(ctx);
374
cr.saveParameterNames = true;
375
Names names = Names.instance(ctx);
376
377
Set<String> classes = getTopLevelClasses(outDir);
378
Deque<String> work = new LinkedList<String>(classes);
379
String classname;
380
while ((classname = work.poll()) != null) {
381
System.err.println("Checking class " + classname);
382
ClassSymbol sym = syms.enterClass(syms.noModule, names.table.fromString(classname));
383
sym.complete();
384
385
if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces)
386
continue;
387
388
for (Symbol s : sym.members_field.getSymbols(NON_RECURSIVE)) {
389
System.err.println("Checking member " + s);
390
switch (s.kind) {
391
case TYP: {
392
String name = s.flatName().toString();
393
if (!classes.contains(name)) {
394
classes.add(name);
395
work.add(name);
396
}
397
break;
398
}
399
case MTH:
400
verify((MethodSymbol) s, expectNames);
401
break;
402
}
403
404
}
405
}
406
}
407
408
void verify(MethodSymbol m, boolean expectNames) {
409
if ((m.flags() & Flags.SYNTHETIC) != 0 && !testSyntheticMethods)
410
return;
411
412
//System.err.println("verify: " + m.params());
413
int i = 1;
414
for (VarSymbol v: m.params()) {
415
String expectName;
416
if (expectNames)
417
expectName = getExpectedName(v, i);
418
else
419
expectName = "arg" + (i - 1);
420
checkEqual(expectName, v.name.toString());
421
i++;
422
}
423
}
424
425
String getExpectedName(VarSymbol v, int i) {
426
// special cases:
427
// synthetic method
428
if (((v.owner.owner.flags() & Flags.ENUM) != 0)
429
&& v.owner.name.toString().equals("valueOf"))
430
return "name";
431
// interfaces don't have saved names
432
// -- no Code attribute for the LocalVariableTable attribute
433
if ((v.owner.owner.flags() & Flags.INTERFACE) != 0)
434
return "arg" + (i - 1);
435
// abstract methods don't have saved names
436
// -- no Code attribute for the LocalVariableTable attribute
437
if ((v.owner.flags() & Flags.ABSTRACT) != 0)
438
return "arg" + (i - 1);
439
// bridge methods use argN. No LVT for them anymore
440
if ((v.owner.flags() & Flags.BRIDGE) != 0)
441
return "arg" + (i - 1);
442
443
// The rest of this method assumes the local conventions in the test program
444
Type t = v.type;
445
String s;
446
if (t.hasTag(TypeTag.CLASS))
447
s = ((ClassType) t).tsym.name.toString();
448
else
449
s = t.toString();
450
return String.valueOf(Character.toLowerCase(s.charAt(0))) + i;
451
}
452
453
void compile(File outDir, String... opts) throws Exception {
454
//File testSrc = new File(System.getProperty("test.src"), ".");
455
List<String> args = new ArrayList<String>();
456
args.add("-d");
457
args.add(outDir.getPath());
458
args.addAll(Arrays.asList(opts));
459
//args.add(new File(testSrc, "Test.java").getPath());
460
args.add("Test.java");
461
StringWriter sw = new StringWriter();
462
PrintWriter pw = new PrintWriter(sw);
463
int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
464
pw.close();
465
if (rc != 0) {
466
System.err.println(sw.toString());
467
throw new Exception("compilation failed unexpectedly");
468
}
469
}
470
471
Set<String> getTopLevelClasses(File outDir) {
472
Set<String> classes = new HashSet<String>();
473
for (String f: outDir.list()) {
474
if (f.endsWith(".class") && !f.contains("$"))
475
classes.add(f.replace(".class", ""));
476
}
477
return classes;
478
}
479
480
void checkEqual(String expect, String found) {
481
if (!expect.equals(found))
482
error("mismatch: expected:" + expect + " found:" + found);
483
}
484
485
void error(String msg) {
486
System.err.println(msg);
487
errors++;
488
throw new Error();
489
}
490
491
int errors;
492
}
493
494