/** Class to encapsulate a test run. */ class Test { /** Run the test. */ void run() throws Exception {
log ("starting test");
setup();
createStarImportScope();
test();
}
/** *Setupenvbycreatingpseudo-randomcollectionofnames,packagesandclasses.
*/ void setup() {
log ("setup");
context = new Context();
JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
make = TreeMaker.instance(context);
names = Names.instance(context); // Name.Table impls tied to an instance of Names
symtab = Symtab.instance(context);
types = Types.instance(context); int setupCount = rgen.nextInt(MAX_SETUP_COUNT); for (int i = 0; i < setupCount; i++) { switch (random(SetupKind.values())) { case NAMES:
setupNames(); break; casePACKAGE:
setupPackage(); break; caseCLASS:
setupClass(); break;
}
}
}
/** *Setuparandomnumberofnames.
*/ void setupNames() { int count = rgen.nextInt(MAX_SETUP_NAME_COUNT);
log("setup: creating " + count + " new names"); for (int i = 0; i < count; i++) {
names.fromString("n" + (++nextNameSerial));
}
}
/** *Setupapackagecontainingarandomnumberofmemberelements.
*/ void setupPackage() {
Name name = names.fromString("p" + (++nextPackageSerial)); int count = rgen.nextInt(MAX_SETUP_PACKAGE_COUNT);
log("setup: creating package " + name + " with " + count + " entries");
PackageSymbol p = new PackageSymbol(name, symtab.rootPackage);
p.members_field = WriteableScope.create(p); for (int i = 0; i < count; i++) {
String outer = name + "c" + i;
String suffix = random(null, "$Entry", "$Entry2");
ClassSymbol c1 = createClass(names.fromString(outer), p); // log("setup: created " + c1); if (suffix != null) {
ClassSymbol c2 = createClass(names.fromString(outer + suffix), p); // log("setup: created " + c2);
}
} // log("package " + p, p.members_field);
packages.add(p);
imports.add(p);
}
/** *Setupaclasscontainingarandomnumberofmemberelements.
*/ void setupClass() {
Name name = names.fromString("c" + (++nextClassSerial)); int count = rgen.nextInt(MAX_SETUP_CLASS_COUNT);
log("setup: creating class " + name + " with " + count + " entries");
ClassSymbol c = createClass(name, symtab.unnamedModule.unnamedPackage); // log("setup: created " + c); for (int i = 0; i < count; i++) {
ClassSymbol ic = createClass(names.fromString("Entry" + i), c); // log("setup: created " + ic);
}
classes.add(c);
imports.add(c);
}
/** *Thecoreofthetest.Inarandomorder,movenestedclassesfrom *thepackageinwhichtheycreatedtotheclasswhichshouldownthem.
*/ void test() {
log ("test");
List<ClassSymbol> nestedClasses = new LinkedList<ClassSymbol>(); for (PackageSymbol p: packages) { for (Symbol sym : p.members_field.getSymbols()) { if (sym.name.toString().contains("$"))
nestedClasses.add((ClassSymbol) sym);
}
}
for (int i = nestedClasses.size(); i > 0; i--) { // select a random nested class to move from package to class
ClassSymbol sym = nestedClasses.remove(rgen.nextInt(i));
log("adjusting class " + sym);
// remove from star import model
starImportModel.remove(sym);
String s = sym.name.toString(); int dollar = s.indexOf("$");
// owner should be a package assert (sym.owner.kind == PCK);
ClassSymbol createClass(Name name, Symbol owner) {
ClassSymbol sym = new ClassSymbol(0, name, owner);
sym.members_field = WriteableScope.create(sym); if (owner != symtab.unnamedModule.unnamedPackage)
owner.members().enter(sym); return sym;
}
Context context;
Symtab symtab;
TreeMaker make;
Names names;
Types types; int nextNameSerial;
List<PackageSymbol> packages = new ArrayList<PackageSymbol>(); int nextPackageSerial;
List<ClassSymbol> classes = new ArrayList<ClassSymbol>();
List<Symbol> imports = new ArrayList<Symbol>(); int nextClassSerial;
StarImportScope starImportScope;
Model starImportModel;
}
class Model { private Map<Name, Set<Symbol>> map = new HashMap<Name, Set<Symbol>>(); private Set<Symbol> bogus = new HashSet<Symbol>();
void enter(Symbol sym) {
Set<Symbol> syms = map.get(sym.name); if (syms == null)
map.put(sym.name, syms = new LinkedHashSet<Symbol>());
syms.add(sym);
}
void remove(Symbol sym) {
Set<Symbol> syms = map.get(sym.name); if (syms == null)
error("no entries for " + sym.name + " found in reference model"); else { boolean ok = syms.remove(sym); if (ok) { // log(sym.name + "(" + sym + ") removed from reference model");
} else {
error(sym.name + " not found in reference model");
} if (syms.isEmpty())
map.remove(sym.name);
}
}
/** *Checkthecontentsofascope
*/ void check(Scope scope) { // First, check all entries in scope are in map int bogusCount = 0; for (Symbol sym : scope.getSymbols()) { if (sym.owner != scope.getOrigin(sym).owner) { if (bogus.contains(sym)) {
bogusCount++;
} else {
log("Warning: " + sym.name + ":" + sym + " appears to be bogus");
bogus.add(sym);
}
} else {
Set<Symbol> syms = map.get(sym.name); if (syms == null) {
error("check: no entries found for " + sym.name + ":" + sym + " in reference map");
} elseif (!syms.contains(sym)) {
error("check: symbol " + sym.name + ":" + sym + " not found in reference map");
}
}
} if (bogusCount > 0) {
log("Warning: " + bogusCount + " other bogus entries previously reported");
}
// Second, check all entries in map are in scope for (Map.Entry<Name,Set<Symbol>> me: map.entrySet()) {
Name name = me.getKey(); if (scope.findFirst(name) == null) {
error("check: no entries found for " + name + " in scope"); continue;
}
nextSym: for (Symbol sym: me.getValue()) { for (Symbol s : scope.getSymbolsByName(name)) { if (sym == s) continue nextSym;
}
error("check: symbol " + sym + " not found in scope");
}
}
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.