Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/langtools/jdk/jshell/ClassMembersTest.java
40931 views
1
/*
2
* Copyright (c) 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 8139829
27
* @summary Test access to members of user defined class.
28
* @build KullaTesting TestingInputStream ExpectedDiagnostic
29
* @run testng/timeout=600 ClassMembersTest
30
*/
31
32
import java.lang.annotation.RetentionPolicy;
33
import java.util.ArrayList;
34
import java.util.List;
35
36
import javax.tools.Diagnostic;
37
38
import jdk.jshell.SourceCodeAnalysis;
39
import org.testng.annotations.DataProvider;
40
import org.testng.annotations.Test;
41
import jdk.jshell.TypeDeclSnippet;
42
import static jdk.jshell.Snippet.Status.OVERWRITTEN;
43
import static jdk.jshell.Snippet.Status.VALID;
44
45
public class ClassMembersTest extends KullaTesting {
46
47
@Test(dataProvider = "memberTestCase")
48
public void memberTest(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
49
MemberTestCase testCase = new MemberTestCase(accessModifier, codeChunk, isStaticMember, isStaticReference);
50
assertEval(testCase.generateSource());
51
String expectedMessage = testCase.expectedMessage;
52
if (testCase.codeChunk != CodeChunk.CONSTRUCTOR || testCase.isAccessible()) {
53
assertEval("A a = new A();");
54
}
55
if (expectedMessage == null) {
56
assertEval(testCase.useCodeChunk());
57
} else {
58
assertDeclareFail(testCase.useCodeChunk(), expectedMessage);
59
}
60
}
61
62
private List<String> parseCode(String input) {
63
List<String> list = new ArrayList<>();
64
SourceCodeAnalysis codeAnalysis = getAnalysis();
65
String source = input;
66
while (!source.trim().isEmpty()) {
67
SourceCodeAnalysis.CompletionInfo info = codeAnalysis.analyzeCompletion(source);
68
list.add(info.source());
69
source = info.remaining();
70
}
71
return list;
72
}
73
74
@Test(dataProvider = "memberTestCase")
75
public void extendsMemberTest(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
76
MemberTestCase testCase = new ExtendsMemberTestCase(accessModifier, codeChunk, isStaticMember, isStaticReference);
77
String input = testCase.generateSource();
78
List<String> ss = parseCode(input);
79
assertEval(ss.get(0));
80
if (testCase.codeChunk != CodeChunk.CONSTRUCTOR || testCase.isAccessible()) {
81
assertEval(ss.get(1));
82
assertEval("B b = new B();");
83
}
84
String expectedMessage = testCase.expectedMessage;
85
if (expectedMessage == null) {
86
assertEval(testCase.useCodeChunk());
87
} else {
88
assertDeclareFail(testCase.useCodeChunk(), expectedMessage);
89
}
90
}
91
92
@Test
93
public void interfaceTest() {
94
String interfaceSource =
95
"interface A {\n" +
96
" default int defaultMethod() { return 1; }\n" +
97
" static int staticMethod() { return 2; }\n" +
98
" int method();\n" +
99
" class Inner1 {}\n" +
100
" static class Inner2 {}\n" +
101
"}";
102
assertEval(interfaceSource);
103
assertEval("A.staticMethod();", "2");
104
String classSource =
105
"class B implements A {\n" +
106
" public int method() { return 3; }\n" +
107
"}";
108
assertEval(classSource);
109
assertEval("B b = new B();");
110
assertEval("b.defaultMethod();", "1");
111
assertDeclareFail("B.staticMethod();",
112
new ExpectedDiagnostic("compiler.err.cant.resolve.location.args", 0, 14, 1, -1, -1, Diagnostic.Kind.ERROR));
113
assertEval("b.method();", "3");
114
assertEval("new A.Inner1();");
115
assertEval("new A.Inner2();");
116
assertEval("new B.Inner1();");
117
assertEval("new B.Inner2();");
118
}
119
120
@Test
121
public void enumTest() {
122
String enumSource =
123
"enum E {A(\"s\");\n" +
124
" private final String s;\n" +
125
" private E(String s) { this.s = s; }\n" +
126
" public String method() { return s; }\n" +
127
" private String privateMethod() { return s; }\n" +
128
" public static String staticMethod() { return staticPrivateMethod(); }\n" +
129
" private static String staticPrivateMethod() { return \"a\"; }\n" +
130
"}";
131
assertEval(enumSource);
132
assertEval("E a = E.A;", "A");
133
assertDeclareFail("a.s;",
134
new ExpectedDiagnostic("compiler.err.report.access", 0, 3, 1, -1, -1, Diagnostic.Kind.ERROR));
135
assertDeclareFail("new E(\"q\");",
136
new ExpectedDiagnostic("compiler.err.enum.cant.be.instantiated", 0, 10, 0, -1, -1, Diagnostic.Kind.ERROR));
137
assertEval("a.method();", "\"s\"");
138
assertDeclareFail("a.privateMethod();",
139
new ExpectedDiagnostic("compiler.err.report.access", 0, 15, 1, -1, -1, Diagnostic.Kind.ERROR));
140
assertEval("E.staticMethod();", "\"a\"");
141
assertDeclareFail("a.staticPrivateMethod();",
142
new ExpectedDiagnostic("compiler.err.report.access", 0, 21, 1, -1, -1, Diagnostic.Kind.ERROR));
143
assertDeclareFail("E.method();",
144
new ExpectedDiagnostic("compiler.err.non-static.cant.be.ref", 0, 8, 1, -1, -1, Diagnostic.Kind.ERROR));
145
}
146
147
@Test(dataProvider = "retentionPolicyTestCase")
148
public void annotationTest(RetentionPolicy policy) {
149
assertEval("import java.lang.annotation.*;");
150
String annotationSource =
151
"@Retention(RetentionPolicy." + policy.toString() + ")\n" +
152
"@interface A {}";
153
assertEval(annotationSource);
154
String classSource =
155
"@A class C {\n" +
156
" @A C() {}\n" +
157
" @A void f() {}\n" +
158
" @A int f;\n" +
159
" @A class Inner {}\n" +
160
"}";
161
assertEval(classSource);
162
String isRuntimeVisible = policy == RetentionPolicy.RUNTIME ? "true" : "false";
163
assertEval("C.class.getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
164
assertEval("C.class.getDeclaredConstructor().getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
165
assertEval("C.class.getDeclaredMethod(\"f\").getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
166
assertEval("C.class.getDeclaredField(\"f\").getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
167
assertEval("C.Inner.class.getAnnotationsByType(A.class).length > 0;", isRuntimeVisible);
168
}
169
170
@DataProvider(name = "retentionPolicyTestCase")
171
public Object[][] retentionPolicyTestCaseGenerator() {
172
List<Object[]> list = new ArrayList<>();
173
for (RetentionPolicy policy : RetentionPolicy.values()) {
174
list.add(new Object[]{policy});
175
}
176
return list.toArray(new Object[list.size()][]);
177
}
178
179
@DataProvider(name = "memberTestCase")
180
public Object[][] memberTestCaseGenerator() {
181
List<Object[]> list = new ArrayList<>();
182
for (AccessModifier accessModifier : AccessModifier.values()) {
183
for (Static isStaticMember : Static.values()) {
184
for (Static isStaticReference : Static.values()) {
185
for (CodeChunk codeChunk : CodeChunk.values()) {
186
if (codeChunk == CodeChunk.CONSTRUCTOR && isStaticMember == Static.STATIC) {
187
continue;
188
}
189
list.add(new Object[]{ accessModifier, codeChunk, isStaticMember, isStaticReference });
190
}
191
}
192
}
193
}
194
return list.toArray(new Object[list.size()][]);
195
}
196
197
public static class ExtendsMemberTestCase extends MemberTestCase {
198
199
public ExtendsMemberTestCase(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember, Static isStaticReference) {
200
super(accessModifier, codeChunk, isStaticMember, isStaticReference);
201
}
202
203
@Override
204
public String getSourceTemplate() {
205
return super.getSourceTemplate() + "\n"
206
+ "class B extends A {}";
207
}
208
209
@Override
210
public String errorMessage() {
211
if (!isAccessible()) {
212
if (codeChunk == CodeChunk.METHOD) {
213
return "compiler.err.cant.resolve.location.args";
214
}
215
if (codeChunk == CodeChunk.CONSTRUCTOR) {
216
return "compiler.err.cant.resolve.location";
217
}
218
}
219
return super.errorMessage();
220
}
221
222
@Override
223
public String useCodeChunk() {
224
return useCodeChunk("B");
225
}
226
}
227
228
public static class MemberTestCase {
229
public final AccessModifier accessModifier;
230
public final CodeChunk codeChunk;
231
public final Static isStaticMember;
232
public final Static isStaticReference;
233
public final String expectedMessage;
234
235
public MemberTestCase(AccessModifier accessModifier, CodeChunk codeChunk, Static isStaticMember,
236
Static isStaticReference) {
237
this.accessModifier = accessModifier;
238
this.codeChunk = codeChunk;
239
this.isStaticMember = isStaticMember;
240
this.isStaticReference = isStaticReference;
241
this.expectedMessage = errorMessage();
242
}
243
244
public String getSourceTemplate() {
245
return "class A {\n" +
246
" #MEMBER#\n" +
247
"}";
248
}
249
250
public boolean isAccessible() {
251
return accessModifier != AccessModifier.PRIVATE;
252
}
253
254
public String errorMessage() {
255
if (!isAccessible()) {
256
return "compiler.err.report.access";
257
}
258
if (codeChunk == CodeChunk.INNER_INTERFACE) {
259
return "compiler.err.abstract.cant.be.instantiated";
260
}
261
if (isStaticMember == Static.STATIC) {
262
if (isStaticReference == Static.NO && codeChunk == CodeChunk.INNER_CLASS) {
263
return "compiler.err.qualified.new.of.static.class";
264
}
265
return null;
266
}
267
if (isStaticReference == Static.STATIC) {
268
if (codeChunk == CodeChunk.CONSTRUCTOR) {
269
return null;
270
}
271
if (codeChunk == CodeChunk.INNER_CLASS) {
272
return "compiler.err.encl.class.required";
273
}
274
return "compiler.err.non-static.cant.be.ref";
275
}
276
return null;
277
}
278
279
public String generateSource() {
280
return getSourceTemplate().replace("#MEMBER#", codeChunk.generateSource(accessModifier, isStaticMember));
281
}
282
283
protected String useCodeChunk(String className) {
284
String name = className.toLowerCase();
285
switch (codeChunk) {
286
case CONSTRUCTOR:
287
return String.format("new %s();", className);
288
case METHOD:
289
if (isStaticReference == Static.STATIC) {
290
return String.format("%s.method();", className);
291
} else {
292
return String.format("%s.method();", name);
293
}
294
case FIELD:
295
if (isStaticReference == Static.STATIC) {
296
return String.format("%s.field;", className);
297
} else {
298
return String.format("%s.field;", name);
299
}
300
case INNER_CLASS:
301
if (isStaticReference == Static.STATIC) {
302
return String.format("new %s.Inner();", className);
303
} else {
304
return String.format("%s.new Inner();", name);
305
}
306
case INNER_INTERFACE:
307
return String.format("new %s.Inner();", className);
308
default:
309
throw new AssertionError("Unknown code chunk: " + this);
310
}
311
}
312
313
public String useCodeChunk() {
314
return useCodeChunk("A");
315
}
316
}
317
318
public enum AccessModifier {
319
PUBLIC("public"),
320
PROTECTED("protected"),
321
PACKAGE_PRIVATE(""),
322
PRIVATE("private");
323
324
private final String modifier;
325
326
AccessModifier(String modifier) {
327
this.modifier = modifier;
328
}
329
330
public String getModifier() {
331
return modifier;
332
}
333
}
334
335
public enum Static {
336
STATIC("static"), NO("");
337
338
private final String modifier;
339
340
Static(String modifier) {
341
this.modifier = modifier;
342
}
343
344
public String getModifier() {
345
return modifier;
346
}
347
}
348
349
public enum CodeChunk {
350
CONSTRUCTOR("#MODIFIER# A() {}"),
351
METHOD("#MODIFIER# int method() { return 10; }"),
352
FIELD("#MODIFIER# int field = 10;"),
353
INNER_CLASS("#MODIFIER# class Inner {}"),
354
INNER_INTERFACE("#MODIFIER# interface Inner {}");
355
356
private final String code;
357
358
CodeChunk(String code) {
359
this.code = code;
360
}
361
362
public String generateSource(AccessModifier accessModifier, Static isStatic) {
363
return code.replace("#MODIFIER#", accessModifier.getModifier() + " " + isStatic.getModifier());
364
}
365
}
366
}
367
368