test/tools/javac/scope/7017664/CompoundScopeTest.java

changeset 0
959103a6100f
child 2525
2eb010b6cb22
equal deleted inserted replaced
-1:000000000000 0:959103a6100f
1 /*
2 * Copyright (c) 2011, 2013, 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 7017664 7036906
27 * @summary Basher for CompoundScopes
28 */
29
30 import java.util.Random;
31 import java.util.Map;
32 import java.util.HashMap;
33 import com.sun.tools.javac.util.*;
34 import com.sun.tools.javac.code.*;
35 import com.sun.tools.javac.code.Scope.*;
36 import com.sun.tools.javac.code.Symbol.*;
37 import com.sun.tools.javac.file.JavacFileManager;
38
39 public class CompoundScopeTest {
40 public static void main(String... args) throws Exception {
41 new CompoundScopeTest().run(args);
42 }
43
44 static final int MAX_SYMBOLS_COUNT = 20;
45 static final int PASSES = 10;
46
47 void run(String... args) throws Exception {
48 int count = PASSES;
49
50 for (int i = 0; i < args.length; i++) {
51 String arg = args[i];
52 if (arg.equals("-seed") && (i + 1 < args.length))
53 seed = Long.parseLong(args[++i]);
54 else if(arg.equals("-tests") && (i + 1 < args.length))
55 count = Integer.parseInt(args[++i]);
56 else
57 throw new Exception("unknown arg: " + arg);
58 }
59
60 rgen = new Random(seed);
61
62 for (int i = 0; i < count; i++) {
63 Test t = new Test();
64 t.run();
65 }
66
67 if (errors > 0)
68 throw new Exception(errors + " errors found");
69 }
70
71 /**
72 * Write a message to stderr.
73 */
74 void log(String msg) {
75 System.err.println(msg);
76 }
77
78 /**
79 * Write an error message to stderr.
80 */
81 void error(String msg) {
82 System.err.println("Error: " + msg);
83 errors++;
84 }
85
86 Random rgen;
87 long seed = 0;
88
89 int errors;
90
91 /** Class to encapsulate a test run. */
92 class Test {
93
94 List<Symbol> elems = List.nil();
95 Map<Name, List<Symbol>> shadowedMap = new HashMap<Name, List<Symbol>>();
96
97 /** Run the test. */
98 void run() throws Exception {
99 log ("starting test");
100 setup();
101 Scope[] scopes = { createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)),
102 createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)),
103 createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)) };
104 boolean[][] scopeNesting = { {false, true, false, true},
105 {false, true, true, true},
106 {false, false, true, true} };
107 /**
108 * We want to generate (and check) the following compound scopes:
109 * C1 = C(S1, S2, S3)
110 * C2 = C((S1, S2), S3)
111 * C3 = C(S1, (S2, S3))
112 * C3 = C(C(S1, S2, S3))
113 */
114 for (int i = 0 ; i < 4 ; i ++) {
115 CompoundScope root = new CompoundScope(symtab.noSymbol);
116 CompoundScope sub = new CompoundScope(symtab.noSymbol);
117 boolean subAdded = false;
118 for (int sc = 0 ; sc < 3 ; sc ++) {
119 if (scopeNesting[sc][i]) {
120 sub.addSubScope(scopes[sc]);
121 if (!subAdded) {
122 root.addSubScope(sub);
123 subAdded = true;
124 }
125 } else {
126 root.addSubScope(scopes[sc]);
127 }
128 }
129 log("testing scope: " + root);
130 checkElems(root, null);
131 checkElems(root, new OddFilter());
132 checkShadowed(root, null);
133 checkShadowed(root, new OddFilter());
134 }
135 }
136
137 class OddFilter implements Filter<Symbol> {
138 public boolean accepts(Symbol s) {
139 Name numPart = s.name.subName(1, s.name.length());
140 return Integer.parseInt(numPart.toString()) % 2 != 0;
141 }
142 }
143
144 /**
145 * Create a scope containing a given number of synthetic symbols
146 */
147 Scope createScope(int nelems) {
148 Scope s = new Scope(symtab.noSymbol);
149 for (int i = 0 ; i < nelems ; i++) {
150 Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null);
151 s.enter(sym);
152 elems = elems.prepend(sym);
153 List<Symbol> shadowed = shadowedMap.get(sym.name);
154 if (shadowed == null) {
155 shadowed = List.nil();
156 }
157 shadowedMap.put(sym.name, shadowed.prepend(sym));
158 }
159 return s;
160 }
161
162 /**
163 * Setup compiler context
164 */
165 void setup() {
166 log ("setup");
167 context = new Context();
168 JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
169 names = Names.instance(context); // Name.Table impls tied to an instance of Names
170 symtab = Symtab.instance(context);
171 }
172
173 /**
174 * Check that CompoundScope.getElements() correctly visits all symbols
175 * in all subscopes (in the correct order)
176 */
177 void checkElems(CompoundScope cs, Filter<Symbol> sf) {
178 int count = 0;
179 ListBuffer<Symbol> found = new ListBuffer<>();
180 List<Symbol> allSymbols = sf == null ?
181 elems :
182 filter(elems, sf);
183 int expectedCount = allSymbols.length();
184 for (Symbol s : sf == null ? cs.getElements() : cs.getElements(sf)) {
185 checkSameSymbols(s, allSymbols.head);
186 allSymbols = allSymbols.tail;
187 found.append(s);
188 count++;
189 }
190 if (count != expectedCount) {
191 error("CompoundScope.getElements() did not returned enough symbols");
192 }
193 }
194
195 /**
196 * Check that CompoundScope.getElements() correctly visits all symbols
197 * with a given name in all subscopes (in the correct order)
198 */
199 void checkShadowed(CompoundScope cs, Filter<Symbol> sf) {
200 for (Map.Entry<Name, List<Symbol>> shadowedEntry : shadowedMap.entrySet()) {
201 int count = 0;
202 List<Symbol> shadowed = sf == null ?
203 shadowedEntry.getValue() :
204 filter(shadowedEntry.getValue(), sf);
205 int expectedCount = shadowed.length();
206 Name name = shadowedEntry.getKey();
207 for (Symbol s : sf == null ? cs.getElementsByName(name) : cs.getElementsByName(name, sf)) {
208 checkSameSymbols(s, shadowed.head);
209 shadowed = shadowed.tail;
210 count++;
211 }
212 if (count != expectedCount) {
213 error("CompoundScope.lookup() did not returned enough symbols for name " + name);
214 }
215 }
216 }
217
218 List<Symbol> filter(List<Symbol> elems, Filter<Symbol> sf) {
219 ListBuffer<Symbol> res = new ListBuffer<>();
220 for (Symbol s : elems) {
221 if (sf.accepts(s)) {
222 res.append(s);
223 }
224 }
225 return res.toList();
226 }
227
228 void checkSameSymbols(Symbol found, Symbol req) {
229 if (found != req) {
230 error("Symbol mismatch - found : " + found + ":" + found.hashCode() + "\n" +
231 " required : " + req + ":" + req.hashCode());
232 }
233 }
234
235 Context context;
236 Symtab symtab;
237 Names names;
238 }
239 }

mercurial