1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/test/tools/javac/scope/7017664/CompoundScopeTest.java Tue Feb 15 11:49:46 2011 +0000 1.3 @@ -0,0 +1,212 @@ 1.4 +/* 1.5 + * Copyright (c) 2011, 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 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); 1.134 + checkShadowed(root); 1.135 + } 1.136 + } 1.137 + 1.138 + /** 1.139 + * Create a scope containing a given number of synthetic symbols 1.140 + */ 1.141 + Scope createScope(int nelems) { 1.142 + Scope s = new Scope(symtab.noSymbol); 1.143 + for (int i = 0 ; i < nelems ; i++) { 1.144 + Symbol sym = new TypeSymbol(0, names.fromString("s" + i), null, null); 1.145 + s.enter(sym); 1.146 + elems = elems.prepend(sym); 1.147 + List<Symbol> shadowed = shadowedMap.get(sym.name); 1.148 + if (shadowed == null) { 1.149 + shadowed = List.nil(); 1.150 + } 1.151 + shadowedMap.put(sym.name, shadowed.prepend(sym)); 1.152 + } 1.153 + return s; 1.154 + } 1.155 + 1.156 + /** 1.157 + * Setup compiler context 1.158 + */ 1.159 + void setup() { 1.160 + log ("setup"); 1.161 + context = new Context(); 1.162 + JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab 1.163 + names = Names.instance(context); // Name.Table impls tied to an instance of Names 1.164 + symtab = Symtab.instance(context); 1.165 + } 1.166 + 1.167 + /** 1.168 + * Check that CompoundScope.getElements() correctly visits all symbols 1.169 + * in all subscopes (in the correct order) 1.170 + */ 1.171 + void checkElems(CompoundScope cs) { 1.172 + List<Symbol> allSymbols = elems; 1.173 + int count = 0; 1.174 + for (Symbol s : cs.getElements()) { 1.175 + checkSameSymbols(s, allSymbols.head); 1.176 + allSymbols = allSymbols.tail; 1.177 + count++; 1.178 + } 1.179 + if (count != elems.size()) { 1.180 + error("CompoundScope.getElements() did not returned enough symbols"); 1.181 + } 1.182 + } 1.183 + 1.184 + /** 1.185 + * Check that CompoundScope.getElements() correctly visits all symbols 1.186 + * with a given name in all subscopes (in the correct order) 1.187 + */ 1.188 + void checkShadowed(CompoundScope cs) { 1.189 + for (Map.Entry<Name, List<Symbol>> shadowedEntry : shadowedMap.entrySet()) { 1.190 + int count = 0; 1.191 + List<Symbol> shadowed = shadowedEntry.getValue(); 1.192 + Name name = shadowedEntry.getKey(); 1.193 + for (Symbol s : cs.getElementsByName(name)) { 1.194 + checkSameSymbols(s, shadowed.head); 1.195 + shadowed = shadowed.tail; 1.196 + count++; 1.197 + } 1.198 + if (count != shadowedEntry.getValue().size()) { 1.199 + error("CompoundScope.lookup() did not returned enough symbols for name " + name); 1.200 + } 1.201 + } 1.202 + } 1.203 + 1.204 + void checkSameSymbols(Symbol found, Symbol req) { 1.205 + if (found != req) { 1.206 + error("Symbol mismatch - found : " + found + ":" + found.hashCode() + "\n" + 1.207 + " required : " + req + ":" + req.hashCode()); 1.208 + } 1.209 + } 1.210 + 1.211 + Context context; 1.212 + Symtab symtab; 1.213 + Names names; 1.214 + } 1.215 +}