mcimadamore@877: /* mcimadamore@877: * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. mcimadamore@877: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mcimadamore@877: * mcimadamore@877: * This code is free software; you can redistribute it and/or modify it mcimadamore@877: * under the terms of the GNU General Public License version 2 only, as mcimadamore@877: * published by the Free Software Foundation. mcimadamore@877: * mcimadamore@877: * This code is distributed in the hope that it will be useful, but WITHOUT mcimadamore@877: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mcimadamore@877: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mcimadamore@877: * version 2 for more details (a copy is included in the LICENSE file that mcimadamore@877: * accompanied this code). mcimadamore@877: * mcimadamore@877: * You should have received a copy of the GNU General Public License version mcimadamore@877: * 2 along with this work; if not, write to the Free Software Foundation, mcimadamore@877: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mcimadamore@877: * mcimadamore@877: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mcimadamore@877: * or visit www.oracle.com if you need additional information or have any mcimadamore@877: * questions. mcimadamore@877: */ mcimadamore@877: mcimadamore@877: /* mcimadamore@877: * @test mcimadamore@877: * @bug 7017664 mcimadamore@877: * @summary Basher for CompoundScopes mcimadamore@877: */ mcimadamore@877: mcimadamore@877: import java.util.Random; mcimadamore@877: import java.util.Map; mcimadamore@877: import java.util.HashMap; mcimadamore@877: import com.sun.tools.javac.util.*; mcimadamore@877: import com.sun.tools.javac.code.*; mcimadamore@877: import com.sun.tools.javac.code.Scope.*; mcimadamore@877: import com.sun.tools.javac.code.Symbol.*; mcimadamore@877: import com.sun.tools.javac.file.JavacFileManager; mcimadamore@877: mcimadamore@877: public class CompoundScopeTest { mcimadamore@877: public static void main(String... args) throws Exception { mcimadamore@877: new CompoundScopeTest().run(args); mcimadamore@877: } mcimadamore@877: mcimadamore@877: static final int MAX_SYMBOLS_COUNT = 20; mcimadamore@877: static final int PASSES = 10; mcimadamore@877: mcimadamore@877: void run(String... args) throws Exception { mcimadamore@877: int count = PASSES; mcimadamore@877: mcimadamore@877: for (int i = 0; i < args.length; i++) { mcimadamore@877: String arg = args[i]; mcimadamore@877: if (arg.equals("-seed") && (i + 1 < args.length)) mcimadamore@877: seed = Long.parseLong(args[++i]); mcimadamore@877: else if(arg.equals("-tests") && (i + 1 < args.length)) mcimadamore@877: count = Integer.parseInt(args[++i]); mcimadamore@877: else mcimadamore@877: throw new Exception("unknown arg: " + arg); mcimadamore@877: } mcimadamore@877: mcimadamore@877: rgen = new Random(seed); mcimadamore@877: mcimadamore@877: for (int i = 0; i < count; i++) { mcimadamore@877: Test t = new Test(); mcimadamore@877: t.run(); mcimadamore@877: } mcimadamore@877: mcimadamore@877: if (errors > 0) mcimadamore@877: throw new Exception(errors + " errors found"); mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Write a message to stderr. mcimadamore@877: */ mcimadamore@877: void log(String msg) { mcimadamore@877: System.err.println(msg); mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Write an error message to stderr. mcimadamore@877: */ mcimadamore@877: void error(String msg) { mcimadamore@877: System.err.println("Error: " + msg); mcimadamore@877: errors++; mcimadamore@877: } mcimadamore@877: mcimadamore@877: Random rgen; mcimadamore@877: long seed = 0; mcimadamore@877: mcimadamore@877: int errors; mcimadamore@877: mcimadamore@877: /** Class to encapsulate a test run. */ mcimadamore@877: class Test { mcimadamore@877: mcimadamore@877: List elems = List.nil(); mcimadamore@877: Map> shadowedMap = new HashMap>(); mcimadamore@877: mcimadamore@877: /** Run the test. */ mcimadamore@877: void run() throws Exception { mcimadamore@877: log ("starting test"); mcimadamore@877: setup(); mcimadamore@877: Scope[] scopes = { createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)), mcimadamore@877: createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)), mcimadamore@877: createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)) }; mcimadamore@877: boolean[][] scopeNesting = { {false, true, false, true}, mcimadamore@877: {false, true, true, true}, mcimadamore@877: {false, false, true, true} }; mcimadamore@877: /** mcimadamore@877: * We want to generate (and check) the following compound scopes: mcimadamore@877: * C1 = C(S1, S2, S3) mcimadamore@877: * C2 = C((S1, S2), S3) mcimadamore@877: * C3 = C(S1, (S2, S3)) mcimadamore@877: * C3 = C(C(S1, S2, S3)) mcimadamore@877: */ mcimadamore@877: for (int i = 0 ; i < 4 ; i ++) { mcimadamore@877: CompoundScope root = new CompoundScope(symtab.noSymbol); mcimadamore@877: CompoundScope sub = new CompoundScope(symtab.noSymbol); mcimadamore@877: boolean subAdded = false; mcimadamore@877: for (int sc = 0 ; sc < 3 ; sc ++) { mcimadamore@877: if (scopeNesting[sc][i]) { mcimadamore@877: sub.addSubScope(scopes[sc]); mcimadamore@877: if (!subAdded) { mcimadamore@877: root.addSubScope(sub); mcimadamore@877: subAdded = true; mcimadamore@877: } mcimadamore@877: } else { mcimadamore@877: root.addSubScope(scopes[sc]); mcimadamore@877: } mcimadamore@877: } mcimadamore@877: log("testing scope: " + root); mcimadamore@877: checkElems(root); mcimadamore@877: checkShadowed(root); mcimadamore@877: } mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Create a scope containing a given number of synthetic symbols mcimadamore@877: */ mcimadamore@877: Scope createScope(int nelems) { mcimadamore@877: Scope s = new Scope(symtab.noSymbol); mcimadamore@877: for (int i = 0 ; i < nelems ; i++) { mcimadamore@877: Symbol sym = new TypeSymbol(0, names.fromString("s" + i), null, null); mcimadamore@877: s.enter(sym); mcimadamore@877: elems = elems.prepend(sym); mcimadamore@877: List shadowed = shadowedMap.get(sym.name); mcimadamore@877: if (shadowed == null) { mcimadamore@877: shadowed = List.nil(); mcimadamore@877: } mcimadamore@877: shadowedMap.put(sym.name, shadowed.prepend(sym)); mcimadamore@877: } mcimadamore@877: return s; mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Setup compiler context mcimadamore@877: */ mcimadamore@877: void setup() { mcimadamore@877: log ("setup"); mcimadamore@877: context = new Context(); mcimadamore@877: JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab mcimadamore@877: names = Names.instance(context); // Name.Table impls tied to an instance of Names mcimadamore@877: symtab = Symtab.instance(context); mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Check that CompoundScope.getElements() correctly visits all symbols mcimadamore@877: * in all subscopes (in the correct order) mcimadamore@877: */ mcimadamore@877: void checkElems(CompoundScope cs) { mcimadamore@877: List allSymbols = elems; mcimadamore@877: int count = 0; mcimadamore@877: for (Symbol s : cs.getElements()) { mcimadamore@877: checkSameSymbols(s, allSymbols.head); mcimadamore@877: allSymbols = allSymbols.tail; mcimadamore@877: count++; mcimadamore@877: } mcimadamore@877: if (count != elems.size()) { mcimadamore@877: error("CompoundScope.getElements() did not returned enough symbols"); mcimadamore@877: } mcimadamore@877: } mcimadamore@877: mcimadamore@877: /** mcimadamore@877: * Check that CompoundScope.getElements() correctly visits all symbols mcimadamore@877: * with a given name in all subscopes (in the correct order) mcimadamore@877: */ mcimadamore@877: void checkShadowed(CompoundScope cs) { mcimadamore@877: for (Map.Entry> shadowedEntry : shadowedMap.entrySet()) { mcimadamore@877: int count = 0; mcimadamore@877: List shadowed = shadowedEntry.getValue(); mcimadamore@877: Name name = shadowedEntry.getKey(); mcimadamore@877: for (Symbol s : cs.getElementsByName(name)) { mcimadamore@877: checkSameSymbols(s, shadowed.head); mcimadamore@877: shadowed = shadowed.tail; mcimadamore@877: count++; mcimadamore@877: } mcimadamore@877: if (count != shadowedEntry.getValue().size()) { mcimadamore@877: error("CompoundScope.lookup() did not returned enough symbols for name " + name); mcimadamore@877: } mcimadamore@877: } mcimadamore@877: } mcimadamore@877: mcimadamore@877: void checkSameSymbols(Symbol found, Symbol req) { mcimadamore@877: if (found != req) { mcimadamore@877: error("Symbol mismatch - found : " + found + ":" + found.hashCode() + "\n" + mcimadamore@877: " required : " + req + ":" + req.hashCode()); mcimadamore@877: } mcimadamore@877: } mcimadamore@877: mcimadamore@877: Context context; mcimadamore@877: Symtab symtab; mcimadamore@877: Names names; mcimadamore@877: } mcimadamore@877: }