1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/scope/7017664/CompoundScopeTest.java Wed Apr 27 01:34:52 2016 +0800 1.3 @@ -0,0 +1,239 @@ 1.4 +/* 1.5 + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + */ 1.26 + 1.27 +/* 1.28 + * @test 1.29 + * @bug 7017664 7036906 1.30 + * @summary Basher for CompoundScopes 1.31 + */ 1.32 + 1.33 +import java.util.Random; 1.34 +import java.util.Map; 1.35 +import java.util.HashMap; 1.36 +import com.sun.tools.javac.util.*; 1.37 +import com.sun.tools.javac.code.*; 1.38 +import com.sun.tools.javac.code.Scope.*; 1.39 +import com.sun.tools.javac.code.Symbol.*; 1.40 +import com.sun.tools.javac.file.JavacFileManager; 1.41 + 1.42 +public class CompoundScopeTest { 1.43 + public static void main(String... args) throws Exception { 1.44 + new CompoundScopeTest().run(args); 1.45 + } 1.46 + 1.47 + static final int MAX_SYMBOLS_COUNT = 20; 1.48 + static final int PASSES = 10; 1.49 + 1.50 + void run(String... args) throws Exception { 1.51 + int count = PASSES; 1.52 + 1.53 + for (int i = 0; i < args.length; i++) { 1.54 + String arg = args[i]; 1.55 + if (arg.equals("-seed") && (i + 1 < args.length)) 1.56 + seed = Long.parseLong(args[++i]); 1.57 + else if(arg.equals("-tests") && (i + 1 < args.length)) 1.58 + count = Integer.parseInt(args[++i]); 1.59 + else 1.60 + throw new Exception("unknown arg: " + arg); 1.61 + } 1.62 + 1.63 + rgen = new Random(seed); 1.64 + 1.65 + for (int i = 0; i < count; i++) { 1.66 + Test t = new Test(); 1.67 + t.run(); 1.68 + } 1.69 + 1.70 + if (errors > 0) 1.71 + throw new Exception(errors + " errors found"); 1.72 + } 1.73 + 1.74 + /** 1.75 + * Write a message to stderr. 1.76 + */ 1.77 + void log(String msg) { 1.78 + System.err.println(msg); 1.79 + } 1.80 + 1.81 + /** 1.82 + * Write an error message to stderr. 1.83 + */ 1.84 + void error(String msg) { 1.85 + System.err.println("Error: " + msg); 1.86 + errors++; 1.87 + } 1.88 + 1.89 + Random rgen; 1.90 + long seed = 0; 1.91 + 1.92 + int errors; 1.93 + 1.94 + /** Class to encapsulate a test run. */ 1.95 + class Test { 1.96 + 1.97 + List<Symbol> elems = List.nil(); 1.98 + Map<Name, List<Symbol>> shadowedMap = new HashMap<Name, List<Symbol>>(); 1.99 + 1.100 + /** Run the test. */ 1.101 + void run() throws Exception { 1.102 + log ("starting test"); 1.103 + setup(); 1.104 + Scope[] scopes = { createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)), 1.105 + createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)), 1.106 + createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)) }; 1.107 + boolean[][] scopeNesting = { {false, true, false, true}, 1.108 + {false, true, true, true}, 1.109 + {false, false, true, true} }; 1.110 + /** 1.111 + * We want to generate (and check) the following compound scopes: 1.112 + * C1 = C(S1, S2, S3) 1.113 + * C2 = C((S1, S2), S3) 1.114 + * C3 = C(S1, (S2, S3)) 1.115 + * C3 = C(C(S1, S2, S3)) 1.116 + */ 1.117 + for (int i = 0 ; i < 4 ; i ++) { 1.118 + CompoundScope root = new CompoundScope(symtab.noSymbol); 1.119 + CompoundScope sub = new CompoundScope(symtab.noSymbol); 1.120 + boolean subAdded = false; 1.121 + for (int sc = 0 ; sc < 3 ; sc ++) { 1.122 + if (scopeNesting[sc][i]) { 1.123 + sub.addSubScope(scopes[sc]); 1.124 + if (!subAdded) { 1.125 + root.addSubScope(sub); 1.126 + subAdded = true; 1.127 + } 1.128 + } else { 1.129 + root.addSubScope(scopes[sc]); 1.130 + } 1.131 + } 1.132 + log("testing scope: " + root); 1.133 + checkElems(root, null); 1.134 + checkElems(root, new OddFilter()); 1.135 + checkShadowed(root, null); 1.136 + checkShadowed(root, new OddFilter()); 1.137 + } 1.138 + } 1.139 + 1.140 + class OddFilter implements Filter<Symbol> { 1.141 + public boolean accepts(Symbol s) { 1.142 + Name numPart = s.name.subName(1, s.name.length()); 1.143 + return Integer.parseInt(numPart.toString()) % 2 != 0; 1.144 + } 1.145 + } 1.146 + 1.147 + /** 1.148 + * Create a scope containing a given number of synthetic symbols 1.149 + */ 1.150 + Scope createScope(int nelems) { 1.151 + Scope s = new Scope(symtab.noSymbol); 1.152 + for (int i = 0 ; i < nelems ; i++) { 1.153 + Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null); 1.154 + s.enter(sym); 1.155 + elems = elems.prepend(sym); 1.156 + List<Symbol> shadowed = shadowedMap.get(sym.name); 1.157 + if (shadowed == null) { 1.158 + shadowed = List.nil(); 1.159 + } 1.160 + shadowedMap.put(sym.name, shadowed.prepend(sym)); 1.161 + } 1.162 + return s; 1.163 + } 1.164 + 1.165 + /** 1.166 + * Setup compiler context 1.167 + */ 1.168 + void setup() { 1.169 + log ("setup"); 1.170 + context = new Context(); 1.171 + JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab 1.172 + names = Names.instance(context); // Name.Table impls tied to an instance of Names 1.173 + symtab = Symtab.instance(context); 1.174 + } 1.175 + 1.176 + /** 1.177 + * Check that CompoundScope.getElements() correctly visits all symbols 1.178 + * in all subscopes (in the correct order) 1.179 + */ 1.180 + void checkElems(CompoundScope cs, Filter<Symbol> sf) { 1.181 + int count = 0; 1.182 + ListBuffer<Symbol> found = new ListBuffer<>(); 1.183 + List<Symbol> allSymbols = sf == null ? 1.184 + elems : 1.185 + filter(elems, sf); 1.186 + int expectedCount = allSymbols.length(); 1.187 + for (Symbol s : sf == null ? cs.getElements() : cs.getElements(sf)) { 1.188 + checkSameSymbols(s, allSymbols.head); 1.189 + allSymbols = allSymbols.tail; 1.190 + found.append(s); 1.191 + count++; 1.192 + } 1.193 + if (count != expectedCount) { 1.194 + error("CompoundScope.getElements() did not returned enough symbols"); 1.195 + } 1.196 + } 1.197 + 1.198 + /** 1.199 + * Check that CompoundScope.getElements() correctly visits all symbols 1.200 + * with a given name in all subscopes (in the correct order) 1.201 + */ 1.202 + void checkShadowed(CompoundScope cs, Filter<Symbol> sf) { 1.203 + for (Map.Entry<Name, List<Symbol>> shadowedEntry : shadowedMap.entrySet()) { 1.204 + int count = 0; 1.205 + List<Symbol> shadowed = sf == null ? 1.206 + shadowedEntry.getValue() : 1.207 + filter(shadowedEntry.getValue(), sf); 1.208 + int expectedCount = shadowed.length(); 1.209 + Name name = shadowedEntry.getKey(); 1.210 + for (Symbol s : sf == null ? cs.getElementsByName(name) : cs.getElementsByName(name, sf)) { 1.211 + checkSameSymbols(s, shadowed.head); 1.212 + shadowed = shadowed.tail; 1.213 + count++; 1.214 + } 1.215 + if (count != expectedCount) { 1.216 + error("CompoundScope.lookup() did not returned enough symbols for name " + name); 1.217 + } 1.218 + } 1.219 + } 1.220 + 1.221 + List<Symbol> filter(List<Symbol> elems, Filter<Symbol> sf) { 1.222 + ListBuffer<Symbol> res = new ListBuffer<>(); 1.223 + for (Symbol s : elems) { 1.224 + if (sf.accepts(s)) { 1.225 + res.append(s); 1.226 + } 1.227 + } 1.228 + return res.toList(); 1.229 + } 1.230 + 1.231 + void checkSameSymbols(Symbol found, Symbol req) { 1.232 + if (found != req) { 1.233 + error("Symbol mismatch - found : " + found + ":" + found.hashCode() + "\n" + 1.234 + " required : " + req + ":" + req.hashCode()); 1.235 + } 1.236 + } 1.237 + 1.238 + Context context; 1.239 + Symtab symtab; 1.240 + Names names; 1.241 + } 1.242 +}