8031569: Refactor javac scope implementation to enable lazy imports

Introducing an internal API for Scope; rewriting ImportScopes to extend CompoundScopes.

Co-authored-by: Maurizio Cimadamore <maurizio.cimadamore@oracle.com>
Reviewed-by: mcimadamore, jjg, jfranck
This commit is contained in:
Jan Lahoda 2014-07-09 16:32:05 +02:00
parent c2f98fba15
commit 0067b70725
50 changed files with 1614 additions and 1383 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -46,18 +46,33 @@ import com.sun.tools.javac.comp.Env;
* @author Jonathan Gibbons; * @author Jonathan Gibbons;
*/ */
public class JavacScope implements com.sun.source.tree.Scope { public class JavacScope implements com.sun.source.tree.Scope {
static JavacScope create(Env<AttrContext> env) {
if (env.outer == null || env.outer == env) {
//the "top-level" scope needs to return both imported and defined elements
//see test CheckLocalElements
return new JavacScope(env) {
@Override
public Iterable<? extends Element> getLocalElements() {
return env.toplevel.namedImportScope.getSymbols();
}
};
} else {
return new JavacScope(env);
}
}
protected final Env<AttrContext> env; protected final Env<AttrContext> env;
/** Creates a new instance of JavacScope */ private JavacScope(Env<AttrContext> env) {
JavacScope(Env<AttrContext> env) {
env.getClass(); // null-check env.getClass(); // null-check
this.env = env; this.env = env;
} }
public JavacScope getEnclosingScope() { public JavacScope getEnclosingScope() {
if (env.outer != null && env.outer != env) if (env.outer != null && env.outer != env) {
return new JavacScope(env.outer); return create(env.outer);
else { } else {
// synthesize an outermost "star-import" scope // synthesize an outermost "star-import" scope
return new JavacScope(env) { return new JavacScope(env) {
public boolean isStarImportScope() { public boolean isStarImportScope() {
@ -67,7 +82,7 @@ public class JavacScope implements com.sun.source.tree.Scope {
return null; return null;
} }
public Iterable<? extends Element> getLocalElements() { public Iterable<? extends Element> getLocalElements() {
return env.toplevel.starImportScope.getElements(); return env.toplevel.starImportScope.getSymbols();
} }
}; };
} }

View File

@ -456,10 +456,9 @@ public class JavacTrees extends DocTrees {
} }
searched.add(tsym); searched.add(tsym);
for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(fieldName); for (Symbol sym : tsym.members().getSymbolsByName(fieldName)) {
e.scope != null; e = e.next()) { if (sym.kind == Kinds.VAR) {
if (e.sym.kind == Kinds.VAR) { return (VarSymbol)sym;
return (VarSymbol)e.sym;
} }
} }
@ -499,11 +498,10 @@ public class JavacTrees extends DocTrees {
/** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */ /** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) { MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(names.init); for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
e.scope != null; e = e.next()) { if (sym.kind == Kinds.MTH) {
if (e.sym.kind == Kinds.MTH) { if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) { return (MethodSymbol) sym;
return (MethodSymbol) e.sym;
} }
} }
} }
@ -529,7 +527,6 @@ public class JavacTrees extends DocTrees {
searched.add(tsym); searched.add(tsym);
// search current class // search current class
com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(methodName);
//### Using modifier filter here isn't really correct, //### Using modifier filter here isn't really correct,
//### but emulates the old behavior. Instead, we should //### but emulates the old behavior. Instead, we should
@ -542,10 +539,10 @@ public class JavacTrees extends DocTrees {
// In order to provide textually identical results, we // In order to provide textually identical results, we
// attempt to emulate the old behavior. // attempt to emulate the old behavior.
MethodSymbol lastFound = null; MethodSymbol lastFound = null;
for (; e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
if (e.sym.kind == Kinds.MTH) { if (sym.kind == Kinds.MTH) {
if (e.sym.name == methodName) { if (sym.name == methodName) {
lastFound = (MethodSymbol)e.sym; lastFound = (MethodSymbol)sym;
} }
} }
} }
@ -553,11 +550,11 @@ public class JavacTrees extends DocTrees {
return lastFound; return lastFound;
} }
} else { } else {
for (; e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
if (e.sym != null && if (sym != null &&
e.sym.kind == Kinds.MTH) { sym.kind == Kinds.MTH) {
if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) { if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
return (MethodSymbol) e.sym; return (MethodSymbol) sym;
} }
} }
} }
@ -684,7 +681,7 @@ public class JavacTrees extends DocTrees {
} }
public JavacScope getScope(TreePath path) { public JavacScope getScope(TreePath path) {
return new JavacScope(getAttrContext(path)); return JavacScope.create(getAttrContext(path));
} }
public String getDocComment(TreePath path) { public String getDocComment(TreePath path) {

View File

@ -37,6 +37,7 @@ import javax.tools.StandardJavaFileManager;
import static javax.tools.StandardLocation.*; import static javax.tools.StandardLocation.*;
import com.sun.tools.javac.comp.Annotate; import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
@ -218,7 +219,7 @@ public class ClassFinder {
if (c.owner.kind == PCK) { if (c.owner.kind == PCK) {
Symbol owner = c.owner; Symbol owner = c.owner;
for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) { for (Name name : Convert.enclosingCandidates(Convert.shortName(c.name))) {
Symbol encl = owner.members().lookup(name).sym; Symbol encl = owner.members().findFirst(name);
if (encl == null) if (encl == null)
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner)); encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
if (encl != null) if (encl != null)
@ -335,7 +336,7 @@ public class ClassFinder {
boolean isPkgInfo = classname == names.package_info; boolean isPkgInfo = classname == names.package_info;
ClassSymbol c = isPkgInfo ClassSymbol c = isPkgInfo
? p.package_info ? p.package_info
: (ClassSymbol) p.members_field.lookup(classname).sym; : (ClassSymbol) p.members_field.findFirst(classname);
if (c == null) { if (c == null) {
c = syms.enterClass(classname, p); c = syms.enterClass(classname, p);
if (c.classfile == null) // only update the file if's it's newly created if (c.classfile == null) // only update the file if's it's newly created
@ -399,7 +400,7 @@ public class ClassFinder {
*/ */
private void fillIn(PackageSymbol p) throws IOException { private void fillIn(PackageSymbol p) throws IOException {
if (p.members_field == null) if (p.members_field == null)
p.members_field = new Scope(p); p.members_field = WriteableScope.create(p);
preferCurrent = false; preferCurrent = false;
if (userPathsFirst) { if (userPathsFirst) {

File diff suppressed because it is too large Load Diff

View File

@ -33,19 +33,21 @@ import java.util.concurrent.Callable;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr; import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.comp.Env;
import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.FORALL; import static com.sun.tools.javac.code.TypeTag.FORALL;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
/** Root class for Java symbols. It contains subclasses /** Root class for Java symbols. It contains subclasses
* for specific sorts of symbols, such as variables, methods and operators, * for specific sorts of symbols, such as variables, methods and operators,
@ -376,7 +378,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
/** If this is a class or package, its members, otherwise null. /** If this is a class or package, its members, otherwise null.
*/ */
public Scope members() { public WriteableScope members() {
return null; return null;
} }
@ -475,15 +477,13 @@ public abstract class Symbol extends AnnoConstruct implements Element {
if (currentClass == owner) { if (currentClass == owner) {
return this; return this;
} }
Scope.Entry e = currentClass.members().lookup(name); for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
while (e.scope != null) { if (sym.kind == kind &&
if (e.sym.kind == kind &&
(kind != MTH || (kind != MTH ||
(e.sym.flags() & STATIC) != 0 && (sym.flags() & STATIC) != 0 &&
types.isSubSignature(e.sym.type, type))) { types.isSubSignature(sym.type, type))) {
return e.sym; return sym;
} }
e = e.next();
} }
Symbol hiddenSym = null; Symbol hiddenSym = null;
for (Type st : types.interfaces(currentClass.type) for (Type st : types.interfaces(currentClass.type)
@ -632,7 +632,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public boolean isConstructor() { return other.isConstructor(); } public boolean isConstructor() { return other.isConstructor(); }
public Name getQualifiedName() { return other.getQualifiedName(); } public Name getQualifiedName() { return other.getQualifiedName(); }
public Name flatName() { return other.flatName(); } public Name flatName() { return other.flatName(); }
public Scope members() { return other.members(); } public WriteableScope members() { return other.members(); }
public boolean isInner() { return other.isInner(); } public boolean isInner() { return other.isInner(); }
public boolean hasOuterInstance() { return other.hasOuterInstance(); } public boolean hasOuterInstance() { return other.hasOuterInstance(); }
public ClassSymbol enclClass() { return other.enclClass(); } public ClassSymbol enclClass() { return other.enclClass(); }
@ -721,9 +721,9 @@ public abstract class Symbol extends AnnoConstruct implements Element {
if (kind == TYP && type.hasTag(TYPEVAR)) { if (kind == TYP && type.hasTag(TYPEVAR)) {
return list; return list;
} }
for (Scope.Entry e = members().elems; e != null; e = e.sibling) { for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this) if (sym != null && (sym.flags() & SYNTHETIC) == 0 && sym.owner == this)
list = list.prepend(e.sym); list = list.prepend(sym);
} }
return list; return list;
} }
@ -818,7 +818,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public static class PackageSymbol extends TypeSymbol public static class PackageSymbol extends TypeSymbol
implements PackageElement { implements PackageElement {
public Scope members_field; public WriteableScope members_field;
public Name fullname; public Name fullname;
public ClassSymbol package_info; // see bug 6443073 public ClassSymbol package_info; // see bug 6443073
@ -845,7 +845,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
return name.isEmpty() && owner != null; return name.isEmpty() && owner != null;
} }
public Scope members() { public WriteableScope members() {
if (completer != null) complete(); if (completer != null) complete();
return members_field; return members_field;
} }
@ -910,7 +910,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
/** a scope for all class members; variables, methods and inner classes /** a scope for all class members; variables, methods and inner classes
* type parameters are not part of this scope * type parameters are not part of this scope
*/ */
public Scope members_field; public WriteableScope members_field;
/** the fully qualified name of the class, i.e. pck.outer.inner. /** the fully qualified name of the class, i.e. pck.outer.inner.
* null for anonymous classes * null for anonymous classes
@ -971,7 +971,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
return flags_field; return flags_field;
} }
public Scope members() { public WriteableScope members() {
if (completer != null) complete(); if (completer != null) complete();
return members_field; return members_field;
} }
@ -1397,15 +1397,13 @@ public abstract class Symbol extends AnnoConstruct implements Element {
public Symbol implementedIn(TypeSymbol c, Types types) { public Symbol implementedIn(TypeSymbol c, Types types) {
Symbol impl = null; Symbol impl = null;
for (Scope.Entry e = c.members().lookup(name); for (Symbol sym : c.members().getSymbolsByName(name)) {
impl == null && e.scope != null; if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
e = e.next()) {
if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
// FIXME: I suspect the following requires a // FIXME: I suspect the following requires a
// subst() for a parametric return type. // subst() for a parametric return type.
types.isSameType(type.getReturnType(), types.isSameType(type.getReturnType(),
types.memberType(owner.type, e.sym).getReturnType())) { types.memberType(owner.type, sym).getReturnType())) {
impl = e.sym; impl = sym;
} }
} }
return impl; return impl;
@ -1441,12 +1439,10 @@ public abstract class Symbol extends AnnoConstruct implements Element {
*/ */
public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) { public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) { for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
for (Scope.Entry e = c.members().lookup(name); for (Symbol sym : c.members().getSymbolsByName(name)) {
e.scope != null; if (sym.kind == MTH &&
e = e.next()) { ((MethodSymbol)sym).binaryOverrides(this, origin, types))
if (e.sym.kind == MTH && return (MethodSymbol)sym;
((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
return (MethodSymbol)e.sym;
} }
} }
return null; return null;

View File

@ -34,6 +34,7 @@ import javax.lang.model.element.ElementVisitor;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.Completer; import com.sun.tools.javac.code.Symbol.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.CompletionFailure;
@ -396,7 +397,7 @@ public class Symtab {
sym.completer = null; sym.completer = null;
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE; sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
sym.erasure_field = type; sym.erasure_field = type;
sym.members_field = new Scope(sym); sym.members_field = WriteableScope.create(sym);
type.typarams_field = List.nil(); type.typarams_field = List.nil();
type.allparams_field = List.nil(); type.allparams_field = List.nil();
type.supertype_field = annotationType; type.supertype_field = annotationType;
@ -466,7 +467,7 @@ public class Symtab {
// Create class to hold all predefined constants and operations. // Create class to hold all predefined constants and operations.
predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage); predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
Scope scope = new Scope(predefClass); WriteableScope scope = WriteableScope.create(predefClass);
predefClass.members_field = scope; predefClass.members_field = scope;
// Get the initial completer for Symbols from the ClassFinder // Get the initial completer for Symbols from the ClassFinder
@ -578,7 +579,7 @@ public class Symtab {
ClassType arrayClassType = (ClassType)arrayClass.type; ClassType arrayClassType = (ClassType)arrayClass.type;
arrayClassType.supertype_field = objectType; arrayClassType.supertype_field = objectType;
arrayClassType.interfaces_field = List.of(cloneableType, serializableType); arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
arrayClass.members_field = new Scope(arrayClass); arrayClass.members_field = WriteableScope.create(arrayClass);
lengthVar = new VarSymbol( lengthVar = new VarSymbol(
PUBLIC | FINAL, PUBLIC | FINAL,
names.length, names.length,

View File

@ -403,7 +403,7 @@ public class Types {
} }
final ListBuffer<Symbol> abstracts = new ListBuffer<>(); final ListBuffer<Symbol> abstracts = new ListBuffer<>();
for (Symbol sym : membersCache.getElements(new DescriptorFilter(origin))) { for (Symbol sym : membersCache.getSymbols(new DescriptorFilter(origin))) {
Type mtype = memberType(origin.type, sym); Type mtype = memberType(origin.type, sym);
if (abstracts.isEmpty() || if (abstracts.isEmpty() ||
(sym.name == abstracts.first().name && (sym.name == abstracts.first().name &&
@ -633,7 +633,7 @@ public class Types {
Type descType = findDescriptorType(targets.head); Type descType = findDescriptorType(targets.head);
ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass()); ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
csym.completer = null; csym.completer = null;
csym.members_field = new Scope(csym); csym.members_field = WriteableScope.create(csym);
MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym); MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
csym.members_field.enter(instDescSym); csym.members_field.enter(instDescSym);
Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym, Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym,
@ -655,7 +655,7 @@ public class Types {
Symbol descSym = findDescriptorSymbol(origin); Symbol descSym = findDescriptorSymbol(origin);
CompoundScope members = membersClosure(origin.type, false); CompoundScope members = membersClosure(origin.type, false);
ListBuffer<Symbol> overridden = new ListBuffer<>(); ListBuffer<Symbol> overridden = new ListBuffer<>();
outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { outer: for (Symbol m2 : members.getSymbolsByName(descSym.name, bridgeFilter)) {
if (m2 == descSym) continue; if (m2 == descSym) continue;
else if (descSym.overrides(m2, origin, Types.this, false)) { else if (descSym.overrides(m2, origin, Types.this, false)) {
for (Symbol m3 : overridden) { for (Symbol m3 : overridden) {
@ -2290,7 +2290,7 @@ public class Types {
bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ? bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
syms.objectType : // error condition, recover syms.objectType : // error condition, recover
erasure(firstExplicitBound); erasure(firstExplicitBound);
bc.members_field = new Scope(bc); bc.members_field = WriteableScope.create(bc);
return bc.type; return bc.type;
} }
@ -2619,8 +2619,8 @@ public class Types {
} }
public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) { public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) {
for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) { for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) {
if (msym.overrides(e.sym, origin, Types.this, true)) { if (msym.overrides(sym, origin, Types.this, true)) {
return true; return true;
} }
} }
@ -2680,12 +2680,10 @@ public class Types {
while (t.hasTag(TYPEVAR)) while (t.hasTag(TYPEVAR))
t = t.getUpperBound(); t = t.getUpperBound();
TypeSymbol c = t.tsym; TypeSymbol c = t.tsym;
for (Scope.Entry e = c.members().lookup(ms.name, implFilter); for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {
e.scope != null; if (sym != null &&
e = e.next(implFilter)) { sym.overrides(ms, origin, Types.this, checkResult))
if (e.sym != null && return (MethodSymbol)sym;
e.sym.overrides(ms, origin, Types.this, checkResult))
return (MethodSymbol)e.sym;
} }
} }
return null; return null;
@ -2742,11 +2740,11 @@ public class Types {
CompoundScope membersClosure = new CompoundScope(csym); CompoundScope membersClosure = new CompoundScope(csym);
if (!skipInterface) { if (!skipInterface) {
for (Type i : interfaces(t)) { for (Type i : interfaces(t)) {
membersClosure.addSubScope(visit(i, skipInterface)); membersClosure.prependSubScope(visit(i, skipInterface));
} }
} }
membersClosure.addSubScope(visit(supertype(t), skipInterface)); membersClosure.prependSubScope(visit(supertype(t), skipInterface));
membersClosure.addSubScope(csym.members()); membersClosure.prependSubScope(csym.members());
e = new Entry(skipInterface, membersClosure); e = new Entry(skipInterface, membersClosure);
_map.put(csym, e); _map.put(csym, e);
} }
@ -2775,7 +2773,7 @@ public class Types {
public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) { public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
Filter<Symbol> filter = new MethodFilter(ms, site); Filter<Symbol> filter = new MethodFilter(ms, site);
List<MethodSymbol> candidates = List.nil(); List<MethodSymbol> candidates = List.nil();
for (Symbol s : membersClosure(site, false).getElements(filter)) { for (Symbol s : membersClosure(site, false).getSymbols(filter)) {
if (!site.tsym.isInterface() && !s.owner.isInterface()) { if (!site.tsym.isInterface() && !s.owner.isInterface()) {
return List.of((MethodSymbol)s); return List.of((MethodSymbol)s);
} else if (!candidates.contains(s)) { } else if (!candidates.contains(s)) {

View File

@ -690,7 +690,7 @@ public class Annotate {
Scope scope = targetContainerType.tsym.members(); Scope scope = targetContainerType.tsym.members();
int nr_value_elems = 0; int nr_value_elems = 0;
boolean error = false; boolean error = false;
for(Symbol elm : scope.getElementsByName(names.value)) { for(Symbol elm : scope.getSymbolsByName(names.value)) {
nr_value_elems++; nr_value_elems++;
if (nr_value_elems == 1 && if (nr_value_elems == 1 &&

View File

@ -37,6 +37,7 @@ import com.sun.source.tree.TreeVisitor;
import com.sun.source.util.SimpleTreeVisitor; import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Check.CheckContext; import com.sun.tools.javac.comp.Check.CheckContext;
@ -618,14 +619,11 @@ public class Attr extends JCTree.Visitor {
return newEnv; return newEnv;
} }
Scope copyScope(Scope sc) { WriteableScope copyScope(WriteableScope sc) {
Scope newScope = new Scope(sc.owner); WriteableScope newScope = WriteableScope.create(sc.owner);
List<Symbol> elemsList = List.nil(); List<Symbol> elemsList = List.nil();
while (sc != null) { for (Symbol sym : sc.getSymbols()) {
for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) { elemsList = elemsList.prepend(sym);
elemsList = elemsList.prepend(e.sym);
}
sc = sc.next;
} }
for (Symbol s : elemsList) { for (Symbol s : elemsList) {
newScope.enter(s); newScope.enter(s);
@ -1140,12 +1138,12 @@ public class Attr extends JCTree.Visitor {
// Block is a static or instance initializer; // Block is a static or instance initializer;
// let the owner of the environment be a freshly // let the owner of the environment be a freshly
// created BLOCK-method. // created BLOCK-method.
final Env<AttrContext> localEnv = Symbol fakeOwner =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
localEnv.info.scope.owner =
new MethodSymbol(tree.flags | BLOCK | new MethodSymbol(tree.flags | BLOCK |
env.info.scope.owner.flags() & STRICTFP, names.empty, null, env.info.scope.owner.flags() & STRICTFP, names.empty, null,
env.info.scope.owner); env.info.scope.owner);
final Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared(fakeOwner)));
if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++; if ((tree.flags & STATIC) != 0) localEnv.info.staticLevel++;
attribStats(tree.stats, localEnv); attribStats(tree.stats, localEnv);
@ -1328,7 +1326,7 @@ public class Attr extends JCTree.Visitor {
} }
// where // where
/** Add any variables defined in stats to the switch scope. */ /** Add any variables defined in stats to the switch scope. */
private static void addVars(List<JCStatement> stats, Scope switchScope) { private static void addVars(List<JCStatement> stats, WriteableScope switchScope) {
for (;stats.nonEmpty(); stats = stats.tail) { for (;stats.nonEmpty(); stats = stats.tail) {
JCTree stat = stats.head; JCTree stat = stats.head;
if (stat.hasTag(VARDEF)) if (stat.hasTag(VARDEF))
@ -1344,10 +1342,9 @@ public class Attr extends JCTree.Visitor {
} }
JCIdent ident = (JCIdent)tree; JCIdent ident = (JCIdent)tree;
Name name = ident.name; Name name = ident.name;
for (Scope.Entry e = enumType.tsym.members().lookup(name); for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
e.scope != null; e = e.next()) { if (sym.kind == VAR) {
if (e.sym.kind == VAR) { Symbol s = ident.sym = sym;
Symbol s = ident.sym = e.sym;
((VarSymbol)s).getConstValue(); // ensure initializer is evaluated ((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
ident.type = s.type; ident.type = s.type;
return ((s.flags_field & Flags.ENUM) == 0) return ((s.flags_field & Flags.ENUM) == 0)
@ -2343,7 +2340,7 @@ public class Attr extends JCTree.Visitor {
Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym); Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym);
int count = 0; int count = 0;
boolean found = false; boolean found = false;
for (Symbol sym : csym.members().getElements()) { for (Symbol sym : csym.members().getSymbols()) {
if ((sym.flags() & SYNTHETIC) != 0 || if ((sym.flags() & SYNTHETIC) != 0 ||
sym.isConstructor()) continue; sym.isConstructor()) continue;
count++; count++;
@ -2774,15 +2771,15 @@ public class Attr extends JCTree.Visitor {
Symbol owner = env.info.scope.owner; Symbol owner = env.info.scope.owner;
if (owner.kind == VAR && owner.owner.kind == TYP) { if (owner.kind == VAR && owner.owner.kind == TYP) {
//field initializer //field initializer
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared()));
ClassSymbol enclClass = owner.enclClass(); ClassSymbol enclClass = owner.enclClass();
Symbol newScopeOwner = env.info.scope.owner;
/* if the field isn't static, then we can get the first constructor /* if the field isn't static, then we can get the first constructor
* and use it as the owner of the environment. This is what * and use it as the owner of the environment. This is what
* LTM code is doing to look for type annotations so we are fine. * LTM code is doing to look for type annotations so we are fine.
*/ */
if ((owner.flags() & STATIC) == 0) { if ((owner.flags() & STATIC) == 0) {
for (Symbol s : enclClass.members_field.getElementsByName(names.init)) { for (Symbol s : enclClass.members_field.getSymbolsByName(names.init)) {
lambdaEnv.info.scope.owner = s; newScopeOwner = s;
break; break;
} }
} else { } else {
@ -2798,8 +2795,9 @@ public class Attr extends JCTree.Visitor {
clinit.params = List.<VarSymbol>nil(); clinit.params = List.<VarSymbol>nil();
clinits.put(enclClass, clinit); clinits.put(enclClass, clinit);
} }
lambdaEnv.info.scope.owner = clinit; newScopeOwner = clinit;
} }
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner)));
} else { } else {
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup())); lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
} }
@ -4515,7 +4513,7 @@ public class Attr extends JCTree.Visitor {
for (List<JCTypeParameter> l = tree.typarams; for (List<JCTypeParameter> l = tree.typarams;
l.nonEmpty(); l = l.tail) { l.nonEmpty(); l = l.tail) {
Assert.checkNonNull(env.info.scope.lookup(l.head.name).scope); Assert.checkNonNull(env.info.scope.findFirst(l.head.name));
} }
// Check that a generic class doesn't extend Throwable // Check that a generic class doesn't extend Throwable
@ -4602,16 +4600,21 @@ public class Attr extends JCTree.Visitor {
private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) { private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
// check for presence of serialVersionUID // check for presence of serialVersionUID
Scope.Entry e = c.members().lookup(names.serialVersionUID); VarSymbol svuid = null;
while (e.scope != null && e.sym.kind != VAR) e = e.next(); for (Symbol sym : c.members().getSymbolsByName(names.serialVersionUID)) {
if (e.scope == null) { if (sym.kind == VAR) {
svuid = (VarSymbol)sym;
break;
}
}
if (svuid == null) {
log.warning(LintCategory.SERIAL, log.warning(LintCategory.SERIAL,
tree.pos(), "missing.SVUID", c); tree.pos(), "missing.SVUID", c);
return; return;
} }
// check that it is static final // check that it is static final
VarSymbol svuid = (VarSymbol)e.sym;
if ((svuid.flags() & (STATIC | FINAL)) != if ((svuid.flags() & (STATIC | FINAL)) !=
(STATIC | FINAL)) (STATIC | FINAL))
log.warning(LintCategory.SERIAL, log.warning(LintCategory.SERIAL,

View File

@ -27,6 +27,7 @@ package com.sun.tools.javac.comp;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
/** Contains information specific to the attribute and enter /** Contains information specific to the attribute and enter
* passes, to be used in place of the generic field in environments. * passes, to be used in place of the generic field in environments.
@ -40,7 +41,7 @@ public class AttrContext {
/** The scope of local symbols. /** The scope of local symbols.
*/ */
Scope scope = null; WriteableScope scope = null;
/** The number of enclosing `static' modifiers. /** The number of enclosing `static' modifiers.
*/ */
@ -87,7 +88,7 @@ public class AttrContext {
/** Duplicate this context, replacing scope field and copying all others. /** Duplicate this context, replacing scope field and copying all others.
*/ */
AttrContext dup(Scope scope) { AttrContext dup(WriteableScope scope) {
AttrContext info = new AttrContext(); AttrContext info = new AttrContext();
info.scope = scope; info.scope = scope;
info.staticLevel = staticLevel; info.staticLevel = staticLevel;
@ -112,7 +113,7 @@ public class AttrContext {
public Iterable<Symbol> getLocalElements() { public Iterable<Symbol> getLocalElements() {
if (scope == null) if (scope == null)
return List.nil(); return List.nil();
return scope.getElements(); return scope.getSymbols();
} }
boolean lastResolveVarargs() { boolean lastResolveVarargs() {

View File

@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
import java.util.*; import java.util.*;
import javax.tools.JavaFileManager; import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.Compound; import com.sun.tools.javac.code.Attribute.Compound;
@ -39,6 +40,8 @@ import com.sun.tools.javac.util.List;
import com.sun.tools.javac.code.Lint; import com.sun.tools.javac.code.Lint;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Scope.NamedImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext; import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
@ -51,6 +54,7 @@ import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.ANNOTATION; import static com.sun.tools.javac.code.Flags.ANNOTATION;
import static com.sun.tools.javac.code.Flags.SYNCHRONIZED; import static com.sun.tools.javac.code.Flags.SYNCHRONIZED;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.code.TypeTag.WILDCARD; import static com.sun.tools.javac.code.TypeTag.WILDCARD;
@ -362,16 +366,13 @@ public class Check {
* @param s The scope. * @param s The scope.
*/ */
void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) { void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
if (s.next != null) { for (Symbol sym : s.getSymbolsByName(v.name)) {
for (Scope.Entry e = s.next.lookup(v.name); if (sym.owner != v.owner) break;
e.scope != null && e.sym.owner == v.owner; if (sym.kind == VAR &&
e = e.next()) { (sym.owner.kind & (VAR | MTH)) != 0 &&
if (e.sym.kind == VAR && v.name != names.error) {
(e.sym.owner.kind & (VAR | MTH)) != 0 && duplicateError(pos, sym);
v.name != names.error) { return;
duplicateError(pos, e.sym);
return;
}
} }
} }
} }
@ -383,16 +384,13 @@ public class Check {
* @param s The scope. * @param s The scope.
*/ */
void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) { void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
if (s.next != null) { for (Symbol sym : s.getSymbolsByName(c.name)) {
for (Scope.Entry e = s.next.lookup(c.name); if (sym.owner != c.owner) break;
e.scope != null && e.sym.owner == c.owner; if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
e = e.next()) { (sym.owner.kind & (VAR | MTH)) != 0 &&
if (e.sym.kind == TYP && !e.sym.type.hasTag(TYPEVAR) && c.name != names.error) {
(e.sym.owner.kind & (VAR | MTH)) != 0 && duplicateError(pos, sym);
c.name != names.error) { return;
duplicateError(pos, e.sym);
return;
}
} }
} }
} }
@ -405,9 +403,9 @@ public class Check {
* @param s The enclosing scope. * @param s The enclosing scope.
*/ */
boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) { boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) { for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
if (e.sym.kind == TYP && e.sym.name != names.error) { if (sym.kind == TYP && sym.name != names.error) {
duplicateError(pos, e.sym); duplicateError(pos, sym);
return false; return false;
} }
} }
@ -1778,10 +1776,7 @@ public class Check {
for (Type t1 = sup; for (Type t1 = sup;
t1.hasTag(CLASS) && t1.tsym.type.isParameterized(); t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
t1 = types.supertype(t1)) { t1 = types.supertype(t1)) {
for (Scope.Entry e1 = t1.tsym.members().elems; for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
e1 != null;
e1 = e1.sibling) {
Symbol s1 = e1.sym;
if (s1.kind != MTH || if (s1.kind != MTH ||
(s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 || (s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
!s1.isInheritedIn(site.tsym, types) || !s1.isInheritedIn(site.tsym, types) ||
@ -1796,10 +1791,7 @@ public class Check {
for (Type t2 = sup; for (Type t2 = sup;
t2.hasTag(CLASS); t2.hasTag(CLASS);
t2 = types.supertype(t2)) { t2 = types.supertype(t2)) {
for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
e2.scope != null;
e2 = e2.next()) {
Symbol s2 = e2.sym;
if (s2 == s1 || if (s2 == s1 ||
s2.kind != MTH || s2.kind != MTH ||
(s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 || (s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
@ -1893,15 +1885,13 @@ public class Check {
/** Return the first method in t2 that conflicts with a method from t1. */ /** Return the first method in t2 that conflicts with a method from t1. */
private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) { private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) { for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
Symbol s1 = e1.sym;
Type st1 = null; Type st1 = null;
if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) || if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
(s1.flags() & SYNTHETIC) != 0) continue; (s1.flags() & SYNTHETIC) != 0) continue;
Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false); Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
if (impl != null && (impl.flags() & ABSTRACT) == 0) continue; if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) { for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
Symbol s2 = e2.sym;
if (s1 == s2) continue; if (s1 == s2) continue;
if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) || if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
(s2.flags() & SYNTHETIC) != 0) continue; (s2.flags() & SYNTHETIC) != 0) continue;
@ -1944,8 +1934,7 @@ public class Check {
Type st2 = types.memberType(site, s2); Type st2 = types.memberType(site, s2);
closure(site, supertypes); closure(site, supertypes);
for (Type t : supertypes.values()) { for (Type t : supertypes.values()) {
for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) { for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
Symbol s3 = e.sym;
if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue; if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
Type st3 = types.memberType(site,s3); Type st3 = types.memberType(site,s3);
if (types.overrideEquivalent(st3, st1) && if (types.overrideEquivalent(st3, st1) &&
@ -1995,14 +1984,12 @@ public class Check {
void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) { void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
TypeSymbol c = site.tsym; TypeSymbol c = site.tsym;
Scope.Entry e = c.members().lookup(m.name); for (Symbol sym : c.members().getSymbolsByName(m.name)) {
while (e.scope != null) { if (m.overrides(sym, origin, types, false)) {
if (m.overrides(e.sym, origin, types, false)) { if ((sym.flags() & ABSTRACT) == 0) {
if ((e.sym.flags() & ABSTRACT) == 0) { checkOverride(tree, m, (MethodSymbol)sym, origin);
checkOverride(tree, m, (MethodSymbol)e.sym, origin);
} }
} }
e = e.next();
} }
} }
@ -2037,9 +2024,9 @@ public class Check {
ClassSymbol someClass) { ClassSymbol someClass) {
if (lint.isEnabled(LintCategory.OVERRIDES)) { if (lint.isEnabled(LintCategory.OVERRIDES)) {
MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
.tsym.members().lookup(names.equals).sym; .tsym.members().findFirst(names.equals);
MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
.tsym.members().lookup(names.hashCode).sym; .tsym.members().findFirst(names.hashCode);
boolean overridesEquals = types.implementation(equalsAtObject, boolean overridesEquals = types.implementation(equalsAtObject,
someClass, false, equalsHasCodeFilter).owner == someClass; someClass, false, equalsHasCodeFilter).owner == someClass;
boolean overridesHashCode = types.implementation(hashCodeAtObject, boolean overridesHashCode = types.implementation(hashCodeAtObject,
@ -2095,12 +2082,10 @@ public class Check {
// since they cannot have abstract members. // since they cannot have abstract members.
if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) { if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
Scope s = c.members(); Scope s = c.members();
for (Scope.Entry e = s.elems; for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
undef == null && e != null; if (sym.kind == MTH &&
e = e.sibling) { (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
if (e.sym.kind == MTH && MethodSymbol absmeth = (MethodSymbol)sym;
(e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
MethodSymbol absmeth = (MethodSymbol)e.sym;
MethodSymbol implmeth = absmeth.implementation(impl, types, true); MethodSymbol implmeth = absmeth.implementation(impl, types, true);
if (implmeth == null || implmeth == absmeth) { if (implmeth == null || implmeth == absmeth) {
//look for default implementations //look for default implementations
@ -2113,6 +2098,7 @@ public class Check {
} }
if (implmeth == null || implmeth == absmeth) { if (implmeth == null || implmeth == absmeth) {
undef = absmeth; undef = absmeth;
break;
} }
} }
} }
@ -2336,10 +2322,10 @@ public class Check {
for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) { for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
ClassSymbol lc = (ClassSymbol)l.head.tsym; ClassSymbol lc = (ClassSymbol)l.head.tsym;
if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) { if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) { for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
if (e.sym.kind == MTH && if (sym.kind == MTH &&
(e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) { (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol absmeth = (MethodSymbol)sym;
MethodSymbol implmeth = absmeth.implementation(origin, types, false); MethodSymbol implmeth = absmeth.implementation(origin, types, false);
if (implmeth != null && implmeth != absmeth && if (implmeth != null && implmeth != absmeth &&
(implmeth.owner.flags() & INTERFACE) == (implmeth.owner.flags() & INTERFACE) ==
@ -2382,15 +2368,15 @@ public class Check {
void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) { void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) { for (Type ct = c.type; ct != Type.noType ; ct = types.supertype(ct)) {
for (Scope.Entry e = ct.tsym.members().lookup(sym.name); e.scope == ct.tsym.members(); e = e.next()) { for (Symbol sym2 : ct.tsym.members().getSymbolsByName(sym.name, NON_RECURSIVE)) {
// VM allows methods and variables with differing types // VM allows methods and variables with differing types
if (sym.kind == e.sym.kind && if (sym.kind == sym2.kind &&
types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) && types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
sym != e.sym && sym != sym2 &&
(sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) && (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
(sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 && (sym.flags() & IPROXY) == 0 && (sym2.flags() & IPROXY) == 0 &&
(sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) { (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym); syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
return; return;
} }
} }
@ -2411,7 +2397,7 @@ public class Check {
List<MethodSymbol> potentiallyAmbiguousList = List.nil(); List<MethodSymbol> potentiallyAmbiguousList = List.nil();
boolean overridesAny = false; boolean overridesAny = false;
for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { for (Symbol m1 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
if (!sym.overrides(m1, site.tsym, types, false)) { if (!sym.overrides(m1, site.tsym, types, false)) {
if (m1 == sym) { if (m1 == sym) {
continue; continue;
@ -2429,7 +2415,7 @@ public class Check {
} }
//...check each method m2 that is a member of 'site' //...check each method m2 that is a member of 'site'
for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) { for (Symbol m2 : types.membersClosure(site, false).getSymbolsByName(sym.name, cf)) {
if (m2 == m1) continue; if (m2 == m1) continue;
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) m1 has the same erasure as m2, issue an error //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
@ -2466,7 +2452,7 @@ public class Check {
void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) { void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
ClashFilter cf = new ClashFilter(site); ClashFilter cf = new ClashFilter(site);
//for each method m1 that is a member of 'site'... //for each method m1 that is a member of 'site'...
for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { for (Symbol s : types.membersClosure(site, true).getSymbolsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as //if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) { if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck)) {
@ -2508,7 +2494,7 @@ public class Check {
void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) { void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site); DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
for (Symbol m : types.membersClosure(site, false).getElements(dcf)) { for (Symbol m : types.membersClosure(site, false).getSymbols(dcf)) {
Assert.check(m.kind == MTH); Assert.check(m.kind == MTH);
List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m); List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
if (prov.size() > 1) { if (prov.size() > 1) {
@ -2772,11 +2758,11 @@ public class Check {
void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) { void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) { for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
Scope s = sup.tsym.members(); Scope s = sup.tsym.members();
for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) { for (Symbol sym : s.getSymbolsByName(m.name)) {
if (e.sym.kind == MTH && if (sym.kind == MTH &&
(e.sym.flags() & (PUBLIC | PROTECTED)) != 0 && (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
types.overrideEquivalent(m.type, e.sym.type)) types.overrideEquivalent(m.type, sym.type))
log.error(pos, "intf.annotation.member.clash", e.sym, sup); log.error(pos, "intf.annotation.member.clash", sym, sup);
} }
} }
} }
@ -2856,9 +2842,9 @@ public class Check {
} }
private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) { private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
Scope.Entry e = container.members().lookup(names.value); Symbol sym = container.members().findFirst(names.value);
if (e.scope != null && e.sym.kind == MTH) { if (sym != null && sym.kind == MTH) {
MethodSymbol m = (MethodSymbol) e.sym; MethodSymbol m = (MethodSymbol) sym;
Type ret = m.getReturnType(); Type ret = m.getReturnType();
if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) { if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
log.error(pos, "invalid.repeatable.annotation.value.return", log.error(pos, "invalid.repeatable.annotation.value.return",
@ -3003,7 +2989,7 @@ public class Check {
private void validateDefault(Symbol container, DiagnosticPosition pos) { private void validateDefault(Symbol container, DiagnosticPosition pos) {
// validate that all other elements of containing type has defaults // validate that all other elements of containing type has defaults
Scope scope = container.members(); Scope scope = container.members();
for(Symbol elm : scope.getElements()) { for(Symbol elm : scope.getSymbols()) {
if (elm.name != names.value && if (elm.name != names.value &&
elm.kind == Kinds.MTH && elm.kind == Kinds.MTH &&
((MethodSymbol)elm).defaultValue == null) { ((MethodSymbol)elm).defaultValue == null) {
@ -3025,8 +3011,8 @@ public class Check {
if (sup == owner.type) if (sup == owner.type)
continue; // skip "this" continue; // skip "this"
Scope scope = sup.tsym.members(); Scope scope = sup.tsym.members();
for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) { for (Symbol sym : scope.getSymbolsByName(m.name)) {
if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true)) if (!sym.isStatic() && m.overrides(sym, owner, types, true))
return true; return true;
} }
} }
@ -3160,12 +3146,10 @@ public class Check {
boolean isValid = true; boolean isValid = true;
// collect an inventory of the annotation elements // collect an inventory of the annotation elements
Set<MethodSymbol> members = new LinkedHashSet<>(); Set<MethodSymbol> members = new LinkedHashSet<>();
for (Scope.Entry e = a.annotationType.type.tsym.members().elems; for (Symbol sym : a.annotationType.type.tsym.members().getSymbols(NON_RECURSIVE))
e != null; if (sym.kind == MTH && sym.name != names.clinit &&
e = e.sibling) (sym.flags() & SYNTHETIC) == 0)
if (e.sym.kind == MTH && e.sym.name != names.clinit && members.add((MethodSymbol) sym);
(e.sym.flags() & SYNTHETIC) == 0)
members.add((MethodSymbol) e.sym);
// remove the ones that are assigned values // remove the ones that are assigned values
for (JCTree arg : a.args) { for (JCTree arg : a.args) {
@ -3293,8 +3277,7 @@ public class Check {
} }
try { try {
tsym.flags_field |= LOCKED; tsym.flags_field |= LOCKED;
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
Symbol s = e.sym;
if (s.kind != Kinds.MTH) if (s.kind != Kinds.MTH)
continue; continue;
checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType()); checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
@ -3436,23 +3419,23 @@ public class Check {
if (sym.type.isErroneous()) if (sym.type.isErroneous())
return true; return true;
if (sym.owner.name == names.any) return false; if (sym.owner.name == names.any) return false;
for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) { for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
if (sym != e.sym && if (sym != byName &&
(e.sym.flags() & CLASH) == 0 && (byName.flags() & CLASH) == 0 &&
sym.kind == e.sym.kind && sym.kind == byName.kind &&
sym.name != names.error && sym.name != names.error &&
(sym.kind != MTH || (sym.kind != MTH ||
types.hasSameArgs(sym.type, e.sym.type) || types.hasSameArgs(sym.type, byName.type) ||
types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) { types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) { if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
varargsDuplicateError(pos, sym, e.sym); varargsDuplicateError(pos, sym, byName);
return true; return true;
} else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) { } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
duplicateErasureError(pos, sym, e.sym); duplicateErasureError(pos, sym, byName);
sym.flags_field |= CLASH; sym.flags_field |= CLASH;
return true; return true;
} else { } else {
duplicateError(pos, e.sym); duplicateError(pos, byName);
return false; return false;
} }
} }
@ -3471,47 +3454,50 @@ public class Check {
/** Check that single-type import is not already imported or top-level defined, /** Check that single-type import is not already imported or top-level defined,
* but make an exception for two single-type imports which denote the same type. * but make an exception for two single-type imports which denote the same type.
* @param pos Position for error reporting. * @param pos Position for error reporting.
* @param toplevel The file in which in the check is performed.
* @param sym The symbol. * @param sym The symbol.
* @param s The scope
*/ */
boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) { boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
return checkUniqueImport(pos, sym, s, false); return checkUniqueImport(pos, toplevel, sym, false);
} }
/** Check that static single-type import is not already imported or top-level defined, /** Check that static single-type import is not already imported or top-level defined,
* but make an exception for two single-type imports which denote the same type. * but make an exception for two single-type imports which denote the same type.
* @param pos Position for error reporting. * @param pos Position for error reporting.
* @param toplevel The file in which in the check is performed.
* @param sym The symbol. * @param sym The symbol.
* @param s The scope
*/ */
boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) { boolean checkUniqueStaticImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
return checkUniqueImport(pos, sym, s, true); return checkUniqueImport(pos, toplevel, sym, true);
} }
/** Check that single-type import is not already imported or top-level defined, /** Check that single-type import is not already imported or top-level defined,
* but make an exception for two single-type imports which denote the same type. * but make an exception for two single-type imports which denote the same type.
* @param pos Position for error reporting. * @param pos Position for error reporting.
* @param toplevel The file in which in the check is performed.
* @param sym The symbol. * @param sym The symbol.
* @param s The scope.
* @param staticImport Whether or not this was a static import * @param staticImport Whether or not this was a static import
*/ */
private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) { private boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym, boolean staticImport) {
for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) { NamedImportScope namedImportScope = toplevel.namedImportScope;
WriteableScope topLevelScope = toplevel.toplevelScope;
for (Symbol byName : namedImportScope.getSymbolsByName(sym.name)) {
// is encountered class entered via a class declaration? // is encountered class entered via a class declaration?
boolean isClassDecl = e.scope == s; boolean isClassDecl = namedImportScope.getOrigin(byName) == topLevelScope;
if ((isClassDecl || sym != e.sym) && if ((isClassDecl || sym != byName) &&
sym.kind == e.sym.kind && sym.kind == byName.kind &&
sym.name != names.error && sym.name != names.error &&
(!staticImport || !e.isStaticallyImported())) { (!staticImport || !namedImportScope.isStaticallyImported(byName))) {
if (!e.sym.type.isErroneous()) { if (!byName.type.isErroneous()) {
if (!isClassDecl) { if (!isClassDecl) {
if (staticImport) if (staticImport)
log.error(pos, "already.defined.static.single.import", e.sym); log.error(pos, "already.defined.static.single.import", byName);
else else
log.error(pos, "already.defined.single.import", e.sym); log.error(pos, "already.defined.single.import", byName);
} }
else if (sym != e.sym) else if (sym != byName)
log.error(pos, "already.defined.this.unit", e.sym); log.error(pos, "already.defined.this.unit", byName);
} }
return false; return false;
} }
@ -3610,4 +3596,68 @@ public class Check {
} }
} }
} }
public void checkImportsResolvable(final JCCompilationUnit toplevel) {
for (final JCImport imp : toplevel.getImports()) {
if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
continue;
final JCFieldAccess select = (JCFieldAccess) imp.qualid;
final Symbol origin;
if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
continue;
JavaFileObject prev = log.useSource(toplevel.sourcefile);
try {
TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
log.error(imp.pos(), "cant.resolve.location",
KindName.STATIC,
select.name, List.<Type>nil(), List.<Type>nil(),
Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
TreeInfo.symbol(select.selected).type);
}
} finally {
log.useSource(prev);
}
}
}
private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
if (tsym == null || !processed.add(tsym))
return false;
// also search through inherited names
if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
return true;
for (Type t : types.interfaces(tsym.type))
if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
return true;
for (Symbol sym : tsym.members().getSymbolsByName(name)) {
if (sym.isStatic() &&
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types)) {
return true;
}
}
return false;
}
// is the sym accessible everywhere in packge?
public boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
int flags = (int)(sym.flags() & AccessFlags);
switch (flags) {
default:
case PUBLIC:
return true;
case PRIVATE:
return false;
case 0:
case PROTECTED:
return sym.packge() == packge;
}
}
} }

View File

@ -376,9 +376,8 @@ public class DeferredAttr extends JCTree.Visitor {
ResultInfo resultInfo, ResultInfo resultInfo,
Annotate.PositionCreator creator) { Annotate.PositionCreator creator) {
final JCTree newTree = new TreeCopier<>(make).copy(tree); final JCTree newTree = new TreeCopier<>(make).copy(tree);
Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared())); Env<AttrContext> speculativeEnv = env.dup(newTree, env.info.dup(env.info.scope.dupUnshared(env.info.scope.owner)));
speculativeEnv.info.isSpeculative = true; speculativeEnv.info.isSpeculative = true;
speculativeEnv.info.scope.owner = env.info.scope.owner;
Log.DeferredDiagnosticHandler deferredDiagnosticHandler = Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() { new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() {
public boolean accepts(final JCDiagnostic d) { public boolean accepts(final JCDiagnostic d) {

View File

@ -191,7 +191,7 @@ public class Enter extends JCTree.Visitor {
*/ */
public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) { public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
Env<AttrContext> localEnv = Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(new Scope(tree.sym))); env.dup(tree, env.info.dup(WriteableScope.create(tree.sym)));
localEnv.enclClass = tree; localEnv.enclClass = tree;
localEnv.outer = env; localEnv.outer = env;
localEnv.info.isSelfCall = false; localEnv.info.isSelfCall = false;
@ -207,9 +207,10 @@ public class Enter extends JCTree.Visitor {
Env<AttrContext> localEnv = new Env<>(tree, new AttrContext()); Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
localEnv.toplevel = tree; localEnv.toplevel = tree;
localEnv.enclClass = predefClassDef; localEnv.enclClass = predefClassDef;
tree.namedImportScope = new ImportScope(tree.packge); tree.toplevelScope = WriteableScope.create(tree.packge);
tree.namedImportScope = new NamedImportScope(tree.packge, tree.toplevelScope);
tree.starImportScope = new StarImportScope(tree.packge); tree.starImportScope = new StarImportScope(tree.packge);
localEnv.info.scope = tree.namedImportScope; localEnv.info.scope = tree.toplevelScope;
localEnv.info.lint = lint; localEnv.info.lint = lint;
return localEnv; return localEnv;
} }
@ -218,7 +219,7 @@ public class Enter extends JCTree.Visitor {
Env<AttrContext> localEnv = new Env<>(tree, new AttrContext()); Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
localEnv.toplevel = tree; localEnv.toplevel = tree;
localEnv.enclClass = predefClassDef; localEnv.enclClass = predefClassDef;
localEnv.info.scope = tree.namedImportScope; localEnv.info.scope = tree.toplevelScope;
localEnv.info.lint = lint; localEnv.info.lint = lint;
return localEnv; return localEnv;
} }
@ -228,7 +229,7 @@ public class Enter extends JCTree.Visitor {
* where the local scope is for type variables, and the this and super symbol * where the local scope is for type variables, and the this and super symbol
* only, and members go into the class member scope. * only, and members go into the class member scope.
*/ */
Scope enterScope(Env<AttrContext> env) { WriteableScope enterScope(Env<AttrContext> env) {
return (env.tree.hasTag(JCTree.Tag.CLASSDEF)) return (env.tree.hasTag(JCTree.Tag.CLASSDEF))
? ((JCClassDecl) env.tree).sym.members_field ? ((JCClassDecl) env.tree).sym.members_field
: env.info.scope; : env.info.scope;
@ -324,7 +325,7 @@ public class Enter extends JCTree.Visitor {
c.flatname = names.fromString(tree.packge + "." + name); c.flatname = names.fromString(tree.packge + "." + name);
c.sourcefile = tree.sourcefile; c.sourcefile = tree.sourcefile;
c.completer = null; c.completer = null;
c.members_field = new Scope(c); c.members_field = WriteableScope.create(c);
tree.packge.package_info = c; tree.packge.package_info = c;
} }
classEnter(tree.defs, topEnv); classEnter(tree.defs, topEnv);
@ -338,7 +339,7 @@ public class Enter extends JCTree.Visitor {
@Override @Override
public void visitClassDef(JCClassDecl tree) { public void visitClassDef(JCClassDecl tree) {
Symbol owner = env.info.scope.owner; Symbol owner = env.info.scope.owner;
Scope enclScope = enterScope(env); WriteableScope enclScope = enterScope(env);
ClassSymbol c; ClassSymbol c;
if (owner.kind == PCK) { if (owner.kind == PCK) {
// We are seeing a toplevel class. // We are seeing a toplevel class.
@ -392,7 +393,7 @@ public class Enter extends JCTree.Visitor {
c.completer = memberEnter; c.completer = memberEnter;
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree); c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
c.sourcefile = env.toplevel.sourcefile; c.sourcefile = env.toplevel.sourcefile;
c.members_field = new Scope(c); c.members_field = WriteableScope.create(c);
ClassType ct = (ClassType)c.type; ClassType ct = (ClassType)c.type;
if (owner.kind != PCK && (c.flags_field & STATIC) == 0) { if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
@ -495,7 +496,7 @@ public class Enter extends JCTree.Visitor {
// if there remain any unimported toplevels (these must have // if there remain any unimported toplevels (these must have
// no classes at all), process their import statements as well. // no classes at all), process their import statements as well.
for (JCCompilationUnit tree : trees) { for (JCCompilationUnit tree : trees) {
if (tree.starImportScope.elems == null) { if (tree.starImportScope.isEmpty()) {
JavaFileObject prev = log.useSource(tree.sourcefile); JavaFileObject prev = log.useSource(tree.sourcefile);
Env<AttrContext> topEnv = topLevelEnv(tree); Env<AttrContext> topEnv = topLevelEnv(tree);
memberEnter.memberEnter(tree, topEnv); memberEnter.memberEnter(tree, topEnv);

View File

@ -30,6 +30,7 @@ package com.sun.tools.javac.comp;
import java.util.HashMap; import java.util.HashMap;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@ -1419,7 +1420,7 @@ public class Flow {
/** The list of unreferenced automatic resources. /** The list of unreferenced automatic resources.
*/ */
Scope unrefdResources; WriteableScope unrefdResources;
/** Set when processing a loop body the second time for DU analysis. */ /** Set when processing a loop body the second time for DU analysis. */
FlowKind flowKind = FlowKind.NORMAL; FlowKind flowKind = FlowKind.NORMAL;
@ -2410,7 +2411,7 @@ public class Flow {
nextadr = 0; nextadr = 0;
pendingExits = new ListBuffer<>(); pendingExits = new ListBuffer<>();
this.classDef = null; this.classDef = null;
unrefdResources = new Scope(env.enclClass.sym); unrefdResources = WriteableScope.create(env.enclClass.sym);
scan(tree); scan(tree);
} finally { } finally {
// note that recursive invocations of this method fail hard // note that recursive invocations of this method fail hard

View File

@ -31,7 +31,7 @@ import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.TreeTranslator; import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol; import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
@ -448,7 +448,7 @@ public class LambdaToMethod extends TreeTranslator {
make.at(prevPos); make.at(prevPos);
} }
// Replace the entered symbol for this variable // Replace the entered symbol for this variable
Scope sc = tree.sym.owner.members(); WriteableScope sc = tree.sym.owner.members();
if (sc != null) { if (sc != null) {
sc.remove(tree.sym); sc.remove(tree.sym);
sc.enter(xsym); sc.enter(xsym);
@ -1475,7 +1475,7 @@ public class LambdaToMethod extends TreeTranslator {
return clinit; return clinit;
} else { } else {
//get the first constructor and treat it as the instance init sym //get the first constructor and treat it as the instance init sym
for (Symbol s : csym.members_field.getElementsByName(names.init)) { for (Symbol s : csym.members_field.getSymbolsByName(names.init)) {
return s; return s;
} }
} }

View File

@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
import java.util.*; import java.util.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.Option.PkgInfo; import com.sun.tools.javac.main.Option.PkgInfo;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
@ -45,6 +46,7 @@ import com.sun.tools.javac.tree.EndPosTable;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK; import static com.sun.tools.javac.code.Flags.BLOCK;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
@ -299,7 +301,7 @@ public class Lower extends TreeTranslator {
Symbol sym = _sym; Symbol sym = _sym;
if (sym.kind == VAR || sym.kind == MTH) { if (sym.kind == VAR || sym.kind == MTH) {
while (sym != null && sym.owner != owner) while (sym != null && sym.owner != owner)
sym = proxies.lookup(proxyName(sym.name)).sym; sym = proxies.findFirst(proxyName(sym.name));
if (sym != null && sym.owner == owner) { if (sym != null && sym.owner == owner) {
VarSymbol v = (VarSymbol)sym; VarSymbol v = (VarSymbol)sym;
if (v.getConstValue() == null) { if (v.getConstValue() == null) {
@ -644,7 +646,7 @@ public class Lower extends TreeTranslator {
} }
c.sourcefile = owner.sourcefile; c.sourcefile = owner.sourcefile;
c.completer = null; c.completer = null;
c.members_field = new Scope(c); c.members_field = WriteableScope.create(c);
c.flags_field = flags; c.flags_field = flags;
ClassType ctype = (ClassType) c.type; ClassType ctype = (ClassType) c.type;
ctype.supertype_field = syms.objectType; ctype.supertype_field = syms.objectType;
@ -678,7 +680,7 @@ public class Lower extends TreeTranslator {
* @param sym The symbol. * @param sym The symbol.
* @param s The scope. * @param s The scope.
*/ */
private void enterSynthetic(DiagnosticPosition pos, Symbol sym, Scope s) { private void enterSynthetic(DiagnosticPosition pos, Symbol sym, WriteableScope s) {
s.enter(sym); s.enter(sym);
} }
@ -746,7 +748,7 @@ public class Lower extends TreeTranslator {
* @param name The name. * @param name The name.
*/ */
private Symbol lookupSynthetic(Name name, Scope s) { private Symbol lookupSynthetic(Name name, Scope s) {
Symbol sym = s.lookup(name).sym; Symbol sym = s.findFirst(name);
return (sym==null || (sym.flags()&SYNTHETIC)==0) ? null : sym; return (sym==null || (sym.flags()&SYNTHETIC)==0) ? null : sym;
} }
@ -901,11 +903,9 @@ public class Lower extends TreeTranslator {
/** Return binary operator that corresponds to given access code. /** Return binary operator that corresponds to given access code.
*/ */
private OperatorSymbol binaryAccessOperator(int acode) { private OperatorSymbol binaryAccessOperator(int acode) {
for (Scope.Entry e = syms.predefClass.members().elems; for (Symbol sym : syms.predefClass.members().getSymbols(NON_RECURSIVE)) {
e != null; if (sym instanceof OperatorSymbol) {
e = e.sibling) { OperatorSymbol op = (OperatorSymbol)sym;
if (e.sym instanceof OperatorSymbol) {
OperatorSymbol op = (OperatorSymbol)e.sym;
if (accessCode(op.opcode) == acode) return op; if (accessCode(op.opcode) == acode) return op;
} }
} }
@ -1143,7 +1143,7 @@ public class Lower extends TreeTranslator {
return makeLit(sym.type, cv); return makeLit(sym.type, cv);
} }
// Otherwise replace the variable by its proxy. // Otherwise replace the variable by its proxy.
sym = proxies.lookup(proxyName(sym.name)).sym; sym = proxies.findFirst(proxyName(sym.name));
Assert.check(sym != null && (sym.flags_field & FINAL) != 0); Assert.check(sym != null && (sym.flags_field & FINAL) != 0);
tree = make.at(tree.pos).Ident(sym); tree = make.at(tree.pos).Ident(sym);
} }
@ -1459,12 +1459,12 @@ public class Lower extends TreeTranslator {
* in an additional innermost scope, where they represent the constructor * in an additional innermost scope, where they represent the constructor
* parameters. * parameters.
*/ */
Scope proxies; WriteableScope proxies;
/** A scope containing all unnamed resource variables/saved /** A scope containing all unnamed resource variables/saved
* exception variables for translated TWR blocks * exception variables for translated TWR blocks
*/ */
Scope twrVars; WriteableScope twrVars;
/** A stack containing the this$n field of the currently translated /** A stack containing the this$n field of the currently translated
* classes (if needed) in innermost first order. * classes (if needed) in innermost first order.
@ -1519,7 +1519,7 @@ public class Lower extends TreeTranslator {
nestingLevel++; nestingLevel++;
} }
Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel); Name result = names.fromString("this" + target.syntheticNameChar() + nestingLevel);
while (owner.kind == TYP && ((ClassSymbol)owner).members().lookup(result).scope != null) while (owner.kind == TYP && ((ClassSymbol)owner).members().findFirst(result) != null)
result = names.fromString(result.toString() + target.syntheticNameChar()); result = names.fromString(result.toString() + target.syntheticNameChar());
return result; return result;
} }
@ -1859,10 +1859,10 @@ public class Lower extends TreeTranslator {
* name is the name of a free variable. * name is the name of a free variable.
*/ */
JCStatement initField(int pos, Name name) { JCStatement initField(int pos, Name name) {
Scope.Entry e = proxies.lookup(name); Iterator<Symbol> it = proxies.getSymbolsByName(name).iterator();
Symbol rhs = e.sym; Symbol rhs = it.next();
Assert.check(rhs.owner.kind == MTH); Assert.check(rhs.owner.kind == MTH);
Symbol lhs = e.next().sym; Symbol lhs = it.next();
Assert.check(rhs.owner.owner == lhs.owner); Assert.check(rhs.owner.owner == lhs.owner);
make.at(pos); make.at(pos);
return return
@ -1903,10 +1903,10 @@ public class Lower extends TreeTranslator {
if ((clazz.flags() & INTERFACE) == 0 && if ((clazz.flags() & INTERFACE) == 0 &&
!target.useInnerCacheClass()) return clazz; !target.useInnerCacheClass()) return clazz;
Scope s = clazz.members(); Scope s = clazz.members();
for (Scope.Entry e = s.elems; e != null; e = e.sibling) for (Symbol sym : s.getSymbols(NON_RECURSIVE))
if (e.sym.kind == TYP && if (sym.kind == TYP &&
e.sym.name == names.empty && sym.name == names.empty &&
(e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym; (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym; return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
} }
@ -2574,7 +2574,7 @@ public class Lower extends TreeTranslator {
// private static final T[] #VALUES = { a, b, c }; // private static final T[] #VALUES = { a, b, c };
Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES"); Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
while (tree.sym.members().lookup(valuesName).scope != null) // avoid name clash while (tree.sym.members().findFirst(valuesName) != null) // avoid name clash
valuesName = names.fromString(valuesName + "" + target.syntheticNameChar()); valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
Type arrayType = new ArrayType(types.erasure(tree.type), Type arrayType = new ArrayType(types.erasure(tree.type),
syms.arrayClass, Type.noAnnotations); syms.arrayClass, Type.noAnnotations);
@ -2602,7 +2602,7 @@ public class Lower extends TreeTranslator {
} else { } else {
// template: T[] $result = new T[$values.length]; // template: T[] $result = new T[$values.length];
Name resultName = names.fromString(target.syntheticNameChar() + "result"); Name resultName = names.fromString(target.syntheticNameChar() + "result");
while (tree.sym.members().lookup(resultName).scope != null) // avoid name clash while (tree.sym.members().findFirst(resultName) != null) // avoid name clash
resultName = names.fromString(resultName + "" + target.syntheticNameChar()); resultName = names.fromString(resultName + "" + target.syntheticNameChar());
VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC, VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC,
resultName, resultName,
@ -2683,8 +2683,7 @@ public class Lower extends TreeTranslator {
private MethodSymbol systemArraycopyMethod; private MethodSymbol systemArraycopyMethod;
private boolean useClone() { private boolean useClone() {
try { try {
Scope.Entry e = syms.objectType.tsym.members().lookup(names.clone); return syms.objectType.tsym.members().findFirst(names.clone) != null;
return (e.sym != null);
} }
catch (CompletionFailure e) { catch (CompletionFailure e) {
return false; return false;
@ -2786,7 +2785,7 @@ public class Lower extends TreeTranslator {
final Name pName = proxyName(l.head.name); final Name pName = proxyName(l.head.name);
m.capturedLocals = m.capturedLocals =
m.capturedLocals.append((VarSymbol) m.capturedLocals.append((VarSymbol)
(proxies.lookup(pName).sym)); (proxies.findFirst(pName)));
added = added.prepend( added = added.prepend(
initField(tree.body.pos, pName)); initField(tree.body.pos, pName));
} }
@ -3969,8 +3968,8 @@ public class Lower extends TreeTranslator {
classdefs = new HashMap<>(); classdefs = new HashMap<>();
actualSymbols = new HashMap<>(); actualSymbols = new HashMap<>();
freevarCache = new HashMap<>(); freevarCache = new HashMap<>();
proxies = new Scope(syms.noSymbol); proxies = WriteableScope.create(syms.noSymbol);
twrVars = new Scope(syms.noSymbol); twrVars = WriteableScope.create(syms.noSymbol);
outerThisStack = List.nil(); outerThisStack = List.nil();
accessNums = new HashMap<>(); accessNums = new HashMap<>();
accessSyms = new HashMap<>(); accessSyms = new HashMap<>();

View File

@ -25,12 +25,18 @@
package com.sun.tools.javac.comp; package com.sun.tools.javac.comp;
import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Set; import java.util.Set;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.ImportFilter;
import com.sun.tools.javac.code.Scope.NamedImportScope;
import com.sun.tools.javac.code.Scope.StarImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.jvm.*; import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.tree.*; import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
@ -43,6 +49,7 @@ import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.ANNOTATION; import static com.sun.tools.javac.code.Flags.ANNOTATION;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.ERROR; import static com.sun.tools.javac.code.TypeTag.ERROR;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
@ -151,7 +158,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
final TypeSymbol tsym, final TypeSymbol tsym,
Env<AttrContext> env) { Env<AttrContext> env) {
// Check that packages imported from exist (JLS ???). // Check that packages imported from exist (JLS ???).
if (tsym.kind == PCK && tsym.members().elems == null && !tsym.exists()) { if (tsym.kind == PCK && tsym.members().isEmpty() && !tsym.exists()) {
// If we can't find java.lang, exit immediately. // If we can't find java.lang, exit immediately.
if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) { if (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang"); JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
@ -160,7 +167,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym); log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym);
} }
} }
env.toplevel.starImportScope.importAll(tsym.members()); env.toplevel.starImportScope.importAll(tsym.members(), tsym.members(), typeImportFilter, false);
} }
/** Import all static members of a class or package on demand. /** Import all static members of a class or package on demand.
@ -171,82 +178,16 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
private void importStaticAll(int pos, private void importStaticAll(int pos,
final TypeSymbol tsym, final TypeSymbol tsym,
Env<AttrContext> env) { Env<AttrContext> env) {
final JavaFileObject sourcefile = env.toplevel.sourcefile; final StarImportScope toScope = env.toplevel.starImportScope;
final Scope toScope = env.toplevel.starImportScope;
final PackageSymbol packge = env.toplevel.packge; final PackageSymbol packge = env.toplevel.packge;
final TypeSymbol origin = tsym; final TypeSymbol origin = tsym;
// enter imported types immediately // enter imported types immediately
new Object() { new SymbolImporter() {
Set<Symbol> processed = new HashSet<>(); void doImport(TypeSymbol tsym) {
void importFrom(TypeSymbol tsym) { toScope.importAll(tsym.members(), origin.members(), staticImportFilter, true);
if (tsym == null || !processed.add(tsym))
return;
// also import inherited names
importFrom(types.supertype(tsym.type).tsym);
for (Type t : types.interfaces(tsym.type))
importFrom(t.tsym);
final Scope fromScope = tsym.members();
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
Symbol sym = e.sym;
if (sym.kind == TYP &&
(sym.flags() & STATIC) != 0 &&
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types) &&
!toScope.includes(sym))
toScope.enter(sym, fromScope, origin.members(), true);
}
} }
}.importFrom(tsym); }.importFrom(tsym);
// enter non-types before annotations that might use them
annotate.earlier(new Annotate.Worker() {
Set<Symbol> processed = new HashSet<>();
public String toString() {
return "import static " + tsym + ".*" + " in " + sourcefile;
}
void importFrom(TypeSymbol tsym) {
if (tsym == null || !processed.add(tsym))
return;
// also import inherited names
importFrom(types.supertype(tsym.type).tsym);
for (Type t : types.interfaces(tsym.type))
importFrom(t.tsym);
final Scope fromScope = tsym.members();
for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
Symbol sym = e.sym;
if (sym.isStatic() && sym.kind != TYP &&
staticImportAccessible(sym, packge) &&
!toScope.includes(sym) &&
sym.isMemberOf(origin, types)) {
toScope.enter(sym, fromScope, origin.members(), true);
}
}
}
public void run() {
importFrom(tsym);
}
});
}
// is the sym accessible everywhere in packge?
boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
int flags = (int)(sym.flags() & AccessFlags);
switch (flags) {
default:
case PUBLIC:
return true;
case PRIVATE:
return false;
case 0:
case PROTECTED:
return sym.packge() == packge;
}
} }
/** Import statics types of a given name. Non-types are handled in Attr. /** Import statics types of a given name. Non-types are handled in Attr.
@ -265,44 +206,47 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
return; return;
} }
final Scope toScope = env.toplevel.namedImportScope; final NamedImportScope toScope = env.toplevel.namedImportScope;
final PackageSymbol packge = env.toplevel.packge; final Scope originMembers = tsym.members();
final TypeSymbol origin = tsym;
// enter imported types immediately // enter imported types immediately
new Object() { new SymbolImporter() {
Set<Symbol> processed = new HashSet<>(); void doImport(TypeSymbol tsym) {
void importFrom(TypeSymbol tsym) { Set<Symbol> maskedOut = null;
if (tsym == null || !processed.add(tsym)) for (Symbol sym : tsym.members().getSymbolsByName(name)) {
return; if (sym.kind == TYP &&
staticImportFilter.accepts(originMembers, sym) &&
// also import inherited names !chk.checkUniqueStaticImport(pos, env.toplevel, sym)) {
importFrom(types.supertype(tsym.type).tsym); if (maskedOut == null)
for (Type t : types.interfaces(tsym.type)) maskedOut = Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>());
importFrom(t.tsym); maskedOut.add(sym);
}
for (Scope.Entry e = tsym.members().lookup(name);
e.scope != null;
e = e.next()) {
Symbol sym = e.sym;
if (sym.isStatic() &&
sym.kind == TYP &&
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types) &&
chk.checkUniqueStaticImport(pos, sym, toScope))
toScope.enter(sym, sym.owner.members(), origin.members(), true);
} }
ImportFilter importFilter = maskedOut != null ?
new MaskedImportFilter(staticImportFilter, maskedOut) :
staticImportFilter;
toScope.importByName(tsym.members(), originMembers, name, importFilter);
} }
}.importFrom(tsym); }.importFrom(tsym);
}
//where:
class MaskedImportFilter implements ImportFilter {
// enter non-types before annotations that might use them private final ImportFilter delegate;
annotate.earlier(new Annotate.Worker() { private final Set<Symbol> maskedOut;
Set<Symbol> processed = new HashSet<>();
boolean found = false;
public String toString() { public MaskedImportFilter(ImportFilter delegate, Set<Symbol> maskedOut) {
return "import static " + tsym + "." + name; this.delegate = delegate;
this.maskedOut = maskedOut;
} }
@Override
public boolean accepts(Scope origin, Symbol sym) {
return !maskedOut.contains(sym) && delegate.accepts(origin, sym);
}
}
abstract class SymbolImporter {
Set<Symbol> processed = new HashSet<>();
void importFrom(TypeSymbol tsym) { void importFrom(TypeSymbol tsym) {
if (tsym == null || !processed.add(tsym)) if (tsym == null || !processed.add(tsym))
return; return;
@ -312,47 +256,21 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
for (Type t : types.interfaces(tsym.type)) for (Type t : types.interfaces(tsym.type))
importFrom(t.tsym); importFrom(t.tsym);
for (Scope.Entry e = tsym.members().lookup(name); doImport(tsym);
e.scope != null;
e = e.next()) {
Symbol sym = e.sym;
if (sym.isStatic() &&
staticImportAccessible(sym, packge) &&
sym.isMemberOf(origin, types)) {
found = true;
if (sym.kind != TYP) {
toScope.enter(sym, sym.owner.members(), origin.members(), true);
}
}
}
} }
public void run() { abstract void doImport(TypeSymbol tsym);
JavaFileObject prev = log.useSource(env.toplevel.sourcefile); }
try {
importFrom(tsym);
if (!found) {
log.error(pos, "cant.resolve.location",
KindName.STATIC,
name, List.<Type>nil(), List.<Type>nil(),
Kinds.typeKindName(tsym.type),
tsym.type);
}
} finally {
log.useSource(prev);
}
}
});
}
/** Import given class. /** Import given class.
* @param pos Position to be used for error reporting. * @param pos Position to be used for error reporting.
* @param tsym The class to be imported. * @param tsym The class to be imported.
* @param env The environment containing the named import * @param env The environment containing the named import
* scope to add to. * scope to add to.
*/ */
private void importNamed(DiagnosticPosition pos, Symbol tsym, Env<AttrContext> env) { private void importNamed(DiagnosticPosition pos, final Symbol tsym, Env<AttrContext> env) {
if (tsym.kind == TYP && if (tsym.kind == TYP &&
chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope)) chk.checkUniqueImport(pos, env.toplevel, tsym))
env.toplevel.namedImportScope.enter(tsym, tsym.owner.members()); env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
} }
/** Construct method type from method signature. /** Construct method type from method signature.
@ -482,6 +400,32 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
* Visitor methods for member enter * Visitor methods for member enter
*********************************************************************/ *********************************************************************/
ImportFilter staticImportFilter;
ImportFilter typeImportFilter = new ImportFilter() {
@Override
public boolean accepts(Scope origin, Symbol t) {
return t.kind == Kinds.TYP;
}
};
protected void memberEnter(JCCompilationUnit tree, Env<AttrContext> env) {
ImportFilter prevStaticImportFilter = staticImportFilter;
try {
final PackageSymbol packge = env.toplevel.packge;
this.staticImportFilter = new ImportFilter() {
@Override
public boolean accepts(Scope origin, Symbol sym) {
return sym.isStatic() &&
chk.staticImportAccessible(sym, packge) &&
sym.isMemberOf((TypeSymbol) origin.owner, types);
}
};
memberEnter((JCTree) tree, env);
} finally {
this.staticImportFilter = prevStaticImportFilter;
}
}
/** Visitor argument: the current environment /** Visitor argument: the current environment
*/ */
protected Env<AttrContext> env; protected Env<AttrContext> env;
@ -570,7 +514,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
} }
public void visitTopLevel(JCCompilationUnit tree) { public void visitTopLevel(JCCompilationUnit tree) {
if (tree.starImportScope.elems != null) { if (!tree.starImportScope.isEmpty()) {
// we must have already processed this toplevel // we must have already processed this toplevel
return; return;
} }
@ -640,7 +584,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
} }
public void visitMethodDef(JCMethodDecl tree) { public void visitMethodDef(JCMethodDecl tree) {
Scope enclScope = enter.enterScope(env); WriteableScope enclScope = enter.enterScope(env);
MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner); MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree); m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
tree.sym = m; tree.sym = m;
@ -696,9 +640,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
*/ */
Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) { Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
Env<AttrContext> localEnv = Env<AttrContext> localEnv =
env.dup(tree, env.info.dup(env.info.scope.dupUnshared())); env.dup(tree, env.info.dup(env.info.scope.dupUnshared(tree.sym)));
localEnv.enclMethod = tree; localEnv.enclMethod = tree;
localEnv.info.scope.owner = tree.sym;
if (tree.sym.type != null) { if (tree.sym.type != null) {
//when this is called in the enter stage, there's no type to be set //when this is called in the enter stage, there's no type to be set
localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType()); localEnv.info.returnResult = attr.new ResultInfo(VAL, tree.sym.type.getReturnType());
@ -739,7 +682,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
ArrayType atype = (ArrayType)tree.vartype.type; ArrayType atype = (ArrayType)tree.vartype.type;
tree.vartype.type = atype.makeVarargs(); tree.vartype.type = atype.makeVarargs();
} }
Scope enclScope = enter.enterScope(env); WriteableScope enclScope = enter.enterScope(env);
VarSymbol v = VarSymbol v =
new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner); new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree); v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
@ -875,8 +818,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) { Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup())); Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
if (tree.sym.owner.kind == TYP) { if (tree.sym.owner.kind == TYP) {
localEnv.info.scope = env.info.scope.dupUnshared(); localEnv.info.scope = env.info.scope.dupUnshared(tree.sym);
localEnv.info.scope.owner = tree.sym;
} }
if ((tree.mods.flags & STATIC) != 0 || if ((tree.mods.flags & STATIC) != 0 ||
((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null)) ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
@ -1220,23 +1162,30 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
// Enter all member fields and methods of a set of half completed // Enter all member fields and methods of a set of half completed
// classes in a second phase. // classes in a second phase.
if (wasFirst) { if (wasFirst) {
Set<JCCompilationUnit> topLevels = new HashSet<>();
try { try {
while (halfcompleted.nonEmpty()) { while (halfcompleted.nonEmpty()) {
Env<AttrContext> toFinish = halfcompleted.next(); Env<AttrContext> toFinish = halfcompleted.next();
topLevels.add(toFinish.toplevel);
finish(toFinish); finish(toFinish);
} }
} finally { } finally {
isFirst = true; isFirst = true;
} }
for (JCCompilationUnit toplevel : topLevels) {
chk.checkImportsResolvable(toplevel);
}
} }
} }
private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) { private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
Scope baseScope = new Scope(tree.sym); WriteableScope baseScope = WriteableScope.create(tree.sym);
//import already entered local classes into base scope //import already entered local classes into base scope
for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) { for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
if (e.sym.isLocal()) { if (sym.isLocal()) {
baseScope.enter(e.sym); baseScope.enter(sym);
} }
} }
//import current type-parameters into base scope //import current type-parameters into base scope

View File

@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.tools.javac.api.Formattable.LocalizedString; import com.sun.tools.javac.api.Formattable.LocalizedString;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr.ResultInfo; import com.sun.tools.javac.comp.Attr.ResultInfo;
@ -100,7 +101,7 @@ public class Resolve {
private final boolean compactMethodDiags; private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode; final EnumSet<VerboseResolutionMode> verboseResolutionMode;
Scope polymorphicSignatureScope; WriteableScope polymorphicSignatureScope;
protected Resolve(Context context) { protected Resolve(Context context) {
context.put(resolveKey, this); context.put(resolveKey, this);
@ -139,7 +140,7 @@ public class Resolve {
allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific(); allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
checkVarargsAccessAfterResolution = checkVarargsAccessAfterResolution =
source.allowPostApplicabilityVarargsAccessCheck(); source.allowPostApplicabilityVarargsAccessCheck();
polymorphicSignatureScope = new Scope(syms.noSymbol); polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags); inapplicableMethodException = new InapplicableMethodException(diags);
} }
@ -1299,13 +1300,11 @@ public class Resolve {
c = c.type.getUpperBound().tsym; c = c.type.getUpperBound().tsym;
Symbol bestSoFar = varNotFound; Symbol bestSoFar = varNotFound;
Symbol sym; Symbol sym;
Scope.Entry e = c.members().lookup(name); for (Symbol s : c.members().getSymbolsByName(name)) {
while (e.scope != null) { if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) { return isAccessible(env, site, s)
return isAccessible(env, site, e.sym) ? s : new AccessError(env, site, s);
? e.sym : new AccessError(env, site, e.sym);
} }
e = e.next();
} }
Type st = types.supertype(c.type); Type st = types.supertype(c.type);
if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) { if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
@ -1348,20 +1347,20 @@ public class Resolve {
*/ */
Symbol findVar(Env<AttrContext> env, Name name) { Symbol findVar(Env<AttrContext> env, Name name) {
Symbol bestSoFar = varNotFound; Symbol bestSoFar = varNotFound;
Symbol sym;
Env<AttrContext> env1 = env; Env<AttrContext> env1 = env;
boolean staticOnly = false; boolean staticOnly = false;
while (env1.outer != null) { while (env1.outer != null) {
Symbol sym = null;
if (isStatic(env1)) staticOnly = true; if (isStatic(env1)) staticOnly = true;
Scope.Entry e = env1.info.scope.lookup(name); for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
while (e.scope != null && if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
(e.sym.kind != VAR || sym = s;
(e.sym.flags_field & SYNTHETIC) != 0)) break;
e = e.next(); }
sym = (e.scope != null) }
? e.sym if (sym == null) {
: findField( sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
env1, env1.enclClass.sym.type, name, env1.enclClass.sym); }
if (sym.exists()) { if (sym.exists()) {
if (staticOnly && if (staticOnly &&
sym.kind == VAR && sym.kind == VAR &&
@ -1378,7 +1377,7 @@ public class Resolve {
env1 = env1.outer; env1 = env1.outer;
} }
sym = findField(env, syms.predefClass.type, name, syms.predefClass); Symbol sym = findField(env, syms.predefClass.type, name, syms.predefClass);
if (sym.exists()) if (sym.exists())
return sym; return sym;
if (bestSoFar.exists()) if (bestSoFar.exists())
@ -1386,18 +1385,16 @@ public class Resolve {
Symbol origin = null; Symbol origin = null;
for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) { for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
Scope.Entry e = sc.lookup(name); for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
for (; e.scope != null; e = e.next()) { if (currentSymbol.kind != VAR)
sym = e.sym;
if (sym.kind != VAR)
continue; continue;
// invariant: sym.kind == VAR // invariant: sym.kind == VAR
if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner) if (bestSoFar.kind < AMBIGUOUS && currentSymbol.owner != bestSoFar.owner)
return new AmbiguityError(bestSoFar, sym); return new AmbiguityError(bestSoFar, currentSymbol);
else if (bestSoFar.kind >= VAR) { else if (bestSoFar.kind >= VAR) {
origin = e.getOrigin().owner; origin = sc.getOrigin(currentSymbol).owner;
bestSoFar = isAccessible(env, origin.type, sym) bestSoFar = isAccessible(env, origin.type, currentSymbol)
? sym : new AccessError(env, origin.type, sym); ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
} }
} }
if (bestSoFar.exists()) break; if (bestSoFar.exists()) break;
@ -1627,7 +1624,7 @@ public class Resolve {
boolean useVarargs, boolean useVarargs,
boolean operator, boolean operator,
boolean abstractok) { boolean abstractok) {
for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) { for (Symbol s : sc.getSymbolsByName(name, new LookupFilter(abstractok))) {
bestSoFar = selectBest(env, site, argtypes, typeargtypes, s, bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
bestSoFar, allowBoxing, useVarargs, operator); bestSoFar, allowBoxing, useVarargs, operator);
} }
@ -1827,12 +1824,11 @@ public class Resolve {
List<Type> argtypes, List<Type> typeargtypes, List<Type> argtypes, List<Type> typeargtypes,
boolean allowBoxing, boolean useVarargs) { boolean allowBoxing, boolean useVarargs) {
Symbol bestSoFar = methodNotFound; Symbol bestSoFar = methodNotFound;
Symbol sym;
Env<AttrContext> env1 = env; Env<AttrContext> env1 = env;
boolean staticOnly = false; boolean staticOnly = false;
while (env1.outer != null) { while (env1.outer != null) {
if (isStatic(env1)) staticOnly = true; if (isStatic(env1)) staticOnly = true;
sym = findMethod( Symbol sym = findMethod(
env1, env1.enclClass.sym.type, name, argtypes, typeargtypes, env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
allowBoxing, useVarargs, false); allowBoxing, useVarargs, false);
if (sym.exists()) { if (sym.exists()) {
@ -1848,41 +1844,37 @@ public class Resolve {
env1 = env1.outer; env1 = env1.outer;
} }
sym = findMethod(env, syms.predefClass.type, name, argtypes, Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
typeargtypes, allowBoxing, useVarargs, false); typeargtypes, allowBoxing, useVarargs, false);
if (sym.exists()) if (sym.exists())
return sym; return sym;
Scope.Entry e = env.toplevel.namedImportScope.lookup(name); for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
for (; e.scope != null; e = e.next()) { Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
sym = e.sym; if (currentSym.kind == MTH) {
Type origin = e.getOrigin().owner.type; if (currentSym.owner.type != origin.type)
if (sym.kind == MTH) { currentSym = currentSym.clone(origin);
if (e.sym.owner.type != origin) if (!isAccessible(env, origin.type, currentSym))
sym = sym.clone(e.getOrigin().owner); currentSym = new AccessError(env, origin.type, currentSym);
if (!isAccessible(env, origin, sym)) bestSoFar = selectBest(env, origin.type,
sym = new AccessError(env, origin, sym);
bestSoFar = selectBest(env, origin,
argtypes, typeargtypes, argtypes, typeargtypes,
sym, bestSoFar, currentSym, bestSoFar,
allowBoxing, useVarargs, false); allowBoxing, useVarargs, false);
} }
} }
if (bestSoFar.exists()) if (bestSoFar.exists())
return bestSoFar; return bestSoFar;
e = env.toplevel.starImportScope.lookup(name); for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
for (; e.scope != null; e = e.next()) { Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
sym = e.sym; if (currentSym.kind == MTH) {
Type origin = e.getOrigin().owner.type; if (currentSym.owner.type != origin.type)
if (sym.kind == MTH) { currentSym = currentSym.clone(origin);
if (e.sym.owner.type != origin) if (!isAccessible(env, origin.type, currentSym))
sym = sym.clone(e.getOrigin().owner); currentSym = new AccessError(env, origin.type, currentSym);
if (!isAccessible(env, origin, sym)) bestSoFar = selectBest(env, origin.type,
sym = new AccessError(env, origin, sym);
bestSoFar = selectBest(env, origin,
argtypes, typeargtypes, argtypes, typeargtypes,
sym, bestSoFar, currentSym, bestSoFar,
allowBoxing, useVarargs, false); allowBoxing, useVarargs, false);
} }
} }
@ -1921,14 +1913,12 @@ public class Resolve {
Type site, Type site,
Name name, Name name,
TypeSymbol c) { TypeSymbol c) {
Scope.Entry e = c.members().lookup(name); for (Symbol sym : c.members().getSymbolsByName(name)) {
while (e.scope != null) { if (sym.kind == TYP) {
if (e.sym.kind == TYP) { return isAccessible(env, site, sym)
return isAccessible(env, site, e.sym) ? sym
? e.sym : new AccessError(env, site, sym);
: new AccessError(env, site, e.sym);
} }
e = e.next();
} }
return typeNotFound; return typeNotFound;
} }
@ -1995,8 +1985,8 @@ public class Resolve {
*/ */
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) { Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
Symbol bestSoFar = typeNotFound; Symbol bestSoFar = typeNotFound;
for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) { for (Symbol s : scope.getSymbolsByName(name)) {
Symbol sym = loadClass(env, e.sym.flatName()); Symbol sym = loadClass(env, s.flatName());
if (bestSoFar.kind == TYP && sym.kind == TYP && if (bestSoFar.kind == TYP && sym.kind == TYP &&
bestSoFar != sym) bestSoFar != sym)
return new AmbiguityError(bestSoFar, sym); return new AmbiguityError(bestSoFar, sym);
@ -2007,15 +1997,13 @@ public class Resolve {
} }
Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) { Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
for (Scope.Entry e = env.info.scope.lookup(name); for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
e.scope != null; if (sym.kind == TYP) {
e = e.next()) {
if (e.sym.kind == TYP) {
if (staticOnly && if (staticOnly &&
e.sym.type.hasTag(TYPEVAR) && sym.type.hasTag(TYPEVAR) &&
e.sym.owner.kind == TYP) sym.owner.kind == TYP)
return new StaticError(e.sym); return new StaticError(sym);
return e.sym; return sym;
} }
} }
return typeNotFound; return typeNotFound;
@ -2322,42 +2310,6 @@ public class Resolve {
kindName(sym), sym, sym.location()); kindName(sym), sym, sym.location());
} }
/* ***************************************************************************
* Debugging
****************************************************************************/
/** print all scopes starting with scope s and proceeding outwards.
* used for debugging.
*/
public void printscopes(Scope s) {
while (s != null) {
if (s.owner != null)
System.err.print(s.owner + ": ");
for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
if ((e.sym.flags() & ABSTRACT) != 0)
System.err.print("abstract ");
System.err.print(e.sym + " ");
}
System.err.println();
s = s.next;
}
}
void printscopes(Env<AttrContext> env) {
while (env.outer != null) {
System.err.println("------------------------------");
printscopes(env.info.scope);
env = env.outer;
}
}
public void printscopes(Type t) {
while (t.hasTag(CLASS)) {
printscopes(t.tsym.members());
t = types.supertype(t);
}
}
/* *************************************************************************** /* ***************************************************************************
* Name resolution * Name resolution
* Naming conventions are as for symbol lookup * Naming conventions are as for symbol lookup
@ -2456,7 +2408,7 @@ public class Resolve {
List<Type> argtypes) { List<Type> argtypes) {
Type mtype = infer.instantiatePolymorphicSignatureInstance(env, Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
(MethodSymbol)spMethod, currentResolutionContext, argtypes); (MethodSymbol)spMethod, currentResolutionContext, argtypes);
for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) { for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
if (types.isSameType(mtype, sym.type)) { if (types.isSameType(mtype, sym.type)) {
return sym; return sym;
} }
@ -2629,14 +2581,11 @@ public class Resolve {
boolean allowBoxing, boolean allowBoxing,
boolean useVarargs) { boolean useVarargs) {
Symbol bestSoFar = methodNotFound; Symbol bestSoFar = methodNotFound;
for (Scope.Entry e = site.tsym.members().lookup(names.init); for (final Symbol sym : site.tsym.members().getSymbolsByName(names.init)) {
e.scope != null;
e = e.next()) {
final Symbol sym = e.sym;
//- System.out.println(" e " + e.sym); //- System.out.println(" e " + e.sym);
if (sym.kind == MTH && if (sym.kind == MTH &&
(sym.flags_field & SYNTHETIC) == 0) { (sym.flags_field & SYNTHETIC) == 0) {
List<Type> oldParams = e.sym.type.hasTag(FORALL) ? List<Type> oldParams = sym.type.hasTag(FORALL) ?
((ForAll)sym.type).tvars : ((ForAll)sym.type).tvars :
List.<Type>nil(); List.<Type>nil();
Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams), Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
@ -3252,7 +3201,7 @@ public class Resolve {
@Override @Override
protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) { protected Symbol lookup(Env<AttrContext> env, MethodResolutionPhase phase) {
Scope sc = new Scope(syms.arrayClass); WriteableScope sc = WriteableScope.create(syms.arrayClass);
MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym); MethodSymbol arrayConstr = new MethodSymbol(PUBLIC, name, null, site.tsym);
arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass); arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
sc.enter(arrayConstr); sc.enter(arrayConstr);
@ -3362,7 +3311,7 @@ public class Resolve {
while (env1.outer != null) { while (env1.outer != null) {
if (isStatic(env1)) staticOnly = true; if (isStatic(env1)) staticOnly = true;
if (env1.enclClass.sym == c) { if (env1.enclClass.sym == c) {
Symbol sym = env1.info.scope.lookup(name).sym; Symbol sym = env1.info.scope.findFirst(name);
if (sym != null) { if (sym != null) {
if (staticOnly) sym = new StaticError(sym); if (staticOnly) sym = new StaticError(sym);
return accessBase(sym, pos, env.enclClass.sym.type, return accessBase(sym, pos, env.enclClass.sym.type,
@ -3449,7 +3398,7 @@ public class Resolve {
while (env1 != null && env1.outer != null) { while (env1 != null && env1.outer != null) {
if (isStatic(env1)) staticOnly = true; if (isStatic(env1)) staticOnly = true;
if (env1.enclClass.sym.isSubClass(member.owner, types)) { if (env1.enclClass.sym.isSubClass(member.owner, types)) {
Symbol sym = env1.info.scope.lookup(name).sym; Symbol sym = env1.info.scope.findFirst(name);
if (sym != null) { if (sym != null) {
if (staticOnly) sym = new StaticError(sym); if (staticOnly) sym = new StaticError(sym);
return sym; return sym;

View File

@ -37,6 +37,7 @@ import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR; import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
import static com.sun.tools.javac.code.TypeTag.VOID; import static com.sun.tools.javac.code.TypeTag.VOID;
@ -449,8 +450,8 @@ public class TransTypes extends TreeTranslator {
TypeSymbol i, TypeSymbol i,
ClassSymbol origin, ClassSymbol origin,
ListBuffer<JCTree> bridges) { ListBuffer<JCTree> bridges) {
for (Scope.Entry e = i.members().elems; e != null; e = e.sibling) for (Symbol sym : i.members().getSymbols(NON_RECURSIVE))
addBridgeIfNeeded(pos, e.sym, origin, bridges); addBridgeIfNeeded(pos, sym, origin, bridges);
for (List<Type> l = types.interfaces(i.type); l.nonEmpty(); l = l.tail) for (List<Type> l = types.interfaces(i.type); l.nonEmpty(); l = l.tail)
addBridges(pos, l.head.tsym, origin, bridges); addBridges(pos, l.head.tsym, origin, bridges);
} }
@ -529,14 +530,12 @@ public class TransTypes extends TreeTranslator {
} }
// Check that we do not introduce a name clash by erasing types. // Check that we do not introduce a name clash by erasing types.
for (Scope.Entry e = tree.sym.owner.members().lookup(tree.name); for (Symbol sym : tree.sym.owner.members().getSymbolsByName(tree.name)) {
e.sym != null; if (sym != tree.sym &&
e = e.next()) { types.isSameType(erasure(sym.type), tree.type)) {
if (e.sym != tree.sym &&
types.isSameType(erasure(e.sym.type), tree.type)) {
log.error(tree.pos(), log.error(tree.pos(),
"name.clash.same.erasure", tree.sym, "name.clash.same.erasure", tree.sym,
e.sym); sym);
return; return;
} }
} }

View File

@ -42,6 +42,7 @@ import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Lint.LintCategory;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.file.BaseFileObject; import com.sun.tools.javac.file.BaseFileObject;
@ -141,7 +142,7 @@ public class ClassReader {
/** The current scope where type variables are entered. /** The current scope where type variables are entered.
*/ */
protected Scope typevars; protected WriteableScope typevars;
/** The path name of the class file currently being read. /** The path name of the class file currently being read.
*/ */
@ -231,7 +232,7 @@ public class ClassReader {
profile = Profile.instance(context); profile = Profile.instance(context);
typevars = new Scope(syms.noSymbol); typevars = WriteableScope.create(syms.noSymbol);
lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE); lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
@ -832,9 +833,9 @@ public class ClassReader {
/** Find type variable with given name in `typevars' scope. /** Find type variable with given name in `typevars' scope.
*/ */
Type findTypeVar(Name name) { Type findTypeVar(Name name) {
Scope.Entry e = typevars.lookup(name); Symbol s = typevars.findFirst(name);
if (e.scope != null) { if (s != null) {
return e.sym.type; return s.type;
} else { } else {
if (readingClassAttr) { if (readingClassAttr) {
// While reading the class attribute, the supertypes // While reading the class attribute, the supertypes
@ -1228,9 +1229,10 @@ public class ClassReader {
MethodType type = nt.uniqueType.type.asMethodType(); MethodType type = nt.uniqueType.type.asMethodType();
for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next()) for (Symbol sym : scope.getSymbolsByName(nt.name)) {
if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type)) if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
return (MethodSymbol)e.sym; return (MethodSymbol)sym;
}
if (nt.name != names.init) if (nt.name != names.init)
// not a constructor // not a constructor
@ -1769,10 +1771,7 @@ public class ClassReader {
MethodSymbol findAccessMethod(Type container, Name name) { MethodSymbol findAccessMethod(Type container, Name name) {
CompletionFailure failure = null; CompletionFailure failure = null;
try { try {
for (Scope.Entry e = container.tsym.members().lookup(name); for (Symbol sym : container.tsym.members().getSymbolsByName(name)) {
e.scope != null;
e = e.next()) {
Symbol sym = e.sym;
if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0) if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0)
return (MethodSymbol) sym; return (MethodSymbol) sym;
} }
@ -1852,11 +1851,9 @@ public class ClassReader {
VarSymbol enumerator = null; VarSymbol enumerator = null;
CompletionFailure failure = null; CompletionFailure failure = null;
try { try {
for (Scope.Entry e = enumTypeSym.members().lookup(proxy.enumerator); for (Symbol sym : enumTypeSym.members().getSymbolsByName(proxy.enumerator)) {
e.scope != null; if (sym.kind == VAR) {
e = e.next()) { enumerator = (VarSymbol)sym;
if (e.sym.kind == VAR) {
enumerator = (VarSymbol)e.sym;
break; break;
} }
} }
@ -2197,7 +2194,7 @@ public class ClassReader {
ClassType ct = (ClassType)c.type; ClassType ct = (ClassType)c.type;
// allocate scope for members // allocate scope for members
c.members_field = new Scope(c); c.members_field = WriteableScope.create(c);
// prepare type variable table // prepare type variable table
typevars = typevars.dup(currentOwner); typevars = typevars.dup(currentOwner);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -49,6 +49,7 @@ import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.UninitializedType.*; import static com.sun.tools.javac.jvm.UninitializedType.*;
import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.main.Option.*;
@ -1563,12 +1564,12 @@ public class ClassWriter extends ClassFile {
} }
} }
void writeFields(Scope.Entry e) { void writeFields(Scope s) {
// process them in reverse sibling order; // process them in reverse sibling order;
// i.e., process them in declaration order. // i.e., process them in declaration order.
List<VarSymbol> vars = List.nil(); List<VarSymbol> vars = List.nil();
for (Scope.Entry i = e; i != null; i = i.sibling) { for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
if (i.sym.kind == VAR) vars = vars.prepend((VarSymbol)i.sym); if (sym.kind == VAR) vars = vars.prepend((VarSymbol)sym);
} }
while (vars.nonEmpty()) { while (vars.nonEmpty()) {
writeField(vars.head); writeField(vars.head);
@ -1576,11 +1577,11 @@ public class ClassWriter extends ClassFile {
} }
} }
void writeMethods(Scope.Entry e) { void writeMethods(Scope s) {
List<MethodSymbol> methods = List.nil(); List<MethodSymbol> methods = List.nil();
for (Scope.Entry i = e; i != null; i = i.sibling) { for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
if (i.sym.kind == MTH && (i.sym.flags() & HYPOTHETICAL) == 0) if (sym.kind == MTH && (sym.flags() & HYPOTHETICAL) == 0)
methods = methods.prepend((MethodSymbol)i.sym); methods = methods.prepend((MethodSymbol)sym);
} }
while (methods.nonEmpty()) { while (methods.nonEmpty()) {
writeMethod(methods.head); writeMethod(methods.head);
@ -1654,12 +1655,12 @@ public class ClassWriter extends ClassFile {
databuf.appendChar(pool.put(l.head.tsym)); databuf.appendChar(pool.put(l.head.tsym));
int fieldsCount = 0; int fieldsCount = 0;
int methodsCount = 0; int methodsCount = 0;
for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) { for (Symbol sym : c.members().getSymbols(NON_RECURSIVE)) {
switch (e.sym.kind) { switch (sym.kind) {
case VAR: fieldsCount++; break; case VAR: fieldsCount++; break;
case MTH: if ((e.sym.flags() & HYPOTHETICAL) == 0) methodsCount++; case MTH: if ((sym.flags() & HYPOTHETICAL) == 0) methodsCount++;
break; break;
case TYP: enterInner((ClassSymbol)e.sym); break; case TYP: enterInner((ClassSymbol)sym); break;
default : Assert.error(); default : Assert.error();
} }
} }
@ -1671,9 +1672,9 @@ public class ClassWriter extends ClassFile {
} }
databuf.appendChar(fieldsCount); databuf.appendChar(fieldsCount);
writeFields(c.members().elems); writeFields(c.members());
databuf.appendChar(methodsCount); databuf.appendChar(methodsCount);
writeMethods(c.members().elems); writeMethods(c.members());
int acountIdx = beginAttrs(); int acountIdx = beginAttrs();
int acount = 0; int acount = 0;

View File

@ -45,6 +45,7 @@ import com.sun.tools.javac.tree.JCTree.*;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.*; import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.jvm.ByteCodes.*; import static com.sun.tools.javac.jvm.ByteCodes.*;
import static com.sun.tools.javac.jvm.CRTFlags.*; import static com.sun.tools.javac.jvm.CRTFlags.*;
@ -302,7 +303,7 @@ public class Gen extends JCTree.Visitor {
if (!target.interfaceObjectOverridesBinaryCompatibility()) { if (!target.interfaceObjectOverridesBinaryCompatibility()) {
if ((sym.owner.flags() & INTERFACE) != 0 && if ((sym.owner.flags() & INTERFACE) != 0 &&
syms.objectType.tsym.members().lookup(sym.name).scope != null) syms.objectType.tsym.members().findFirst(sym.name) != null)
return sym; return sym;
} }
@ -651,13 +652,10 @@ public class Gen extends JCTree.Visitor {
void implementInterfaceMethods(ClassSymbol c, ClassSymbol site) { void implementInterfaceMethods(ClassSymbol c, ClassSymbol site) {
for (List<Type> l = types.interfaces(c.type); l.nonEmpty(); l = l.tail) { for (List<Type> l = types.interfaces(c.type); l.nonEmpty(); l = l.tail) {
ClassSymbol i = (ClassSymbol)l.head.tsym; ClassSymbol i = (ClassSymbol)l.head.tsym;
for (Scope.Entry e = i.members().elems; for (Symbol sym : i.members().getSymbols(NON_RECURSIVE)) {
e != null; if (sym.kind == MTH && (sym.flags() & STATIC) == 0)
e = e.sibling)
{
if (e.sym.kind == MTH && (e.sym.flags() & STATIC) == 0)
{ {
MethodSymbol absMeth = (MethodSymbol)e.sym; MethodSymbol absMeth = (MethodSymbol)sym;
MethodSymbol implMeth = absMeth.binaryImplementation(site, types); MethodSymbol implMeth = absMeth.binaryImplementation(site, types);
if (implMeth == null) if (implMeth == null)
addAbstractMethod(site, absMeth); addAbstractMethod(site, absMeth);

View File

@ -37,7 +37,6 @@ import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
@ -53,6 +52,7 @@ import com.sun.tools.javac.util.Pair;
import static com.sun.tools.javac.main.Option.*; import static com.sun.tools.javac.main.Option.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** This class provides operations to write native header files for classes. /** This class provides operations to write native header files for classes.
* *
@ -146,8 +146,7 @@ public class JNIWriter {
if (c.isLocal() || isSynthetic(c)) if (c.isLocal() || isSynthetic(c))
return false; return false;
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) { for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
Symbol sym = i.sym;
if (sym.kind == MTH && isNative(sym)) if (sym.kind == MTH && isNative(sym))
return true; return true;
for (Attribute.Compound a: sym.getDeclarationAttributes()) { for (Attribute.Compound a: sym.getDeclarationAttributes()) {
@ -156,8 +155,7 @@ public class JNIWriter {
} }
} }
if (checkNestedClasses) { if (checkNestedClasses) {
for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) { for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
Symbol sym = i.sym;
if ((sym.kind == TYP) && needsHeader(((ClassSymbol) sym), true)) if ((sym.kind == TYP) && needsHeader(((ClassSymbol) sym), true))
return true; return true;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -43,6 +43,7 @@ import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.ArrayType; import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** /**
* A generator of dynamic proxy implementations of * A generator of dynamic proxy implementations of
@ -119,9 +120,9 @@ public class AnnotationProxyMaker {
// First find the default values. // First find the default values.
ClassSymbol sym = (ClassSymbol) anno.type.tsym; ClassSymbol sym = (ClassSymbol) anno.type.tsym;
for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) { for (Symbol s : sym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym.kind == Kinds.MTH) { if (s.kind == Kinds.MTH) {
MethodSymbol m = (MethodSymbol) e.sym; MethodSymbol m = (MethodSymbol) s;
Attribute def = m.getDefaultValue(); Attribute def = m.getDefaultValue();
if (def != null) if (def != null)
res.put(m, def); res.put(m, def);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,11 +27,12 @@ package com.sun.tools.javac.model;
import java.util.AbstractList; import java.util.AbstractList;
import java.util.Iterator; import java.util.Iterator;
import java.util.NoSuchElementException;
import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.util.Filter;
import static com.sun.tools.javac.code.Flags.*; import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** /**
* Utility to construct a view of a symbol's members, * Utility to construct a view of a symbol's members,
@ -53,56 +54,28 @@ public class FilteredMemberList extends AbstractList<Symbol> {
public int size() { public int size() {
int cnt = 0; int cnt = 0;
for (Scope.Entry e = scope.elems; e != null; e = e.sibling) { for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
if (!unwanted(e.sym)) if (!unwanted(sym))
cnt++; cnt++;
} }
return cnt; return cnt;
} }
public Symbol get(int index) { public Symbol get(int index) {
for (Scope.Entry e = scope.elems; e != null; e = e.sibling) { for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
if (!unwanted(e.sym) && (index-- == 0)) if (!unwanted(sym) && (index-- == 0))
return e.sym; return sym;
} }
throw new IndexOutOfBoundsException(); throw new IndexOutOfBoundsException();
} }
// A more efficient implementation than AbstractList's. // A more efficient implementation than AbstractList's.
public Iterator<Symbol> iterator() { public Iterator<Symbol> iterator() {
return new Iterator<Symbol>() { return scope.getSymbols(new Filter<Symbol>() {
public boolean accepts(Symbol t) {
/** The next entry to examine, or null if none. */ return !unwanted(t);
private Scope.Entry nextEntry = scope.elems;
private boolean hasNextForSure = false;
public boolean hasNext() {
if (hasNextForSure) {
return true;
}
while (nextEntry != null && unwanted(nextEntry.sym)) {
nextEntry = nextEntry.sibling;
}
hasNextForSure = (nextEntry != null);
return hasNextForSure;
} }
}, NON_RECURSIVE).iterator();
public Symbol next() {
if (hasNext()) {
Symbol result = nextEntry.sym;
nextEntry = nextEntry.sibling;
hasNextForSure = false;
return result;
} else {
throw new NoSuchElementException();
}
}
public void remove() {
throw new UnsupportedOperationException();
}
};
} }
/** /**

View File

@ -35,6 +35,7 @@ import javax.tools.JavaFileObject;
import static javax.lang.model.util.ElementFilter.methodsIn; import static javax.lang.model.util.ElementFilter.methodsIn;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Enter; import com.sun.tools.javac.comp.Enter;
@ -47,6 +48,7 @@ import com.sun.tools.javac.tree.TreeInfo;
import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
@ -356,35 +358,31 @@ public class JavacElements implements Elements {
*/ */
public FilteredMemberList getAllMembers(TypeElement element) { public FilteredMemberList getAllMembers(TypeElement element) {
Symbol sym = cast(Symbol.class, element); Symbol sym = cast(Symbol.class, element);
Scope scope = sym.members().dupUnshared(); WriteableScope scope = sym.members().dupUnshared();
List<Type> closure = types.closure(sym.asType()); List<Type> closure = types.closure(sym.asType());
for (Type t : closure) for (Type t : closure)
addMembers(scope, t); addMembers(scope, t);
return new FilteredMemberList(scope); return new FilteredMemberList(scope);
} }
// where // where
private void addMembers(Scope scope, Type type) { private void addMembers(WriteableScope scope, Type type) {
members: members:
for (Scope.Entry e = type.asElement().members().elems; e != null; e = e.sibling) { for (Symbol e : type.asElement().members().getSymbols(NON_RECURSIVE)) {
Scope.Entry overrider = scope.lookup(e.sym.getSimpleName()); for (Symbol overrider : scope.getSymbolsByName(e.getSimpleName())) {
while (overrider.scope != null) { if (overrider.kind == e.kind && (overrider.flags() & Flags.SYNTHETIC) == 0) {
if (overrider.sym.kind == e.sym.kind if (overrider.getKind() == ElementKind.METHOD &&
&& (overrider.sym.flags() & Flags.SYNTHETIC) == 0) overrides((ExecutableElement)overrider, (ExecutableElement)e, (TypeElement)type.asElement())) {
{
if (overrider.sym.getKind() == ElementKind.METHOD
&& overrides((ExecutableElement)overrider.sym, (ExecutableElement)e.sym, (TypeElement)type.asElement())) {
continue members; continue members;
} }
} }
overrider = overrider.next();
} }
boolean derived = e.sym.getEnclosingElement() != scope.owner; boolean derived = e.getEnclosingElement() != scope.owner;
ElementKind kind = e.sym.getKind(); ElementKind kind = e.getKind();
boolean initializer = kind == ElementKind.CONSTRUCTOR boolean initializer = kind == ElementKind.CONSTRUCTOR
|| kind == ElementKind.INSTANCE_INIT || kind == ElementKind.INSTANCE_INIT
|| kind == ElementKind.STATIC_INIT; || kind == ElementKind.STATIC_INIT;
if (!derived || (!initializer && e.sym.isInheritedIn(scope.owner, types))) if (!derived || (!initializer && e.isInheritedIn(scope.owner, types)))
scope.enter(e.sym); scope.enter(e);
} }
} }

View File

@ -310,9 +310,9 @@ public class JavacTypes implements javax.lang.model.util.Types {
for (Type t : types.closure(origin.type)) { for (Type t : types.closure(origin.type)) {
if (t != origin.type) { if (t != origin.type) {
ClassSymbol c = (ClassSymbol) t.tsym; ClassSymbol c = (ClassSymbol) t.tsym;
for (Scope.Entry e = c.members().lookup(m.name); e.scope != null; e = e.next()) { for (Symbol sym : c.members().getSymbolsByName(m.name)) {
if (e.sym.kind == Kinds.MTH && m.overrides(e.sym, origin, types, true)) { if (sym.kind == Kinds.MTH && m.overrides(sym, origin, types, true)) {
results.add((MethodSymbol) e.sym); results.add((MethodSymbol) sym);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,7 +27,7 @@ package com.sun.tools.javac.sym;
import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute;
@ -189,7 +189,7 @@ public class CreateSymbols extends AbstractProcessor {
new Attribute.Compound(syms.proprietaryType, new Attribute.Compound(syms.proprietaryType,
List.<Pair<Symbol.MethodSymbol,Attribute>>nil()); List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1]; Attribute.Compound[] profileAnnos = new Attribute.Compound[profiles.getProfileCount() + 1];
Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().lookup(names.value).sym; Symbol.MethodSymbol profileValue = (MethodSymbol) syms.profileType.tsym.members().findFirst(names.value);
for (int i = 1; i < profileAnnos.length; i++) { for (int i = 1; i < profileAnnos.length; i++) {
profileAnnos[i] = new Attribute.Compound(syms.profileType, profileAnnos[i] = new Attribute.Compound(syms.profileType,
List.<Pair<Symbol.MethodSymbol, Attribute>>of( List.<Pair<Symbol.MethodSymbol, Attribute>>of(
@ -259,9 +259,9 @@ public class CreateSymbols extends AbstractProcessor {
pool.reset(); pool.reset();
cs.pool = pool; cs.pool = pool;
writer.writeClass(cs); writer.writeClass(cs);
for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) { for (Symbol sym : cs.members().getSymbols(NON_RECURSIVE)) {
if (e.sym.kind == Kinds.TYP) { if (sym.kind == Kinds.TYP) {
ClassSymbol nestedClass = (ClassSymbol)e.sym; ClassSymbol nestedClass = (ClassSymbol)sym;
nestedClass.complete(); nestedClass.complete();
writeClass(pool, nestedClass, writer); writeClass(pool, nestedClass, writer);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -488,8 +488,10 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public JavaFileObject sourcefile; public JavaFileObject sourcefile;
/** The package to which this compilation unit belongs. */ /** The package to which this compilation unit belongs. */
public PackageSymbol packge; public PackageSymbol packge;
/** A scope containing top level classes. */
public WriteableScope toplevelScope;
/** A scope for all named imports. */ /** A scope for all named imports. */
public ImportScope namedImportScope; public NamedImportScope namedImportScope;
/** A scope for all import-on-demands. */ /** A scope for all import-on-demands. */
public StarImportScope starImportScope; public StarImportScope starImportScope;
/** Line starting positions, defined only if option -g is set. */ /** Line starting positions, defined only if option -g is set. */

View File

@ -25,6 +25,8 @@
package com.sun.tools.javac.tree; package com.sun.tools.javac.tree;
import java.util.Iterator;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*; import com.sun.tools.javac.code.Type.*;
@ -978,24 +980,26 @@ public class TreeMaker implements JCTree.Factory {
sym.owner.kind == MTH || sym.owner.kind == VAR) { sym.owner.kind == MTH || sym.owner.kind == VAR) {
return true; return true;
} else if (sym.kind == TYP && toplevel != null) { } else if (sym.kind == TYP && toplevel != null) {
Scope.Entry e; Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator();
e = toplevel.namedImportScope.lookup(sym.name); if (it.hasNext()) {
if (e.scope != null) { Symbol s = it.next();
return return
e.sym == sym && s == sym &&
e.next().scope == null; !it.hasNext();
} }
e = toplevel.packge.members().lookup(sym.name); it = toplevel.packge.members().getSymbolsByName(sym.name).iterator();
if (e.scope != null) { if (it.hasNext()) {
Symbol s = it.next();
return return
e.sym == sym && s == sym &&
e.next().scope == null; !it.hasNext();
} }
e = toplevel.starImportScope.lookup(sym.name); it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator();
if (e.scope != null) { if (it.hasNext()) {
Symbol s = it.next();
return return
e.sym == sym && s == sym &&
e.next().scope == null; !it.hasNext();
} }
} }
return false; return false;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,10 +29,12 @@ import com.sun.javadoc.*;
import com.sun.source.util.TreePath; import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** /**
* Represents an annotation type. * Represents an annotation type.
* *
@ -91,9 +93,9 @@ public class AnnotationTypeDocImpl
*/ */
public AnnotationTypeElementDoc[] elements() { public AnnotationTypeElementDoc[] elements() {
List<AnnotationTypeElementDoc> elements = List.nil(); List<AnnotationTypeElementDoc> elements = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && e.sym.kind == Kinds.MTH) { if (sym != null && sym.kind == Kinds.MTH) {
MethodSymbol s = (MethodSymbol)e.sym; MethodSymbol s = (MethodSymbol)sym;
elements = elements.prepend(env.getAnnotationTypeElementDoc(s)); elements = elements.prepend(env.getAnnotationTypeElementDoc(s));
} }
} }

View File

@ -59,6 +59,7 @@ import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Position; import com.sun.tools.javac.util.Position;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.TypeTag.CLASS; import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.tree.JCTree.Tag.*; import static com.sun.tools.javac.tree.JCTree.Tag.*;
@ -589,9 +590,9 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
*/ */
private FieldDoc[] fields(boolean filter, boolean enumConstants) { private FieldDoc[] fields(boolean filter, boolean enumConstants) {
List<FieldDocImpl> fields = List.nil(); List<FieldDocImpl> fields = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && e.sym.kind == VAR) { if (sym != null && sym.kind == VAR) {
VarSymbol s = (VarSymbol)e.sym; VarSymbol s = (VarSymbol)sym;
boolean isEnum = ((s.flags() & Flags.ENUM) != 0) && boolean isEnum = ((s.flags() & Flags.ENUM) != 0) &&
!env.legacyDoclet; !env.legacyDoclet;
if (isEnum == enumConstants && if (isEnum == enumConstants &&
@ -614,12 +615,12 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
public MethodDoc[] methods(boolean filter) { public MethodDoc[] methods(boolean filter) {
Names names = tsym.name.table.names; Names names = tsym.name.table.names;
List<MethodDocImpl> methods = List.nil(); List<MethodDocImpl> methods = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol sym :tsym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null if (sym != null
&& e.sym.kind == Kinds.MTH && sym.kind == Kinds.MTH
&& e.sym.name != names.init && sym.name != names.init
&& e.sym.name != names.clinit) { && sym.name != names.clinit) {
MethodSymbol s = (MethodSymbol)e.sym; MethodSymbol s = (MethodSymbol)sym;
if (!filter || env.shouldDocument(s)) { if (!filter || env.shouldDocument(s)) {
methods = methods.prepend(env.getMethodDoc(s)); methods = methods.prepend(env.getMethodDoc(s));
} }
@ -649,10 +650,10 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
public ConstructorDoc[] constructors(boolean filter) { public ConstructorDoc[] constructors(boolean filter) {
Names names = tsym.name.table.names; Names names = tsym.name.table.names;
List<ConstructorDocImpl> constructors = List.nil(); List<ConstructorDocImpl> constructors = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && if (sym != null &&
e.sym.kind == Kinds.MTH && e.sym.name == names.init) { sym.kind == Kinds.MTH && sym.name == names.init) {
MethodSymbol s = (MethodSymbol)e.sym; MethodSymbol s = (MethodSymbol)sym;
if (!filter || env.shouldDocument(s)) { if (!filter || env.shouldDocument(s)) {
constructors = constructors.prepend(env.getConstructorDoc(s)); constructors = constructors.prepend(env.getConstructorDoc(s));
} }
@ -685,10 +686,9 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
if (l.contains(this)) return; if (l.contains(this)) return;
l.append(this); l.append(this);
List<ClassDocImpl> more = List.nil(); List<ClassDocImpl> more = List.nil();
for (Scope.Entry e = tsym.members().elems; e != null; for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
e = e.sibling) { if (sym != null && sym.kind == Kinds.TYP) {
if (e.sym != null && e.sym.kind == Kinds.TYP) { ClassSymbol s = (ClassSymbol)sym;
ClassSymbol s = (ClassSymbol)e.sym;
ClassDocImpl c = env.getClassDoc(s); ClassDocImpl c = env.getClassDoc(s);
if (c.isSynthetic()) continue; if (c.isSynthetic()) continue;
if (c != null) more = more.prepend(c); if (c != null) more = more.prepend(c);
@ -713,9 +713,9 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
*/ */
public ClassDoc[] innerClasses(boolean filter) { public ClassDoc[] innerClasses(boolean filter) {
ListBuffer<ClassDocImpl> innerClasses = new ListBuffer<>(); ListBuffer<ClassDocImpl> innerClasses = new ListBuffer<>();
for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) { for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && e.sym.kind == Kinds.TYP) { if (sym != null && sym.kind == Kinds.TYP) {
ClassSymbol s = (ClassSymbol)e.sym; ClassSymbol s = (ClassSymbol)sym;
if ((s.flags_field & Flags.SYNTHETIC) != 0) continue; if ((s.flags_field & Flags.SYNTHETIC) != 0) continue;
if (!filter || env.isVisible(s)) { if (!filter || env.isVisible(s)) {
innerClasses.prepend(env.getClassDoc(s)); innerClasses.prepend(env.getClassDoc(s));
@ -809,17 +809,17 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
if (compenv == null) return null; if (compenv == null) return null;
Scope s = compenv.toplevel.namedImportScope; Scope s = compenv.toplevel.namedImportScope;
for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) { for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
if (e.sym.kind == Kinds.TYP) { if (sym.kind == Kinds.TYP) {
ClassDoc c = env.getClassDoc((ClassSymbol)e.sym); ClassDoc c = env.getClassDoc((ClassSymbol)sym);
return c; return c;
} }
} }
s = compenv.toplevel.starImportScope; s = compenv.toplevel.starImportScope;
for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) { for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
if (e.sym.kind == Kinds.TYP) { if (sym.kind == Kinds.TYP) {
ClassDoc c = env.getClassDoc((ClassSymbol)e.sym); ClassDoc c = env.getClassDoc((ClassSymbol)sym);
return c; return c;
} }
} }
@ -918,7 +918,6 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
*---------------------------------*/ *---------------------------------*/
// search current class // search current class
Scope.Entry e = tsym.members().lookup(names.fromString(methodName));
//### Using modifier filter here isn't really correct, //### Using modifier filter here isn't really correct,
//### but emulates the old behavior. Instead, we should //### but emulates the old behavior. Instead, we should
@ -931,11 +930,11 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
// In order to provide textually identical results, we // In order to provide textually identical results, we
// attempt to emulate the old behavior. // attempt to emulate the old behavior.
MethodSymbol lastFound = null; MethodSymbol lastFound = null;
for (; e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
if (e.sym.kind == Kinds.MTH) { if (sym.kind == Kinds.MTH) {
//### Should intern methodName as Name. //### Should intern methodName as Name.
if (e.sym.name.toString().equals(methodName)) { if (sym.name.toString().equals(methodName)) {
lastFound = (MethodSymbol)e.sym; lastFound = (MethodSymbol)sym;
} }
} }
} }
@ -943,12 +942,12 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
return env.getMethodDoc(lastFound); return env.getMethodDoc(lastFound);
} }
} else { } else {
for (; e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
if (e.sym != null && if (sym != null &&
e.sym.kind == Kinds.MTH) { sym.kind == Kinds.MTH) {
//### Should intern methodName as Name. //### Should intern methodName as Name.
if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) { if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
return env.getMethodDoc((MethodSymbol)e.sym); return env.getMethodDoc((MethodSymbol)sym);
} }
} }
} }
@ -1005,10 +1004,10 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
public ConstructorDoc findConstructor(String constrName, public ConstructorDoc findConstructor(String constrName,
String[] paramTypes) { String[] paramTypes) {
Names names = tsym.name.table.names; Names names = tsym.name.table.names;
for (Scope.Entry e = tsym.members().lookup(names.fromString("<init>")); e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(names.fromString("<init>"))) {
if (e.sym.kind == Kinds.MTH) { if (sym.kind == Kinds.MTH) {
if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) { if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
return env.getConstructorDoc((MethodSymbol)e.sym); return env.getConstructorDoc((MethodSymbol)sym);
} }
} }
} }
@ -1047,10 +1046,10 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
} }
searched.add(this); searched.add(this);
for (Scope.Entry e = tsym.members().lookup(names.fromString(fieldName)); e.scope != null; e = e.next()) { for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(fieldName))) {
if (e.sym.kind == Kinds.VAR) { if (sym.kind == Kinds.VAR) {
//### Should intern fieldName as Name. //### Should intern fieldName as Name.
return env.getFieldDoc((VarSymbol)e.sym); return env.getFieldDoc((VarSymbol)sym);
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -128,8 +128,8 @@ public class MethodDocImpl
t.hasTag(CLASS); t.hasTag(CLASS);
t = env.types.supertype(t)) { t = env.types.supertype(t)) {
ClassSymbol c = (ClassSymbol)t.tsym; ClassSymbol c = (ClassSymbol)t.tsym;
for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) { for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
if (sym.overrides(e.sym, origin, env.types, true)) { if (sym.overrides(sym2, origin, env.types, true)) {
return TypeMaker.getType(env, t); return TypeMaker.getType(env, t);
} }
} }
@ -160,9 +160,9 @@ public class MethodDocImpl
t.hasTag(CLASS); t.hasTag(CLASS);
t = env.types.supertype(t)) { t = env.types.supertype(t)) {
ClassSymbol c = (ClassSymbol)t.tsym; ClassSymbol c = (ClassSymbol)t.tsym;
for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) { for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
if (sym.overrides(e.sym, origin, env.types, true)) { if (sym.overrides(sym2, origin, env.types, true)) {
return env.getMethodDoc((MethodSymbol)e.sym); return env.getMethodDoc((MethodSymbol)sym2);
} }
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -33,7 +33,7 @@ import javax.tools.FileObject;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.source.util.TreePath; import com.sun.source.util.TreePath;
import com.sun.tools.javac.code.Attribute; import com.sun.tools.javac.code.Attribute;
import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.PackageSymbol; import com.sun.tools.javac.code.Symbol.PackageSymbol;
import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree;
@ -43,6 +43,8 @@ import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Position; import com.sun.tools.javac.util.Position;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** /**
* Represents a java package. Provides access to information * Represents a java package. Provides access to information
* about the package, the package's comment and tags, and the * about the package, the package's comment and tags, and the
@ -146,9 +148,9 @@ public class PackageDocImpl extends DocImpl implements PackageDoc {
return allClassesFiltered; return allClassesFiltered;
} }
ListBuffer<ClassDocImpl> classes = new ListBuffer<>(); ListBuffer<ClassDocImpl> classes = new ListBuffer<>();
for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) { for (Symbol enumerated : sym.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null) { if (enumerated != null) {
ClassSymbol s = (ClassSymbol)e.sym; ClassSymbol s = (ClassSymbol)enumerated;
ClassDocImpl c = env.getClassDoc(s); ClassDocImpl c = env.getClassDoc(s);
if (c != null && !c.isSynthetic()) if (c != null && !c.isSynthetic())
c.addAllClasses(classes, filtered); c.addAllClasses(classes, filtered);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -26,15 +26,13 @@
package com.sun.tools.javadoc; package com.sun.tools.javadoc;
import com.sun.javadoc.*; import com.sun.javadoc.*;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope;
import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.Names; import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/** /**
* The serialized form is the specification of a class' serialization * The serialized form is the specification of a class' serialization
@ -159,9 +157,9 @@ class SerializedForm {
/* SERIALIZABLE_FIELDS can be private, /* SERIALIZABLE_FIELDS can be private,
* so must lookup by ClassSymbol, not by ClassDocImpl. * so must lookup by ClassSymbol, not by ClassDocImpl.
*/ */
for (Scope.Entry e = def.members().lookup(names.fromString(SERIALIZABLE_FIELDS)); e.scope != null; e = e.next()) { for (Symbol sym : def.members().getSymbolsByName(names.fromString(SERIALIZABLE_FIELDS))) {
if (e.sym.kind == Kinds.VAR) { if (sym.kind == Kinds.VAR) {
VarSymbol f = (VarSymbol)e.sym; VarSymbol f = (VarSymbol)sym;
if ((f.flags() & Flags.STATIC) != 0 && if ((f.flags() & Flags.STATIC) != 0 &&
(f.flags() & Flags.PRIVATE) != 0) { (f.flags() & Flags.PRIVATE) != 0) {
return f; return f;
@ -180,9 +178,9 @@ class SerializedForm {
private void computeDefaultSerializableFields(DocEnv env, private void computeDefaultSerializableFields(DocEnv env,
ClassSymbol def, ClassSymbol def,
ClassDocImpl cd) { ClassDocImpl cd) {
for (Scope.Entry e = def.members().elems; e != null; e = e.sibling) { for (Symbol sym : def.members().getSymbols(NON_RECURSIVE)) {
if (e.sym != null && e.sym.kind == Kinds.VAR) { if (sym != null && sym.kind == Kinds.VAR) {
VarSymbol f = (VarSymbol)e.sym; VarSymbol f = (VarSymbol)sym;
if ((f.flags() & Flags.STATIC) == 0 && if ((f.flags() & Flags.STATIC) == 0 &&
(f.flags() & Flags.TRANSIENT) == 0) { (f.flags() & Flags.TRANSIENT) == 0) {
//### No modifier filtering applied here. //### No modifier filtering applied here.
@ -209,9 +207,9 @@ class SerializedForm {
private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) { private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) {
Names names = def.name.table.names; Names names = def.name.table.names;
for (Scope.Entry e = def.members().lookup(names.fromString(methodName)); e.scope != null; e = e.next()) { for (Symbol sym : def.members().getSymbolsByName(names.fromString(methodName))) {
if (e.sym.kind == Kinds.MTH) { if (sym.kind == Kinds.MTH) {
MethodSymbol md = (MethodSymbol)e.sym; MethodSymbol md = (MethodSymbol)sym;
if ((md.flags() & Flags.STATIC) == 0) { if ((md.flags() & Flags.STATIC) == 0) {
/* /*
* WARNING: not robust if unqualifiedMethodName is overloaded * WARNING: not robust if unqualifiedMethodName is overloaded
@ -241,10 +239,9 @@ class SerializedForm {
Name fieldName = names.fromString(tag.fieldName()); Name fieldName = names.fromString(tag.fieldName());
// Look for a FieldDocImpl that is documented by serialFieldTagImpl. // Look for a FieldDocImpl that is documented by serialFieldTagImpl.
for (Scope.Entry e = def.members().lookup(fieldName); for (Symbol sym : def.members().getSymbolsByName(fieldName)) {
e.scope != null; e = e.next()) { if (sym.kind == Kinds.VAR) {
if (e.sym.kind == Kinds.VAR) { VarSymbol f = (VarSymbol) sym;
VarSymbol f = (VarSymbol) e.sym;
FieldDocImpl fdi = env.getFieldDoc(f); FieldDocImpl fdi = env.getFieldDoc(f);
((SerialFieldTagImpl) (tag)).mapToFieldDocImpl(fdi); ((SerialFieldTagImpl) (tag)).mapToFieldDocImpl(fdi);
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,19 +23,24 @@
/* /*
* @test * @test
* @bug 6402516 * @bug 6402516 8031569
* @summary need Trees.getScope(TreePath) * @summary need Trees.getScope(TreePath)
* @build Checker CheckLocalElements * @build Checker CheckLocalElements
* @run main CheckLocalElements * @run main CheckLocalElements
*/ */
import java.io.IOException;
import java.util.*; import java.util.*;
import com.sun.source.tree.*; import java.util.regex.*;
import javax.lang.model.element.*; import javax.lang.model.element.*;
import javax.lang.model.util.*; import javax.lang.model.util.*;
import com.sun.source.tree.*;
import com.sun.source.util.*;
/* /*
* Check the local elements of a scope against the contents of string literals. * Check the local elements of a scope against the contents of string literals and top-level comment.
*/ */
public class CheckLocalElements extends Checker { public class CheckLocalElements extends Checker {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
@ -90,6 +95,16 @@ public class CheckLocalElements extends Checker {
return true; return true;
} }
@Override
void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
Matcher m = TOPLEVEL_SCOPE_DEF.matcher(topLevel.getSourceFile().getCharContent(false));
if (!m.find())
throw new AssertionError("Should have top-level scope def!");
check(trees.getScope(new TreePath(topLevel)), m.group(1));
}
//where:
Pattern TOPLEVEL_SCOPE_DEF = Pattern.compile("TOPLEVEL_SCOPE:(.*)");
private String getEnclosingName(Element e) { private String getEnclosingName(Element e) {
Element encl = e.getEnclosingElement(); Element encl = e.getEnclosingElement();
return encl == null ? "" : encl.accept(qualNameVisitor, null); return encl == null ? "" : encl.accept(qualNameVisitor, null);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -67,6 +67,7 @@ abstract class Checker {
for (CompilationUnitTree unit: units) { for (CompilationUnitTree unit: units) {
TreePath p = new TreePath(unit); TreePath p = new TreePath(unit);
s.scan(p, getTrees()); s.scan(p, getTrees());
additionalChecks(getTrees(), unit);
} }
task = null; task = null;
@ -111,6 +112,9 @@ abstract class Checker {
throw new IllegalStateException(); throw new IllegalStateException();
} }
void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
}
void error(Scope s, String ref, String msg) { void error(Scope s, String ref, String msg) {
System.err.println("Error: " + msg); System.err.println("Error: " + msg);
System.err.println("Scope: " + (s == null ? null : asList(s.getLocalElements()))); System.err.println("Scope: " + (s == null ? null : asList(s.getLocalElements())));

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,7 +23,7 @@
import java.util.List; import java.util.List;
import java.io.*; import java.io.*;
//TOPLEVEL_SCOPE:List, Test2, Test; java.io.*, java.lang.*
class Test { class Test {
void m1(int m1_arg) { void m1(int m1_arg) {
String x = "x, m1_arg, super, this; List, Test2, Test; java.io.*, java.lang.*"; String x = "x, m1_arg, super, this; List, Test2, Test; java.io.*, java.lang.*";

View File

@ -32,7 +32,7 @@ import java.util.*;
import javax.tools.StandardLocation; import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Kinds;
import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type;
@ -43,6 +43,8 @@ import com.sun.tools.javac.jvm.ClassReader;
import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names; import com.sun.tools.javac.util.Names;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
public class T6889255 { public class T6889255 {
boolean testInterfaces = true; boolean testInterfaces = true;
boolean testSyntheticMethods = true; boolean testSyntheticMethods = true;
@ -380,11 +382,11 @@ public class T6889255 {
if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces) if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces)
continue; continue;
for (Scope.Entry e = sym.members_field.elems; e != null; e = e.sibling) { for (Symbol s : sym.members_field.getSymbols(NON_RECURSIVE)) {
System.err.println("Checking member " + e.sym); System.err.println("Checking member " + s);
switch (e.sym.kind) { switch (s.kind) {
case Kinds.TYP: { case Kinds.TYP: {
String name = e.sym.flatName().toString(); String name = s.flatName().toString();
if (!classes.contains(name)) { if (!classes.contains(name)) {
classes.add(name); classes.add(name);
work.add(name); work.add(name);
@ -392,7 +394,7 @@ public class T6889255 {
break; break;
} }
case Kinds.MTH: case Kinds.MTH:
verify((MethodSymbol) e.sym, expectNames); verify((MethodSymbol) s, expectNames);
break; break;
} }

View File

@ -0,0 +1,3 @@
/* @test /nodynamiccopyright/
* @compile/fail/ref=ImportOnDemandConflicts.out -XDrawDiagnostics p1/Object.java p1/String.java p2/Boolean.java
*/

View File

@ -0,0 +1,2 @@
String.java:13:9: compiler.err.ref.ambiguous: Boolean, kindname.class, p2.Boolean, p2, kindname.class, java.lang.Boolean, java.lang
1 error

View File

@ -0,0 +1,5 @@
package p1;
public class Object {
public static void test() { }
}

View File

@ -0,0 +1,15 @@
package p1;
import p2.*;
public class String {
public static void test() { }
}
class Test1 {
private void test() {
String.test();
Object.test();
Boolean.valueOf(true);
}
}

View File

@ -0,0 +1,7 @@
package p2;
public class Boolean {
public static Boolean valueOf(boolean b) {
return null;
}
}

View File

@ -31,6 +31,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.PrintWriter; import java.io.PrintWriter;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
@ -337,6 +338,8 @@ public class DPrinter {
printList(label, (List) item); printList(label, (List) item);
} else if (item instanceof Name) { } else if (item instanceof Name) {
printName(label, (Name) item); printName(label, (Name) item);
} else if (item instanceof Scope) {
printScope(label, (Scope) item);
} else { } else {
printString(label, String.valueOf(item)); printString(label, String.valueOf(item));
} }
@ -356,7 +359,7 @@ public class DPrinter {
out.print(label); out.print(label);
out.print(": ["); out.print(": [");
String sep = ""; String sep = "";
for (Symbol sym: scope.getElements()) { for (Symbol sym: scope.getSymbols()) {
out.print(sep); out.print(sep);
out.print(sym.name); out.print(sym.name);
sep = ","; sep = ",";
@ -370,19 +373,7 @@ public class DPrinter {
out.println(label); out.println(label);
indent(+1); indent(+1);
printImplClass(scope, Scope.class); printFullScopeImpl(scope);
printSymbol("owner", scope.owner, Details.SUMMARY);
printScope("next", scope.next, Details.SUMMARY);
printObject("shared", getField(scope, Scope.class, "shared"), Details.SUMMARY);
if (scope instanceof CompoundScope) {
printObject("subScopes",
getField(scope, CompoundScope.class, "subScopes"),
Details.FULL);
} else {
for (Symbol sym : scope.getElements()) {
printSymbol(sym.name.toString(), sym, Details.SUMMARY);
}
}
indent(-1); indent(-1);
break; break;
} }
@ -390,6 +381,72 @@ public class DPrinter {
} }
} }
void printFullScopeImpl(Scope scope) {
indent();
out.println(scope.getClass().getName());
printSymbol("owner", scope.owner, Details.SUMMARY);
if (SCOPE_IMPL_CLASS.equals(scope.getClass().getName())) {
printScope("next", (Scope) getField(scope, scope.getClass(), "next"), Details.SUMMARY);
printObject("shared", getField(scope, scope.getClass(), "shared"), Details.SUMMARY);
Object[] table = (Object[]) getField(scope, scope.getClass(), "table");
for (int i = 0; i < table.length; i++) {
if (i > 0)
out.print(", ");
else
indent();
out.print(i + ":" + entryToString(table[i], table, false));
}
out.println();
} else if (FILTER_SCOPE_CLASS.equals(scope.getClass().getName())) {
printScope("delegate",
(Scope) getField(scope, scope.getClass(), "delegate"), Details.FULL);
} else if (scope instanceof CompoundScope) {
printList("delegates", (List<?>) getField(scope, CompoundScope.class, "subScopes"));
} else {
for (Symbol sym : scope.getSymbols()) {
printSymbol(sym.name.toString(), sym, Details.SUMMARY);
}
}
}
//where:
static final String SCOPE_IMPL_CLASS = "com.sun.tools.javac.code.Scope$ScopeImpl";
static final String FILTER_SCOPE_CLASS = "com.sun.tools.javac.code.Scope$FilterImportScope";
/**
* Create a string showing the contents of an entry, using the table
* to help identify cross-references to other entries in the table.
* @param e the entry to be shown
* @param table the table containing the other entries
*/
String entryToString(Object e, Object[] table, boolean ref) {
if (e == null)
return "null";
Symbol sym = (Symbol) getField(e, e.getClass(), "sym");
if (sym == null)
return "sent"; // sentinel
if (ref) {
int index = indexOf(table, e);
if (index != -1)
return String.valueOf(index);
}
Scope scope = (Scope) getField(e, e.getClass(), "scope");
return "(" + sym.name + ":" + sym
+ ",shdw:" + entryToString(callMethod(e, e.getClass(), "next"), table, true)
+ ",sibl:" + entryToString(getField(e, e.getClass(), "sibling"), table, true)
+ ((sym.owner != scope.owner)
? (",BOGUS[" + sym.owner + "," + scope.owner + "]")
: "")
+ ")";
}
<T> int indexOf(T[] array, T item) {
for (int i = 0; i < array.length; i++) {
if (array[i] == item)
return i;
}
return -1;
}
public void printSource(String label, JCTree tree) { public void printSource(String label, JCTree tree) {
printString(label, Pretty.toSimpleString(tree, maxSrcLength)); printString(label, Pretty.toSimpleString(tree, maxSrcLength));
} }
@ -552,6 +609,23 @@ public class DPrinter {
} }
} }
protected Object callMethod(Object o, Class<?> clazz, String name) {
try {
Method m = clazz.getDeclaredMethod(name);
boolean prev = m.isAccessible();
m.setAccessible(true);
try {
return m.invoke(o);
} finally {
m.setAccessible(prev);
}
} catch (ReflectiveOperationException e) {
return e;
} catch (SecurityException e) {
return e;
}
}
// </editor-fold> // </editor-fold>
// <editor-fold defaultstate="collapsed" desc="JCTree visitor methods"> // <editor-fold defaultstate="collapsed" desc="JCTree visitor methods">

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -117,13 +117,13 @@ public class CompoundScopeTest {
boolean subAdded = false; boolean subAdded = false;
for (int sc = 0 ; sc < 3 ; sc ++) { for (int sc = 0 ; sc < 3 ; sc ++) {
if (scopeNesting[sc][i]) { if (scopeNesting[sc][i]) {
sub.addSubScope(scopes[sc]); sub.prependSubScope(scopes[sc]);
if (!subAdded) { if (!subAdded) {
root.addSubScope(sub); root.prependSubScope(sub);
subAdded = true; subAdded = true;
} }
} else { } else {
root.addSubScope(scopes[sc]); root.prependSubScope(scopes[sc]);
} }
} }
log("testing scope: " + root); log("testing scope: " + root);
@ -145,7 +145,7 @@ public class CompoundScopeTest {
* Create a scope containing a given number of synthetic symbols * Create a scope containing a given number of synthetic symbols
*/ */
Scope createScope(int nelems) { Scope createScope(int nelems) {
Scope s = new Scope(symtab.noSymbol); WriteableScope s = WriteableScope.create(symtab.noSymbol);
for (int i = 0 ; i < nelems ; i++) { for (int i = 0 ; i < nelems ; i++) {
Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null); Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null);
s.enter(sym); s.enter(sym);
@ -181,7 +181,7 @@ public class CompoundScopeTest {
elems : elems :
filter(elems, sf); filter(elems, sf);
int expectedCount = allSymbols.length(); int expectedCount = allSymbols.length();
for (Symbol s : sf == null ? cs.getElements() : cs.getElements(sf)) { for (Symbol s : sf == null ? cs.getSymbols() : cs.getSymbols(sf)) {
checkSameSymbols(s, allSymbols.head); checkSameSymbols(s, allSymbols.head);
allSymbols = allSymbols.tail; allSymbols = allSymbols.tail;
found.append(s); found.append(s);
@ -204,7 +204,7 @@ public class CompoundScopeTest {
filter(shadowedEntry.getValue(), sf); filter(shadowedEntry.getValue(), sf);
int expectedCount = shadowed.length(); int expectedCount = shadowed.length();
Name name = shadowedEntry.getKey(); Name name = shadowedEntry.getKey();
for (Symbol s : sf == null ? cs.getElementsByName(name) : cs.getElementsByName(name, sf)) { for (Symbol s : sf == null ? cs.getSymbolsByName(name) : cs.getSymbolsByName(name, sf)) {
checkSameSymbols(s, shadowed.head); checkSameSymbols(s, shadowed.head);
shadowed = shadowed.tail; shadowed = shadowed.tail;
count++; count++;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -98,7 +98,7 @@ public class ImplementationCacheTest {
MethodSymbol I_m = null; MethodSymbol I_m = null;
for (Symbol sym : i.members().getElements()) { for (Symbol sym : i.members().getSymbols()) {
if (sym.name.contentEquals("m")) { if (sym.name.contentEquals("m")) {
I_m = (MethodSymbol)sym; I_m = (MethodSymbol)sym;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,16 +25,21 @@
* @test * @test
* @bug 7004029 * @bug 7004029
* @summary Ensure Scope impl can cope with hash collisions * @summary Ensure Scope impl can cope with hash collisions
* @library /tools/javac/lib
* @build DPrinter HashCollisionTest
* @run main HashCollisionTest
*/ */
import java.lang.reflect.*; import java.lang.reflect.*;
import java.io.*; import java.io.*;
import com.sun.source.util.Trees;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.util.*; import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.*; import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import static com.sun.tools.javac.code.Kinds.*;
public class HashCollisionTest { public class HashCollisionTest {
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
@ -47,12 +52,13 @@ public class HashCollisionTest {
JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
names = Names.instance(context); // Name.Table impls tied to an instance of Names names = Names.instance(context); // Name.Table impls tied to an instance of Names
symtab = Symtab.instance(context); symtab = Symtab.instance(context);
trees = JavacTrees.instance(context);
// determine hashMask for an empty scope // determine hashMask for an empty scope
Scope emptyScope = new Scope(symtab.unnamedPackage); // any owner will do Scope emptyScope = WriteableScope.create(symtab.unnamedPackage); // any owner will do
Field sHashMask = Scope.class.getDeclaredField("hashMask"); Field field = emptyScope.getClass().getDeclaredField("hashMask");
sHashMask.setAccessible(true); field.setAccessible(true);
scopeHashMask = sHashMask.getInt(emptyScope); scopeHashMask = field.getInt(emptyScope);
log("scopeHashMask: " + scopeHashMask); log("scopeHashMask: " + scopeHashMask);
// 1. determine the Name.hashCode of "Entry", and therefore the index of // 1. determine the Name.hashCode of "Entry", and therefore the index of
@ -92,7 +98,7 @@ public class HashCollisionTest {
// 4. Create a package containing a nested class using the name from 2 // 4. Create a package containing a nested class using the name from 2
PackageSymbol p = new PackageSymbol(names.fromString("p"), symtab.rootPackage); PackageSymbol p = new PackageSymbol(names.fromString("p"), symtab.rootPackage);
p.members_field = new Scope(p); p.members_field = WriteableScope.create(p);
ClassSymbol inner = createClass(innerName, p); ClassSymbol inner = createClass(innerName, p);
// we'll need this later when we "rename" cn // we'll need this later when we "rename" cn
ClassSymbol outer = createClass(outerName, p); ClassSymbol outer = createClass(outerName, p);
@ -100,42 +106,25 @@ public class HashCollisionTest {
// 5. Create a star-import scope // 5. Create a star-import scope
log ("createStarImportScope"); 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); PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
try { StarImportScope starImportScope = new StarImportScope(pkg);
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); dump("initial", starImportScope);
// 6. Insert the contents of the package from 4. // 6. Insert the contents of the package from 4.
Scope p_members = p.members(); Scope fromScope = p.members();
if (importAll != null) { ImportFilter typeFilter = new ImportFilter() {
importAll.invoke(starImportScope, p_members); @Override
} else { public boolean accepts(Scope origin, Symbol sym) {
Scope fromScope = p_members; return sym.kind == Kinds.TYP;
Scope toScope = starImportScope;
// The following lines are taken from MemberEnter.importAll,
// 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);
} }
} };
starImportScope.importAll(fromScope, fromScope, typeFilter, false);
dump("imported p", starImportScope); dump("imported p", starImportScope);
// 7. Insert the class from 3. // 7. Insert the class from 3.
starImportScope.enter(ce, cc.members_field); starImportScope.importAll(cc.members_field, cc.members_field, typeFilter, false);
dump("imported ce", starImportScope); dump("imported ce", starImportScope);
/* /*
@ -149,11 +138,11 @@ public class HashCollisionTest {
outer.members_field.enter(inner); outer.members_field.enter(inner);
// 9. Lookup Entry // 9. Lookup Entry
Scope.Entry e = starImportScope.lookup(entry); Symbol found = starImportScope.findFirst(entry);
dump("final", starImportScope); if (found != ce)
throw new Exception("correct symbol not found: " + entry + "; found=" + found);
if (e.sym == null) dump("final", starImportScope);
throw new Exception("symbol not found: " + entry);
} }
/* /*
@ -170,7 +159,7 @@ public class HashCollisionTest {
*/ */
ClassSymbol createClass(Name name, Symbol owner) { ClassSymbol createClass(Name name, Symbol owner) {
ClassSymbol sym = new ClassSymbol(0, name, owner); ClassSymbol sym = new ClassSymbol(0, name, owner);
sym.members_field = new Scope(sym); sym.members_field = WriteableScope.create(sym);
if (owner != symtab.unnamedPackage) if (owner != symtab.unnamedPackage)
owner.members().enter(sym); owner.members().enter(sym);
return sym; return sym;
@ -180,58 +169,16 @@ public class HashCollisionTest {
* Dump the contents of a scope to System.err. * Dump the contents of a scope to System.err.
*/ */
void dump(String label, Scope s) throws Exception { void dump(String label, Scope s) throws Exception {
dump(label, s, System.err); PrintWriter pw = new PrintWriter(System.err);
new DPrinter(pw, trees).printScope(label, s);
pw.flush();
} }
/** Object readField(Object scope, String fieldName) throws Exception {
* Dump the contents of a scope to a stream. Field field = scope.getClass().getDeclaredField(fieldName);
*/ field.setAccessible(true);
void dump(String label, Scope s, PrintStream out) throws Exception {
out.println(label);
Field sTable = Scope.class.getDeclaredField("table");
sTable.setAccessible(true);
out.println("owner:" + s.owner); return field.get(scope);
Scope.Entry[] table = (Scope.Entry[]) sTable.get(s);
for (int i = 0; i < table.length; i++) {
if (i > 0)
out.print(", ");
out.print(i + ":" + toString(table[i], table, false));
}
out.println();
}
/**
* Create a string showing the contents of an entry, using the table
* to help identify cross-references to other entries in the table.
* @param e the entry to be shown
* @param table the table containing the other entries
*/
String toString(Scope.Entry e, Scope.Entry[] table, boolean ref) {
if (e == null)
return "null";
if (e.sym == null)
return "sent"; // sentinel
if (ref) {
int index = indexOf(table, e);
if (index != -1)
return String.valueOf(index);
}
return "(" + e.sym.name + ":" + e.sym
+ ",shdw:" + toString(e.next(), table, true)
+ ",sibl:" + toString(e.sibling, table, true)
+ ((e.sym.owner != e.scope.owner)
? (",BOGUS[" + e.sym.owner + "," + e.scope.owner + "]")
: "")
+ ")";
}
<T> int indexOf(T[] array, T item) {
for (int i = 0; i < array.length; i++) {
if (array[i] == item)
return i;
}
return -1;
} }
/** /**
@ -246,4 +193,5 @@ public class HashCollisionTest {
Names names; Names names;
Symtab symtab; Symtab symtab;
Trees trees;
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -27,14 +27,17 @@
* @summary Basher for star-import scopes * @summary Basher for star-import scopes
*/ */
import java.lang.reflect.*;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.*; import com.sun.tools.javac.code.Scope.ImportFilter;
import com.sun.tools.javac.code.Scope.StarImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.*;
import static com.sun.tools.javac.code.Kinds.*; import static com.sun.tools.javac.code.Kinds.*;
public class StarImportTest { public class StarImportTest {
@ -87,13 +90,9 @@ public class StarImportTest {
System.err.print(msg); System.err.print(msg);
System.err.print(": "); System.err.print(": ");
String sep = "("; String sep = "(";
for (Scope.Entry se = s.elems; se != null; se = se.sibling) { for (Symbol sym : s.getSymbols()) {
for (Scope.Entry e = se; e.sym != null; e = e.next()) { System.err.print(sep + sym.name + ":" + sym);
System.err.print(sep + e.sym.name + ":" + e.sym); sep = ",";
sep = ",";
}
System.err.print(")");
sep = ", (";
} }
System.err.println(); System.err.println();
} }
@ -171,7 +170,7 @@ public class StarImportTest {
int count = rgen.nextInt(MAX_SETUP_PACKAGE_COUNT); int count = rgen.nextInt(MAX_SETUP_PACKAGE_COUNT);
log("setup: creating package " + name + " with " + count + " entries"); log("setup: creating package " + name + " with " + count + " entries");
PackageSymbol p = new PackageSymbol(name, symtab.rootPackage); PackageSymbol p = new PackageSymbol(name, symtab.rootPackage);
p.members_field = new Scope(p); p.members_field = WriteableScope.create(p);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
String outer = name + "c" + i; String outer = name + "c" + i;
String suffix = random(null, "$Entry", "$Entry2"); String suffix = random(null, "$Entry", "$Entry2");
@ -213,38 +212,21 @@ public class StarImportTest {
log ("createStarImportScope"); log ("createStarImportScope");
PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage); PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
// if StarImportScope exists, use it, otherwise, for testing legacy code, starImportScope = new StarImportScope(pkg);
// fall back on ImportScope
Method importAll;
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;
}
starImportModel = new Model(); starImportModel = new Model();
for (Symbol imp: imports) { for (Symbol imp: imports) {
Scope members = imp.members(); Scope members = imp.members();
if (importAll != null) {
// log("importAll", members); // log("importAll", members);
importAll.invoke(starImportScope, members); starImportScope.importAll(members, members, new ImportFilter() {
} else { @Override
Scope fromScope = members; public boolean accepts(Scope origin, Symbol t) {
Scope toScope = starImportScope; return t.kind == TYP;
// The following lines are taken from MemberEnter.importAll,
// 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);
} }
} }, false);
for (Scope.Entry e = members.elems; e != null; e = e.sibling) { for (Symbol sym : members.getSymbols()) {
starImportModel.enter(e.sym); starImportModel.enter(sym);
} }
} }
@ -260,9 +242,9 @@ public class StarImportTest {
log ("test"); log ("test");
List<ClassSymbol> nestedClasses = new LinkedList<ClassSymbol>(); List<ClassSymbol> nestedClasses = new LinkedList<ClassSymbol>();
for (PackageSymbol p: packages) { for (PackageSymbol p: packages) {
for (Scope.Entry se = p.members_field.elems; se != null; se = se.sibling) { for (Symbol sym : p.members_field.getSymbols()) {
if (se.sym.name.toString().contains("$")) if (sym.name.toString().contains("$"))
nestedClasses.add((ClassSymbol) se.sym); nestedClasses.add((ClassSymbol) sym);
} }
} }
@ -283,8 +265,7 @@ public class StarImportTest {
// determine new owner // determine new owner
Name outerName = names.fromString(s.substring(0, dollar)); Name outerName = names.fromString(s.substring(0, dollar));
// log(sym + " owner: " + sym.owner, sym.owner.members()); // log(sym + " owner: " + sym.owner, sym.owner.members());
Scope.Entry outerEntry = sym.owner.members().lookup(outerName); ClassSymbol outer = (ClassSymbol)sym.owner.members().findFirst(outerName);
ClassSymbol outer = (ClassSymbol) outerEntry.sym;
// log("outer: " + outerName + " " + outer); // log("outer: " + outerName + " " + outer);
// remove from package // remove from package
@ -302,7 +283,7 @@ public class StarImportTest {
ClassSymbol createClass(Name name, Symbol owner) { ClassSymbol createClass(Name name, Symbol owner) {
ClassSymbol sym = new ClassSymbol(0, name, owner); ClassSymbol sym = new ClassSymbol(0, name, owner);
sym.members_field = new Scope(sym); sym.members_field = WriteableScope.create(sym);
if (owner != symtab.unnamedPackage) if (owner != symtab.unnamedPackage)
owner.members().enter(sym); owner.members().enter(sym);
return sym; return sym;
@ -318,7 +299,7 @@ public class StarImportTest {
List<Symbol> imports = new ArrayList<Symbol>(); List<Symbol> imports = new ArrayList<Symbol>();
int nextClassSerial; int nextClassSerial;
Scope starImportScope; StarImportScope starImportScope;
Model starImportModel; Model starImportModel;
} }
@ -355,9 +336,8 @@ public class StarImportTest {
void check(Scope scope) { void check(Scope scope) {
// First, check all entries in scope are in map // First, check all entries in scope are in map
int bogusCount = 0; int bogusCount = 0;
for (Scope.Entry se = scope.elems; se != null; se = se.sibling) { for (Symbol sym : scope.getSymbols()) {
Symbol sym = se.sym; if (sym.owner != scope.getOrigin(sym).owner) {
if (sym.owner != se.scope.owner) {
if (bogus.contains(sym)) { if (bogus.contains(sym)) {
bogusCount++; bogusCount++;
} else { } else {
@ -380,16 +360,14 @@ public class StarImportTest {
// Second, check all entries in map are in scope // Second, check all entries in map are in scope
for (Map.Entry<Name,Set<Symbol>> me: map.entrySet()) { for (Map.Entry<Name,Set<Symbol>> me: map.entrySet()) {
Name name = me.getKey(); Name name = me.getKey();
Scope.Entry se = scope.lookup(name); if (scope.findFirst(name) == null) {
assert (se != null);
if (se.sym == null) {
error("check: no entries found for " + name + " in scope"); error("check: no entries found for " + name + " in scope");
continue; continue;
} }
nextSym: nextSym:
for (Symbol sym: me.getValue()) { for (Symbol sym: me.getValue()) {
for (Scope.Entry e = se; e.sym != null; e = e.next()) { for (Symbol s : scope.getSymbolsByName(name)) {
if (sym == e.sym) if (sym == s)
continue nextSym; continue nextSym;
} }
error("check: symbol " + sym + " not found in scope"); error("check: symbol " + sym + " not found in scope");

View File

@ -1,2 +1,2 @@
T6537020.java:25:16: compiler.err.ref.ambiguous: s, kindname.variable, s, p.T6537020.B, kindname.variable, s, p.T6537020.A T6537020.java:25:16: compiler.err.ref.ambiguous: s, kindname.variable, s, p.T6537020.A, kindname.variable, s, p.T6537020.B
1 error 1 error