use of com.sun.tools.javac.code.Scope in project ceylon by eclipse.
the class HashCollisionTest method run.
void run() throws Exception {
// set up basic environment for test
Context context = new Context();
// required by ClassReader which is required by Symtab
JavacFileManager.preRegister(context);
// Name.Table impls tied to an instance of Names
names = Names.instance(context);
symtab = Symtab.instance(context);
// determine hashMask for an empty scope
// any owner will do
Scope emptyScope = new Scope(symtab.unnamedPackage);
Field sHashMask = Scope.class.getDeclaredField("hashMask");
sHashMask.setAccessible(true);
scopeHashMask = sHashMask.getInt(emptyScope);
log("scopeHashMask: " + scopeHashMask);
// 1. determine the Name.hashCode of "Entry", and therefore the index of
// Entry in an empty scope. i.e. name.hashCode() & Scope.hashMask
Name entry = names.fromString("Entry");
// 2. create names of the form *$Entry until we find a name with a
// hashcode which yields the same index as Entry in an empty scope.
// Since Name.hashCode is a function of position (and not content) it
// should work to create successively longer names until one with the
// desired characteristics is found.
Name outerName;
Name innerName;
StringBuilder sb = new StringBuilder("C");
int i = 0;
do {
sb.append(Integer.toString(i % 10));
innerName = names.fromString(sb + "$Entry");
} while (!clash(entry, innerName) && (++i) < MAX_TRIES);
if (clash(entry, innerName)) {
log("Detected expected hash collision for " + entry + " and " + innerName + " after " + i + " tries");
} else {
throw new Exception("No potential collision found after " + i + " tries");
}
outerName = names.fromString(sb.toString());
/*
* Now we can set up the scenario.
*/
// 3. Create a nested class named Entry
ClassSymbol cc = createClass(names.fromString("C"), symtab.unnamedPackage);
ClassSymbol ce = createClass(entry, cc);
// 4. Create a package containing a nested class using the name from 2
PackageSymbol p = new PackageSymbol(names.fromString("p"), symtab.rootPackage);
p.members_field = new Scope(p);
ClassSymbol inner = createClass(innerName, p);
// we'll need this later when we "rename" cn
ClassSymbol outer = createClass(outerName, p);
// 5. Create a star-import scope
log("createStarImportScope");
// if StarImportScope exists, use it, otherwise, for testing legacy code,
// fall back on ImportScope
Scope starImportScope;
Method importAll;
PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
try {
Class<?> c = Class.forName("com.sun.tools.javac.code.Scope$StarImportScope");
Constructor ctor = c.getDeclaredConstructor(new Class[] { Symbol.class });
importAll = c.getDeclaredMethod("importAll", new Class[] { Scope.class });
starImportScope = (Scope) ctor.newInstance(new Object[] { pkg });
} catch (ClassNotFoundException e) {
starImportScope = new ImportScope(pkg);
importAll = null;
}
dump("initial", starImportScope);
// 6. Insert the contents of the package from 4.
Scope p_members = p.members();
if (importAll != null) {
importAll.invoke(starImportScope, p_members);
} else {
Scope fromScope = p_members;
Scope toScope = starImportScope;
// before the use of StarImportScope.importAll.
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
if (e.sym.kind == TYP && !toScope.includes(e.sym))
toScope.enter(e.sym, fromScope);
}
}
dump("imported p", starImportScope);
// 7. Insert the class from 3.
starImportScope.enter(ce, cc.members_field);
dump("imported ce", starImportScope);
/*
* Set the trap.
*/
// 8. Rename the nested class to Entry. so that there is a bogus entry in the star-import scope
p.members_field.remove(inner);
inner.name = entry;
inner.owner = outer;
outer.members_field.enter(inner);
// 9. Lookup Entry
Scope.Entry e = starImportScope.lookup(entry);
dump("final", starImportScope);
if (e.sym == null)
throw new Exception("symbol not found: " + entry);
}
use of com.sun.tools.javac.code.Scope in project error-prone by google.
the class ASTHelpers method findMatchingMethods.
/**
* Finds all methods in any superclass of {@code startClass} with a certain {@code name} that
* match the given {@code predicate}.
*
* @return The (possibly empty) set of methods in any superclass that match {@code predicate} and
* have the given {@code name}.
*/
public static Set<MethodSymbol> findMatchingMethods(Name name, final Predicate<MethodSymbol> predicate, Type startClass, Types types) {
Filter<Symbol> matchesMethodPredicate = sym -> sym instanceof MethodSymbol && predicate.apply((MethodSymbol) sym);
Set<MethodSymbol> matchingMethods = new HashSet<>();
// Iterate over all classes and interfaces that startClass inherits from.
for (Type superClass : types.closure(startClass)) {
// Iterate over all the methods declared in superClass.
TypeSymbol superClassSymbol = superClass.tsym;
Scope superClassSymbols = superClassSymbol.members();
if (superClassSymbols != null) {
// Can be null if superClass is a type variable
for (Symbol symbol : superClassSymbols.getSymbolsByName(name, matchesMethodPredicate, NON_RECURSIVE)) {
// By definition of the filter, we know that the symbol is a MethodSymbol.
matchingMethods.add((MethodSymbol) symbol);
}
}
}
return matchingMethods;
}
use of com.sun.tools.javac.code.Scope in project ceylon-compiler by ceylon.
the class Attr method visitLetExpr.
/* Added for Ceylon, required by the ExpressionTransformer */
@Override
public void visitLetExpr(LetExpr tree) {
Scope scope;
if (env.info.scope.owner.kind == Kinds.VAR) {
// for field initialisers we must access the parent scope, otherwise we get
// a DelegateScope which doesn't allow us to declare new variables
scope = env.info.scope.next;
} else
scope = env.info.scope;
if (scope instanceof DelegatedScope) {
throw new AssertionError("Broken use of LetExpr");
}
// make a new environment which captures the current one
Env<AttrContext> localEnv = env.dup(tree, env.info.dup(scope.dup()));
// Field initialisers have not been entered yet, so we need to do it now:
if (localEnv.info.scope.owner.kind == Kinds.TYP) {
memberEnter.memberEnter(tree, localEnv);
annotate.flush();
}
// find the lint
Env<AttrContext> lintEnv = env;
while (lintEnv.info.lint == null) lintEnv = lintEnv.next;
// Having found the enclosing lint value, we can initialize the lint value for this let
localEnv.info.lint = lintEnv.info.lint;
Lint prevLint = chk.setLint(env.info.lint);
try {
// do statements if we have any
if (tree.stats != null) {
if (sourceLanguage.isCeylon())
completeLocalTypes(tree.stats, localEnv);
attribStats(tree.stats, localEnv);
}
// now attribute the expression with the LET expected type (pt)
attribExpr(tree.expr, localEnv, pt);
// the type of the LET is the type of the expression
tree.type = tree.expr.type;
// same code in TransTypes.visit(LetExpr)
if (tree.type.constValue() != null && tree.stats != null && !tree.stats.isEmpty())
tree.type = tree.type.baseType();
} finally {
// exit the LET scope
localEnv.info.scope.leave();
// restore the previous lint
chk.setLint(prevLint);
}
}
use of com.sun.tools.javac.code.Scope in project ceylon-compiler by ceylon.
the class Attr method getSyntheticScopeMapping.
/**
* Creates a synthetic scope containing fake generic constructors.
* Assuming that the original scope contains a constructor of the kind:
* Foo(X x, Y y), where X,Y are class type-variables declared in Foo,
* the synthetic scope is added a generic constructor of the kind:
* <X,Y>Foo<X,Y>(X x, Y y). This is crucial in order to enable diamond
* inference. The inferred return type of the synthetic constructor IS
* the inferred type for the diamond operator.
*/
private Pair<Scope, Scope> getSyntheticScopeMapping(Type ctype) {
if (ctype.tag != CLASS) {
return erroneousMapping;
}
Pair<Scope, Scope> mapping = new Pair<Scope, Scope>(ctype.tsym.members(), new Scope(ctype.tsym));
// declared, and insert it into the new scope.
for (Scope.Entry e = mapping.fst.lookup(names.init); e.scope != null; e = e.next()) {
Type synthRestype = new ClassType(ctype.getEnclosingType(), ctype.tsym.type.getTypeArguments(), ctype.tsym);
MethodSymbol synhConstr = new MethodSymbol(e.sym.flags(), names.init, types.createMethodTypeWithReturn(e.sym.type, synthRestype), e.sym.owner);
mapping.snd.enter(synhConstr);
}
return mapping;
}
use of com.sun.tools.javac.code.Scope in project ceylon-compiler by ceylon.
the class Enter method visitTopLevel.
@Override
public void visitTopLevel(JCCompilationUnit tree) {
JavaFileObject prev = log.useSource(tree.sourcefile);
boolean addEnv = false;
boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
if (tree.pid != null) {
tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
if (isPkgInfo) {
addEnv = true;
} else {
log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
}
}
} else {
tree.packge = syms.unnamedPackage;
}
// Find all classes in package.
tree.packge.complete();
Env<AttrContext> topEnv = topLevelEnv(tree);
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> env0 = typeEnvs.get(tree.packge);
if (env0 == null) {
typeEnvs.put(tree.packge, topEnv);
} else {
JCCompilationUnit tree0 = env0.toplevel;
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
log.warning(tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
if (addEnv || (tree0.packageAnnotations.isEmpty() && tree.docComments != null && tree.docComments.get(tree) != null)) {
typeEnvs.put(tree.packge, topEnv);
}
}
}
for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
Name name = names.package_info;
ClassSymbol c = reader.enterClass(name, tree.packge);
c.flatname = names.fromString(tree.packge + "." + name);
c.sourcefile = tree.sourcefile;
c.completer = null;
c.members_field = new Scope(c);
tree.packge.package_info = c;
}
classEnter(tree.defs, topEnv);
if (addEnv) {
todo.append(topEnv);
}
log.useSource(prev);
result = null;
}
Aggregations