--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacScope.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacScope.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,18 +46,33 @@
* @author Jonathan Gibbons;
*/
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;
- /** Creates a new instance of JavacScope */
- JavacScope(Env<AttrContext> env) {
+ private JavacScope(Env<AttrContext> env) {
env.getClass(); // null-check
this.env = env;
}
public JavacScope getEnclosingScope() {
- if (env.outer != null && env.outer != env)
- return new JavacScope(env.outer);
- else {
+ if (env.outer != null && env.outer != env) {
+ return create(env.outer);
+ } else {
// synthesize an outermost "star-import" scope
return new JavacScope(env) {
public boolean isStarImportScope() {
@@ -67,7 +82,7 @@
return null;
}
public Iterable<? extends Element> getLocalElements() {
- return env.toplevel.starImportScope.getElements();
+ return env.toplevel.starImportScope.getSymbols();
}
};
}
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Jul 10 12:39:26 2014 -0700
@@ -456,10 +456,9 @@
}
searched.add(tsym);
- for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(fieldName);
- e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.VAR) {
- return (VarSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbolsByName(fieldName)) {
+ if (sym.kind == Kinds.VAR) {
+ return (VarSymbol)sym;
}
}
@@ -499,11 +498,10 @@
/** @see com.sun.tools.javadoc.ClassDocImpl#findConstructor */
MethodSymbol findConstructor(ClassSymbol tsym, List<Type> paramTypes) {
- for (com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(names.init);
- e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH) {
- if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
- return (MethodSymbol) e.sym;
+ for (Symbol sym : tsym.members().getSymbolsByName(names.init)) {
+ if (sym.kind == Kinds.MTH) {
+ if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
+ return (MethodSymbol) sym;
}
}
}
@@ -529,7 +527,6 @@
searched.add(tsym);
// search current class
- com.sun.tools.javac.code.Scope.Entry e = tsym.members().lookup(methodName);
//### Using modifier filter here isn't really correct,
//### but emulates the old behavior. Instead, we should
@@ -542,10 +539,10 @@
// In order to provide textually identical results, we
// attempt to emulate the old behavior.
MethodSymbol lastFound = null;
- for (; e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH) {
- if (e.sym.name == methodName) {
- lastFound = (MethodSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
+ if (sym.kind == Kinds.MTH) {
+ if (sym.name == methodName) {
+ lastFound = (MethodSymbol)sym;
}
}
}
@@ -553,11 +550,11 @@
return lastFound;
}
} else {
- for (; e.scope != null; e = e.next()) {
- if (e.sym != null &&
- e.sym.kind == Kinds.MTH) {
- if (hasParameterTypes((MethodSymbol) e.sym, paramTypes)) {
- return (MethodSymbol) e.sym;
+ for (Symbol sym : tsym.members().getSymbolsByName(methodName)) {
+ if (sym != null &&
+ sym.kind == Kinds.MTH) {
+ if (hasParameterTypes((MethodSymbol) sym, paramTypes)) {
+ return (MethodSymbol) sym;
}
}
}
@@ -684,7 +681,7 @@
}
public JavacScope getScope(TreePath path) {
- return new JavacScope(getAttrContext(path));
+ return JavacScope.create(getAttrContext(path));
}
public String getDocComment(TreePath path) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
import static javax.tools.StandardLocation.*;
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.jvm.ClassReader;
import com.sun.tools.javac.util.*;
@@ -218,7 +219,7 @@
if (c.owner.kind == PCK) {
Symbol owner = c.owner;
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)
encl = syms.classes.get(TypeSymbol.formFlatName(name, owner));
if (encl != null)
@@ -335,7 +336,7 @@
boolean isPkgInfo = classname == names.package_info;
ClassSymbol c = isPkgInfo
? p.package_info
- : (ClassSymbol) p.members_field.lookup(classname).sym;
+ : (ClassSymbol) p.members_field.findFirst(classname);
if (c == null) {
c = syms.enterClass(classname, p);
if (c.classfile == null) // only update the file if's it's newly created
@@ -399,7 +400,7 @@
*/
private void fillIn(PackageSymbol p) throws IOException {
if (p.members_field == null)
- p.members_field = new Scope(p);
+ p.members_field = WriteableScope.create(p);
preferCurrent = false;
if (userPathsFirst) {
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,440 +25,588 @@
package com.sun.tools.javac.code;
-import java.util.Iterator;
+import java.util.*;
import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+import static com.sun.tools.javac.code.Scope.LookupKind.RECURSIVE;
/** A scope represents an area of visibility in a Java program. The
* Scope class is a container for symbols which provides
* efficient access to symbols given their names. Scopes are implemented
* as hash tables with "open addressing" and "double hashing".
- * Scopes can be nested; the next field of a scope points
- * to its next outer scope. Nested scopes can share their hash tables.
+ * Scopes can be nested. Nested scopes can share their hash tables.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class Scope {
-
- /** The number of scopes that share this scope's hash table.
- */
- private int shared;
-
- /** Next enclosing scope (with whom this scope may share a hashtable)
- */
- public Scope next;
+public abstract class Scope {
/** The scope's owner.
*/
- public Symbol owner;
+ public final Symbol owner;
+
+ protected Scope(Symbol owner) {
+ this.owner = owner;
+ }
- /** A hash table for the scope's entries.
+ /**Returns all Symbols in this Scope. Symbols from outward Scopes are included.
+ */
+ public final Iterable<Symbol> getSymbols() {
+ return getSymbols(noFilter);
+ }
+
+ /**Returns Symbols that match the given filter. Symbols from outward Scopes are included.
+ */
+ public final Iterable<Symbol> getSymbols(Filter<Symbol> sf) {
+ return getSymbols(sf, RECURSIVE);
+ }
+
+ /**Returns all Symbols in this Scope. Symbols from outward Scopes are included
+ * iff lookupKind == RECURSIVE.
*/
- Entry[] table;
+ public final Iterable<Symbol> getSymbols(LookupKind lookupKind) {
+ return getSymbols(noFilter, lookupKind);
+ }
+
+ /**Returns Symbols that match the given filter. Symbols from outward Scopes are included
+ * iff lookupKind == RECURSIVE.
+ */
+ public abstract Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind);
- /** Mask for hash codes, always equal to (table.length - 1).
+ /**Returns Symbols with the given name. Symbols from outward Scopes are included.
+ */
+ public final Iterable<Symbol> getSymbolsByName(Name name) {
+ return getSymbolsByName(name, RECURSIVE);
+ }
+
+ /**Returns Symbols with the given name that match the given filter.
+ * Symbols from outward Scopes are included.
*/
- int hashMask;
+ public final Iterable<Symbol> getSymbolsByName(final Name name, final Filter<Symbol> sf) {
+ return getSymbolsByName(name, sf, RECURSIVE);
+ }
+
+ /**Returns Symbols with the given name. Symbols from outward Scopes are included
+ * iff lookupKind == RECURSIVE.
+ */
+ public final Iterable<Symbol> getSymbolsByName(Name name, LookupKind lookupKind) {
+ return getSymbolsByName(name, noFilter, lookupKind);
+ }
- /** A linear list that also contains all entries in
- * reverse order of appearance (i.e later entries are pushed on top).
+ /**Returns Symbols with the given name that match the given filter.
+ * Symbols from outward Scopes are included iff lookupKind == RECURSIVE.
+ */
+ public abstract Iterable<Symbol> getSymbolsByName(final Name name, final Filter<Symbol> sf,
+ final LookupKind lookupKind);
+
+ /** Return the first Symbol from this or outward scopes with the given name.
+ * Returns null if none.
*/
- public Entry elems;
+ public final Symbol findFirst(Name name) {
+ return findFirst(name, noFilter);
+ }
+
+ /** Return the first Symbol from this or outward scopes with the given name that matches the
+ * given filter. Returns null if none.
+ */
+ public Symbol findFirst(Name name, Filter<Symbol> sf) {
+ Iterator<Symbol> it = getSymbolsByName(name, sf).iterator();
+ return it.hasNext() ? it.next() : null;
+ }
- /** The number of elements in this scope.
- * This includes deleted elements, whose value is the sentinel.
+ /** Returns true iff there are is at least one Symbol in this scope matching the given filter.
+ * Does not inspect outward scopes.
+ */
+ public boolean anyMatch(Filter<Symbol> filter) {
+ return getSymbols(filter, NON_RECURSIVE).iterator().hasNext();
+ }
+
+ /** Returns true iff the given Symbol is in this scope or any outward scope.
*/
- int nelems = 0;
+ public boolean includes(final Symbol sym) {
+ return getSymbolsByName(sym.name, new Filter<Symbol>() {
+ @Override
+ public boolean accepts(Symbol t) {
+ return t == sym;
+ }
+ }).iterator().hasNext();
+ }
+
+ /** Returns true iff this scope does not contain any Symbol. Does not inspect outward scopes.
+ */
+ public boolean isEmpty() {
+ return !getSymbols(NON_RECURSIVE).iterator().hasNext();
+ }
+
+ /** Returns the Scope from which the givins Symbol originates in this scope.
+ */
+ public abstract Scope getOrigin(Symbol byName);
+
+ /** Returns true iff the given Symbol is part of this scope due to a static import.
+ */
+ public abstract boolean isStaticallyImported(Symbol byName);
+
+ private static final Filter<Symbol> noFilter = null;
/** A list of scopes to be notified if items are to be removed from this scope.
*/
List<ScopeListener> listeners = List.nil();
- /** Use as a "not-found" result for lookup.
- * Also used to mark deleted entries in the table.
- */
- private static final Entry sentinel = new Entry(null, null, null, null);
-
- /** The hash table's initial size.
- */
- private static final int INITIAL_SIZE = 0x10;
-
- /** A value for the empty scope.
- */
- public static final Scope emptyScope = new Scope(null, null, new Entry[]{});
-
- /** Construct a new scope, within scope next, with given owner, using
- * given table. The table's length must be an exponent of 2.
- */
- private Scope(Scope next, Symbol owner, Entry[] table) {
- this.next = next;
- Assert.check(emptyScope == null || owner != null);
- this.owner = owner;
- this.table = table;
- this.hashMask = table.length - 1;
- }
-
- /** Convenience constructor used for dup and dupUnshared. */
- private Scope(Scope next, Symbol owner, Entry[] table, int nelems) {
- this(next, owner, table);
- this.nelems = nelems;
- }
-
- /** Construct a new scope, within scope next, with given owner,
- * using a fresh table of length INITIAL_SIZE.
- */
- public Scope(Symbol owner) {
- this(null, owner, new Entry[INITIAL_SIZE]);
- }
-
- /** Construct a fresh scope within this scope, with same owner,
- * which shares its table with the outer scope. Used in connection with
- * method leave if scope access is stack-like in order to avoid allocation
- * of fresh tables.
- */
- public Scope dup() {
- return dup(this.owner);
- }
-
- /** Construct a fresh scope within this scope, with new owner,
- * which shares its table with the outer scope. Used in connection with
- * method leave if scope access is stack-like in order to avoid allocation
- * of fresh tables.
- */
- public Scope dup(Symbol newOwner) {
- Scope result = new Scope(this, newOwner, this.table, this.nelems);
- shared++;
- // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
- // new Error().printStackTrace(System.out);
- return result;
- }
-
- /** Construct a fresh scope within this scope, with same owner,
- * with a new hash table, whose contents initially are those of
- * the table of its outer scope.
- */
- public Scope dupUnshared() {
- return new Scope(this, this.owner, this.table.clone(), this.nelems);
+ public void addScopeListener(ScopeListener sl) {
+ listeners = listeners.prepend(sl);
}
- /** Remove all entries of this scope from its table, if shared
- * with next.
- */
- public Scope leave() {
- Assert.check(shared == 0);
- if (table != next.table) return next;
- while (elems != null) {
- int hash = getIndex(elems.sym.name);
- Entry e = table[hash];
- Assert.check(e == elems, elems.sym);
- table[hash] = elems.shadowed;
- elems = elems.sibling;
- }
- Assert.check(next.shared > 0);
- next.shared--;
- next.nelems = nelems;
- // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
- // new Error().printStackTrace(System.out);
- return next;
- }
-
- /** Double size of hash table.
- */
- private void dble() {
- Assert.check(shared == 0);
- Entry[] oldtable = table;
- Entry[] newtable = new Entry[oldtable.length * 2];
- for (Scope s = this; s != null; s = s.next) {
- if (s.table == oldtable) {
- Assert.check(s == this || s.shared != 0);
- s.table = newtable;
- s.hashMask = newtable.length - 1;
- }
- }
- int n = 0;
- for (int i = oldtable.length; --i >= 0; ) {
- Entry e = oldtable[i];
- if (e != null && e != sentinel) {
- table[getIndex(e.sym.name)] = e;
- n++;
- }
- }
- // We don't need to update nelems for shared inherited scopes,
- // since that gets handled by leave().
- nelems = n;
- }
-
- /** Enter symbol sym in this scope.
- */
- public void enter(Symbol sym) {
- Assert.check(shared == 0);
- enter(sym, this);
- }
-
- public void enter(Symbol sym, Scope s) {
- enter(sym, s, s, false);
- }
-
- /**
- * Enter symbol sym in this scope, but mark that it comes from
- * given scope `s' accessed through `origin'. The last two
- * arguments are only used in import scopes.
- */
- public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
- Assert.check(shared == 0);
- if (nelems * 3 >= hashMask * 2)
- dble();
- int hash = getIndex(sym.name);
- Entry old = table[hash];
- if (old == null) {
- old = sentinel;
- nelems++;
- }
- Entry e = makeEntry(sym, old, elems, s, origin, staticallyImported);
- table[hash] = e;
- elems = e;
-
- //notify listeners
- for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
- l.head.symbolAdded(sym, this);
- }
- }
-
- Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin, boolean staticallyImported) {
- return new Entry(sym, shadowed, sibling, scope);
- }
-
-
public interface ScopeListener {
public void symbolAdded(Symbol sym, Scope s);
public void symbolRemoved(Symbol sym, Scope s);
}
- public void addScopeListener(ScopeListener sl) {
- listeners = listeners.prepend(sl);
- }
-
- /** Remove symbol from this scope. Used when an inner class
- * attribute tells us that the class isn't a package member.
- */
- public void remove(Symbol sym) {
- Assert.check(shared == 0);
- Entry e = lookup(sym.name);
- if (e.scope == null) return;
-
- // remove e from table and shadowed list;
- int i = getIndex(sym.name);
- Entry te = table[i];
- if (te == e)
- table[i] = e.shadowed;
- else while (true) {
- if (te.shadowed == e) {
- te.shadowed = e.shadowed;
- break;
- }
- te = te.shadowed;
- }
-
- // remove e from elems and sibling list
- te = elems;
- if (te == e)
- elems = e.sibling;
- else while (true) {
- if (te.sibling == e) {
- te.sibling = e.sibling;
- break;
- }
- te = te.sibling;
- }
-
- //notify listeners
- for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
- l.head.symbolRemoved(sym, this);
- }
+ public enum LookupKind {
+ RECURSIVE,
+ NON_RECURSIVE;
}
- /** Enter symbol sym in this scope if not already there.
- */
- public void enterIfAbsent(Symbol sym) {
- Assert.check(shared == 0);
- Entry e = lookup(sym.name);
- while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
- if (e.scope != this) enter(sym);
- }
+ /**A scope into which Symbols can be added.*/
+ public abstract static class WriteableScope extends Scope {
+
+ public WriteableScope(Symbol owner) {
+ super(owner);
+ }
- /** Given a class, is there already a class with same fully
- * qualified name in this (import) scope?
- */
- public boolean includes(Symbol c) {
- for (Scope.Entry e = lookup(c.name);
- e.scope == this;
- e = e.next()) {
- if (e.sym == c) return true;
+ /** Enter the given Symbol into this scope.
+ */
+ public abstract void enter(Symbol c);
+ /** Enter symbol sym in this scope if not already there.
+ */
+ public abstract void enterIfAbsent(Symbol c);
+
+ public abstract void remove(Symbol c);
+
+ /** Construct a fresh scope within this scope, with same owner. The new scope may
+ * shares internal structures with the this scope. Used in connection with
+ * method leave if scope access is stack-like in order to avoid allocation
+ * of fresh tables.
+ */
+ public final WriteableScope dup() {
+ return dup(this.owner);
}
- return false;
- }
- static final Filter<Symbol> noFilter = new Filter<Symbol>() {
- public boolean accepts(Symbol s) {
- return true;
- }
- };
+ /** Construct a fresh scope within this scope, with new owner. The new scope may
+ * shares internal structures with the this scope. Used in connection with
+ * method leave if scope access is stack-like in order to avoid allocation
+ * of fresh tables.
+ */
+ public abstract WriteableScope dup(Symbol newOwner);
+
+ /** Must be called on dup-ed scopes to be able to work with the outward scope again.
+ */
+ public abstract WriteableScope leave();
- /** Return the entry associated with given name, starting in
- * this scope and proceeding outwards. If no entry was found,
- * return the sentinel, which is characterized by having a null in
- * both its scope and sym fields, whereas both fields are non-null
- * for regular entries.
- */
- public Entry lookup(Name name) {
- return lookup(name, noFilter);
- }
+ /** Construct a fresh scope within this scope, with same owner. The new scope
+ * will not share internal structures with this scope.
+ */
+ public final WriteableScope dupUnshared() {
+ return dupUnshared(owner);
+ }
- public Entry lookup(Name name, Filter<Symbol> sf) {
- Entry e = table[getIndex(name)];
- if (e == null || e == sentinel)
- return sentinel;
- while (e.scope != null && (e.sym.name != name || !sf.accepts(e.sym)))
- e = e.shadowed;
- return e;
+ /** Construct a fresh scope within this scope, with new owner. The new scope
+ * will not share internal structures with this scope.
+ */
+ public abstract WriteableScope dupUnshared(Symbol newOwner);
+
+ /** Create a new WriteableScope.
+ */
+ public static WriteableScope create(Symbol owner) {
+ return new ScopeImpl(owner);
+ }
+
}
- /*void dump (java.io.PrintStream out) {
- out.println(this);
- for (int l=0; l < table.length; l++) {
- Entry le = table[l];
- out.print("#"+l+": ");
- if (le==sentinel) out.println("sentinel");
- else if(le == null) out.println("null");
- else out.println(""+le+" s:"+le.sym);
- }
- }*/
+ private static class ScopeImpl extends WriteableScope {
+ /** The number of scopes that share this scope's hash table.
+ */
+ private int shared;
+
+ /** Next enclosing scope (with whom this scope may share a hashtable)
+ */
+ public ScopeImpl next;
+
+ /** A hash table for the scope's entries.
+ */
+ Entry[] table;
+
+ /** Mask for hash codes, always equal to (table.length - 1).
+ */
+ int hashMask;
+
+ /** A linear list that also contains all entries in
+ * reverse order of appearance (i.e later entries are pushed on top).
+ */
+ public Entry elems;
+
+ /** The number of elements in this scope.
+ * This includes deleted elements, whose value is the sentinel.
+ */
+ int nelems = 0;
+
+ /** Use as a "not-found" result for lookup.
+ * Also used to mark deleted entries in the table.
+ */
+ private static final Entry sentinel = new Entry(null, null, null, null);
+
+ /** The hash table's initial size.
+ */
+ private static final int INITIAL_SIZE = 0x10;
- /** Look for slot in the table.
- * We use open addressing with double hashing.
- */
- int getIndex (Name name) {
- int h = name.hashCode();
- int i = h & hashMask;
- // The expression below is always odd, so it is guaranteed
- // to be mutually prime with table.length, a power of 2.
- int x = hashMask - ((h + (h >> 16)) << 1);
- int d = -1; // Index of a deleted item.
- for (;;) {
- Entry e = table[i];
- if (e == null)
- return d >= 0 ? d : i;
- if (e == sentinel) {
- // We have to keep searching even if we see a deleted item.
- // However, remember the index in case we fail to find the name.
- if (d < 0)
- d = i;
- } else if (e.sym.name == name)
- return i;
- i = (i + x) & hashMask;
+ /** Construct a new scope, within scope next, with given owner, using
+ * given table. The table's length must be an exponent of 2.
+ */
+ private ScopeImpl(ScopeImpl next, Symbol owner, Entry[] table) {
+ super(owner);
+ this.next = next;
+ Assert.check(owner != null);
+ this.table = table;
+ this.hashMask = table.length - 1;
+ }
+
+ /** Convenience constructor used for dup and dupUnshared. */
+ private ScopeImpl(ScopeImpl next, Symbol owner, Entry[] table, int nelems) {
+ this(next, owner, table);
+ this.nelems = nelems;
}
- }
- public boolean anyMatch(Filter<Symbol> sf) {
- return getElements(sf).iterator().hasNext();
- }
-
- public Iterable<Symbol> getElements() {
- return getElements(noFilter);
- }
+ /** Construct a new scope, within scope next, with given owner,
+ * using a fresh table of length INITIAL_SIZE.
+ */
+ public ScopeImpl(Symbol owner) {
+ this(null, owner, new Entry[INITIAL_SIZE]);
+ }
- public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
- return new Iterable<Symbol>() {
- public Iterator<Symbol> iterator() {
- return new Iterator<Symbol>() {
- private Scope currScope = Scope.this;
- private Scope.Entry currEntry = elems;
- {
- update();
- }
+ /** Construct a fresh scope within this scope, with new owner,
+ * which shares its table with the outer scope. Used in connection with
+ * method leave if scope access is stack-like in order to avoid allocation
+ * of fresh tables.
+ */
+ public WriteableScope dup(Symbol newOwner) {
+ ScopeImpl result = new ScopeImpl(this, newOwner, this.table, this.nelems);
+ shared++;
+ // System.out.println("====> duping scope " + this.hashCode() + " owned by " + newOwner + " to " + result.hashCode());
+ // new Error().printStackTrace(System.out);
+ return result;
+ }
- public boolean hasNext() {
- return currEntry != null;
- }
+ /** Construct a fresh scope within this scope, with new owner,
+ * with a new hash table, whose contents initially are those of
+ * the table of its outer scope.
+ */
+ public WriteableScope dupUnshared(Symbol newOwner) {
+ return new ScopeImpl(this, newOwner, this.table.clone(), this.nelems);
+ }
- public Symbol next() {
- Symbol sym = (currEntry == null ? null : currEntry.sym);
- if (currEntry != null) {
- currEntry = currEntry.sibling;
- }
- update();
- return sym;
- }
-
- public void remove() {
- throw new UnsupportedOperationException();
- }
+ /** Remove all entries of this scope from its table, if shared
+ * with next.
+ */
+ public WriteableScope leave() {
+ Assert.check(shared == 0);
+ if (table != next.table) return next;
+ while (elems != null) {
+ int hash = getIndex(elems.sym.name);
+ Entry e = table[hash];
+ Assert.check(e == elems, elems.sym);
+ table[hash] = elems.shadowed;
+ elems = elems.sibling;
+ }
+ Assert.check(next.shared > 0);
+ next.shared--;
+ next.nelems = nelems;
+ // System.out.println("====> leaving scope " + this.hashCode() + " owned by " + this.owner + " to " + next.hashCode());
+ // new Error().printStackTrace(System.out);
+ return next;
+ }
- private void update() {
- skipToNextMatchingEntry();
- while (currEntry == null && currScope.next != null) {
- currScope = currScope.next;
- currEntry = currScope.elems;
- skipToNextMatchingEntry();
- }
- }
-
- void skipToNextMatchingEntry() {
- while (currEntry != null && !sf.accepts(currEntry.sym)) {
- currEntry = currEntry.sibling;
- }
- }
- };
+ /** Double size of hash table.
+ */
+ private void dble() {
+ Assert.check(shared == 0);
+ Entry[] oldtable = table;
+ Entry[] newtable = new Entry[oldtable.length * 2];
+ for (ScopeImpl s = this; s != null; s = s.next) {
+ if (s.table == oldtable) {
+ Assert.check(s == this || s.shared != 0);
+ s.table = newtable;
+ s.hashMask = newtable.length - 1;
+ }
}
- };
- }
+ int n = 0;
+ for (int i = oldtable.length; --i >= 0; ) {
+ Entry e = oldtable[i];
+ if (e != null && e != sentinel) {
+ table[getIndex(e.sym.name)] = e;
+ n++;
+ }
+ }
+ // We don't need to update nelems for shared inherited scopes,
+ // since that gets handled by leave().
+ nelems = n;
+ }
- public Iterable<Symbol> getElementsByName(Name name) {
- return getElementsByName(name, noFilter);
- }
+ /** Enter symbol sym in this scope.
+ */
+ public void enter(Symbol sym) {
+ Assert.check(shared == 0);
+ if (nelems * 3 >= hashMask * 2)
+ dble();
+ int hash = getIndex(sym.name);
+ Entry old = table[hash];
+ if (old == null) {
+ old = sentinel;
+ nelems++;
+ }
+ Entry e = new Entry(sym, old, elems, this);
+ table[hash] = e;
+ elems = e;
- public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
- return new Iterable<Symbol>() {
- public Iterator<Symbol> iterator() {
- return new Iterator<Symbol>() {
- Scope.Entry currentEntry = lookup(name, sf);
+ //notify listeners
+ for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
+ l.head.symbolAdded(sym, this);
+ }
+ }
- public boolean hasNext() {
- return currentEntry.scope != null;
- }
- public Symbol next() {
- Scope.Entry prevEntry = currentEntry;
- currentEntry = currentEntry.next(sf);
- return prevEntry.sym;
- }
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
+ /** Remove symbol from this scope. Used when an inner class
+ * attribute tells us that the class isn't a package member.
+ */
+ public void remove(Symbol sym) {
+ Assert.check(shared == 0);
+ Entry e = lookup(sym.name);
+ if (e.scope == null) return;
+
+ // remove e from table and shadowed list;
+ int i = getIndex(sym.name);
+ Entry te = table[i];
+ if (te == e)
+ table[i] = e.shadowed;
+ else while (true) {
+ if (te.shadowed == e) {
+ te.shadowed = e.shadowed;
+ break;
+ }
+ te = te.shadowed;
}
- };
- }
- public String toString() {
- StringBuilder result = new StringBuilder();
- result.append("Scope[");
- for (Scope s = this; s != null ; s = s.next) {
- if (s != this) result.append(" | ");
- for (Entry e = s.elems; e != null; e = e.sibling) {
- if (e != s.elems) result.append(", ");
- result.append(e.sym);
+ // remove e from elems and sibling list
+ te = elems;
+ if (te == e)
+ elems = e.sibling;
+ else while (true) {
+ if (te.sibling == e) {
+ te.sibling = e.sibling;
+ break;
+ }
+ te = te.sibling;
+ }
+
+ //notify listeners
+ for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
+ l.head.symbolRemoved(sym, this);
}
}
- result.append("]");
- return result.toString();
+
+ /** Enter symbol sym in this scope if not already there.
+ */
+ public void enterIfAbsent(Symbol sym) {
+ Assert.check(shared == 0);
+ Entry e = lookup(sym.name);
+ while (e.scope == this && e.sym.kind != sym.kind) e = e.next();
+ if (e.scope != this) enter(sym);
+ }
+
+ /** Given a class, is there already a class with same fully
+ * qualified name in this (import) scope?
+ */
+ public boolean includes(Symbol c) {
+ for (Scope.Entry e = lookup(c.name);
+ e.scope == this;
+ e = e.next()) {
+ if (e.sym == c) return true;
+ }
+ return false;
+ }
+
+ /** Return the entry associated with given name, starting in
+ * this scope and proceeding outwards. If no entry was found,
+ * return the sentinel, which is characterized by having a null in
+ * both its scope and sym fields, whereas both fields are non-null
+ * for regular entries.
+ */
+ protected Entry lookup(Name name) {
+ return lookup(name, noFilter);
+ }
+
+ protected Entry lookup(Name name, Filter<Symbol> sf) {
+ Entry e = table[getIndex(name)];
+ if (e == null || e == sentinel)
+ return sentinel;
+ while (e.scope != null && (e.sym.name != name || (sf != null && !sf.accepts(e.sym))))
+ e = e.shadowed;
+ return e;
+ }
+
+ public Symbol findFirst(Name name, Filter<Symbol> sf) {
+ return lookup(name, sf).sym;
+ }
+
+ /*void dump (java.io.PrintStream out) {
+ out.println(this);
+ for (int l=0; l < table.length; l++) {
+ Entry le = table[l];
+ out.print("#"+l+": ");
+ if (le==sentinel) out.println("sentinel");
+ else if(le == null) out.println("null");
+ else out.println(""+le+" s:"+le.sym);
+ }
+ }*/
+
+ /** Look for slot in the table.
+ * We use open addressing with double hashing.
+ */
+ int getIndex (Name name) {
+ int h = name.hashCode();
+ int i = h & hashMask;
+ // The expression below is always odd, so it is guaranteed
+ // to be mutually prime with table.length, a power of 2.
+ int x = hashMask - ((h + (h >> 16)) << 1);
+ int d = -1; // Index of a deleted item.
+ for (;;) {
+ Entry e = table[i];
+ if (e == null)
+ return d >= 0 ? d : i;
+ if (e == sentinel) {
+ // We have to keep searching even if we see a deleted item.
+ // However, remember the index in case we fail to find the name.
+ if (d < 0)
+ d = i;
+ } else if (e.sym.name == name)
+ return i;
+ i = (i + x) & hashMask;
+ }
+ }
+
+ public boolean anyMatch(Filter<Symbol> sf) {
+ return getSymbols(sf, NON_RECURSIVE).iterator().hasNext();
+ }
+
+ public Iterable<Symbol> getSymbols(final Filter<Symbol> sf,
+ final LookupKind lookupKind) {
+ return new Iterable<Symbol>() {
+ public Iterator<Symbol> iterator() {
+ return new Iterator<Symbol>() {
+ private ScopeImpl currScope = ScopeImpl.this;
+ private Scope.Entry currEntry = elems;
+ {
+ update();
+ }
+
+ public boolean hasNext() {
+ return currEntry != null;
+ }
+
+ public Symbol next() {
+ Symbol sym = (currEntry == null ? null : currEntry.sym);
+ if (currEntry != null) {
+ currEntry = currEntry.sibling;
+ }
+ update();
+ return sym;
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ private void update() {
+ skipToNextMatchingEntry();
+ if (lookupKind == RECURSIVE) {
+ while (currEntry == null && currScope.next != null) {
+ currScope = currScope.next;
+ currEntry = currScope.elems;
+ skipToNextMatchingEntry();
+ }
+ }
+ }
+
+ void skipToNextMatchingEntry() {
+ while (currEntry != null && sf != null && !sf.accepts(currEntry.sym)) {
+ currEntry = currEntry.sibling;
+ }
+ }
+ };
+ }
+ };
+ }
+
+ public Iterable<Symbol> getSymbolsByName(final Name name,
+ final Filter<Symbol> sf,
+ final LookupKind lookupKind) {
+ return new Iterable<Symbol>() {
+ public Iterator<Symbol> iterator() {
+ return new Iterator<Symbol>() {
+ Scope.Entry currentEntry = lookup(name, sf);
+
+ public boolean hasNext() {
+ return currentEntry.scope != null &&
+ (lookupKind == RECURSIVE ||
+ currentEntry.scope == ScopeImpl.this);
+ }
+ public Symbol next() {
+ Scope.Entry prevEntry = currentEntry;
+ currentEntry = currentEntry.next(sf);
+ return prevEntry.sym;
+ }
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ };
+ }
+ };
+ }
+
+ public Scope getOrigin(Symbol s) {
+ for (Scope.Entry e = lookup(s.name); e.scope != null ; e = e.next()) {
+ if (e.sym == s) {
+ return this;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean isStaticallyImported(Symbol s) {
+ return false;
+ }
+
+ public String toString() {
+ StringBuilder result = new StringBuilder();
+ result.append("Scope[");
+ for (ScopeImpl s = this; s != null ; s = s.next) {
+ if (s != this) result.append(" | ");
+ for (Entry e = s.elems; e != null; e = e.sibling) {
+ if (e != s.elems) result.append(", ");
+ result.append(e.sym);
+ }
+ }
+ result.append("]");
+ return result.toString();
+ }
}
/** A class for scope entries.
*/
- public static class Entry {
+ private static class Entry {
/** The referenced symbol.
* sym == null iff this == sentinel
@@ -475,8 +623,6 @@
/** The entry's scope.
* scope == null iff this == sentinel
- * for an entry in an import scope, this is the scope
- * where the entry came from (i.e. was imported from).
*/
public Scope scope;
@@ -495,101 +641,201 @@
}
public Entry next(Filter<Symbol> sf) {
- if (shadowed.sym == null || sf.accepts(shadowed.sym)) return shadowed;
+ if (shadowed.sym == null || sf == null || sf.accepts(shadowed.sym)) return shadowed;
else return shadowed.next(sf);
}
- public boolean isStaticallyImported() {
- return false;
+ }
+
+ public static class NamedImportScope extends CompoundScope {
+
+ public NamedImportScope(Symbol owner, Scope currentFileScope) {
+ super(owner);
+ prependSubScope(currentFileScope);
+ }
+
+ public void importByName(Scope delegate, Scope origin, Name name, ImportFilter filter) {
+ appendScope(new FilterImportScope(delegate, origin, name, filter, true));
+ }
+
+ public void importType(Scope delegate, Scope origin, Symbol sym) {
+ appendScope(new SingleEntryScope(delegate.owner, sym, origin));
+ }
+
+ private void appendScope(Scope newScope) {
+ List<Scope> existingScopes = this.subScopes.reverse();
+ subScopes = List.of(existingScopes.head);
+ subScopes = subScopes.prepend(newScope);
+ for (Scope s : existingScopes.tail) {
+ subScopes = subScopes.prepend(s);
+ }
}
- public Scope getOrigin() {
- // The origin is only recorded for import scopes. For all
- // other scope entries, the "enclosing" type is available
- // from other sources. See Attr.visitSelect and
- // Attr.visitIdent. Rather than throwing an assertion
- // error, we return scope which will be the same as origin
- // in many cases.
- return scope;
+ private static class SingleEntryScope extends Scope {
+
+ private final Symbol sym;
+ private final List<Symbol> content;
+ private final Scope origin;
+
+ public SingleEntryScope(Symbol owner, Symbol sym, Scope origin) {
+ super(owner);
+ this.sym = sym;
+ this.content = List.of(sym);
+ this.origin = origin;
+ }
+
+ @Override
+ public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
+ return sf == null || sf.accepts(sym) ? content : Collections.<Symbol>emptyList();
+ }
+
+ @Override
+ public Iterable<Symbol> getSymbolsByName(Name name,
+ Filter<Symbol> sf,
+ LookupKind lookupKind) {
+ return sym.name == name &&
+ (sf == null || sf.accepts(sym)) ? content : Collections.<Symbol>emptyList();
+ }
+
+ @Override
+ public Scope getOrigin(Symbol byName) {
+ return sym == byName ? origin : null;
+ }
+
+ @Override
+ public boolean isStaticallyImported(Symbol byName) {
+ return false;
+ }
+
}
}
- public static class ImportScope extends Scope {
-
- public ImportScope(Symbol owner) {
- super(owner);
- }
-
- @Override
- Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope,
- final Scope origin, final boolean staticallyImported) {
- return new Entry(sym, shadowed, sibling, scope) {
- @Override
- public Scope getOrigin() {
- return origin;
- }
-
- @Override
- public boolean isStaticallyImported() {
- return staticallyImported;
- }
- };
- }
- }
-
- public static class StarImportScope extends ImportScope implements ScopeListener {
+ public static class StarImportScope extends CompoundScope {
public StarImportScope(Symbol owner) {
super(owner);
}
- public void importAll (Scope fromScope) {
- for (Scope.Entry e = fromScope.elems; e != null; e = e.sibling) {
- if (e.sym.kind == Kinds.TYP && !includes(e.sym))
- enter(e.sym, fromScope);
+ public void importAll(Scope delegate,
+ Scope origin,
+ ImportFilter filter,
+ boolean staticImport) {
+ for (Scope existing : subScopes) {
+ Assert.check(existing instanceof FilterImportScope);
+ FilterImportScope fis = (FilterImportScope) existing;
+ if (fis.delegate == delegate && fis.origin == origin &&
+ fis.filter == filter && fis.staticImport == staticImport)
+ return ; //avoid entering the same scope twice
}
- // Register to be notified when imported items are removed
- fromScope.addScopeListener(this);
+ prependSubScope(new FilterImportScope(delegate, origin, null, filter, staticImport));
}
- public void symbolRemoved(Symbol sym, Scope s) {
- remove(sym);
- }
- public void symbolAdded(Symbol sym, Scope s) { }
+ }
+
+ public interface ImportFilter {
+ public boolean accepts(Scope origin, Symbol sym);
}
- /** An empty scope, into which you can't place anything. Used for
- * the scope for a variable initializer.
- */
- public static class DelegatedScope extends Scope {
- Scope delegatee;
- public static final Entry[] emptyTable = new Entry[0];
+ private static class FilterImportScope extends Scope {
+
+ private final Scope delegate;
+ private final Scope origin;
+ private final Name filterName;
+ private final ImportFilter filter;
+ private final boolean staticImport;
+
+ public FilterImportScope(Scope delegate,
+ Scope origin,
+ Name filterName,
+ ImportFilter filter,
+ boolean staticImport) {
+ super(delegate.owner);
+ this.delegate = delegate;
+ this.origin = origin;
+ this.filterName = filterName;
+ this.filter = filter;
+ this.staticImport = staticImport;
+ }
- public DelegatedScope(Scope outer) {
- super(outer, outer.owner, emptyTable);
- delegatee = outer;
+ @Override
+ public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
+ if (filterName != null)
+ return getSymbolsByName(filterName, sf, lookupKind);
+ return new FilteredIterable(delegate.getSymbols(sf, lookupKind));
}
- public Scope dup() {
- return new DelegatedScope(next);
+
+ @Override
+ public Iterable<Symbol> getSymbolsByName(Name name,
+ Filter<Symbol> sf,
+ LookupKind lookupKind) {
+ if (filterName != null && filterName != name)
+ return Collections.emptyList();
+ return new FilteredIterable(delegate.getSymbolsByName(name, sf, lookupKind));
+ }
+
+ @Override
+ public Scope getOrigin(Symbol byName) {
+ return origin;
+ }
+
+ @Override
+ public boolean isStaticallyImported(Symbol byName) {
+ return staticImport;
}
- public Scope dupUnshared() {
- return new DelegatedScope(next);
- }
- public Scope leave() {
- return next;
- }
- public void enter(Symbol sym) {
- // only anonymous classes could be put here
+
+ private class FilteredIterator implements Iterator<Symbol> {
+ private final Iterator<Symbol> delegate;
+ private Symbol next;
+
+ public FilteredIterator(Iterator<Symbol> delegate) {
+ this.delegate = delegate;
+ update();
+ }
+
+ void update() {
+ while (delegate.hasNext()) {
+ if (filter.accepts(origin, next = delegate.next()))
+ return;
+ }
+
+ next = null;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return next != null;
+ }
+
+ @Override
+ public Symbol next() {
+ Symbol result = next;
+
+ update();
+
+ return result;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
}
- public void enter(Symbol sym, Scope s) {
- // only anonymous classes could be put here
+
+ private class FilteredIterable implements Iterable<Symbol> {
+
+ private final Iterable<Symbol> unfiltered;
+
+ public FilteredIterable(Iterable<Symbol> unfiltered) {
+ this.unfiltered = unfiltered;
+ }
+
+ @Override
+ public Iterator<Symbol> iterator() {
+ return new FilteredIterator(unfiltered.iterator());
+ }
}
- public void remove(Symbol sym) {
- throw new AssertionError(sym);
- }
- public Entry lookup(Name name) {
- return delegatee.lookup(name);
- }
+
}
/** A class scope adds capabilities to keep track of changes in related
@@ -600,16 +846,14 @@
*/
public static class CompoundScope extends Scope implements ScopeListener {
- public static final Entry[] emptyTable = new Entry[0];
-
- private List<Scope> subScopes = List.nil();
+ List<Scope> subScopes = List.nil();
private int mark = 0;
public CompoundScope(Symbol owner) {
- super(null, owner, emptyTable);
+ super(owner);
}
- public void addSubScope(Scope that) {
+ public void prependSubScope(Scope that) {
if (that != null) {
subScopes = subScopes.prepend(that);
that.addScopeListener(this);
@@ -618,7 +862,7 @@
sl.symbolAdded(null, this); //propagate upwards in case of nested CompoundScopes
}
}
- }
+ }
public void symbolAdded(Symbol sym, Scope s) {
mark++;
@@ -653,12 +897,13 @@
}
@Override
- public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
+ public Iterable<Symbol> getSymbols(final Filter<Symbol> sf,
+ final LookupKind lookupKind) {
return new Iterable<Symbol>() {
public Iterator<Symbol> iterator() {
return new CompoundScopeIterator(subScopes) {
Iterator<Symbol> nextIterator(Scope s) {
- return s.getElements(sf).iterator();
+ return s.getSymbols(sf, lookupKind).iterator();
}
};
}
@@ -666,18 +911,40 @@
}
@Override
- public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
+ public Iterable<Symbol> getSymbolsByName(final Name name,
+ final Filter<Symbol> sf,
+ final LookupKind lookupKind) {
return new Iterable<Symbol>() {
public Iterator<Symbol> iterator() {
return new CompoundScopeIterator(subScopes) {
Iterator<Symbol> nextIterator(Scope s) {
- return s.getElementsByName(name, sf).iterator();
+ return s.getSymbolsByName(name, sf, lookupKind).iterator();
}
};
}
};
}
+ @Override
+ public Scope getOrigin(Symbol sym) {
+ for (Scope delegate : subScopes) {
+ if (delegate.includes(sym))
+ return delegate.getOrigin(sym);
+ }
+
+ return null;
+ }
+
+ @Override
+ public boolean isStaticallyImported(Symbol sym) {
+ for (Scope delegate : subScopes) {
+ if (delegate.includes(sym))
+ return delegate.isStaticallyImported(sym);
+ }
+
+ return false;
+ }
+
abstract class CompoundScopeIterator implements Iterator<Symbol> {
private Iterator<Symbol> currentIterator;
@@ -715,41 +982,21 @@
currentIterator = null;
}
}
-
- @Override
- public Entry lookup(Name name, Filter<Symbol> sf) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public Scope dup(Symbol newOwner) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void enter(Symbol sym, Scope s, Scope origin, boolean staticallyImported) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public void remove(Symbol sym) {
- throw new UnsupportedOperationException();
- }
}
/** An error scope, for which the owner should be an error symbol. */
- public static class ErrorScope extends Scope {
- ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {
+ public static class ErrorScope extends ScopeImpl {
+ ErrorScope(ScopeImpl next, Symbol errSymbol, Entry[] table) {
super(next, /*owner=*/errSymbol, table);
}
public ErrorScope(Symbol errSymbol) {
super(errSymbol);
}
- public Scope dup() {
- return new ErrorScope(this, owner, table);
+ public WriteableScope dup(Symbol newOwner) {
+ return new ErrorScope(this, newOwner, table);
}
- public Scope dupUnshared() {
- return new ErrorScope(this, owner, table.clone());
+ public WriteableScope dupUnshared(Symbol newOwner) {
+ return new ErrorScope(this, newOwner, table.clone());
}
public Entry lookup(Name name) {
Entry e = super.lookup(name);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Jul 10 12:39:26 2014 -0700
@@ -33,19 +33,21 @@
import javax.lang.model.element.*;
import javax.tools.JavaFileObject;
+import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.comp.Attr;
import com.sun.tools.javac.comp.AttrContext;
import com.sun.tools.javac.comp.Env;
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.Name;
import static com.sun.tools.javac.code.Flags.*;
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.FORALL;
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
* for specific sorts of symbols, such as variables, methods and operators,
@@ -376,7 +378,7 @@
/** If this is a class or package, its members, otherwise null.
*/
- public Scope members() {
+ public WriteableScope members() {
return null;
}
@@ -475,15 +477,13 @@
if (currentClass == owner) {
return this;
}
- Scope.Entry e = currentClass.members().lookup(name);
- while (e.scope != null) {
- if (e.sym.kind == kind &&
+ for (Symbol sym : currentClass.members().getSymbolsByName(name)) {
+ if (sym.kind == kind &&
(kind != MTH ||
- (e.sym.flags() & STATIC) != 0 &&
- types.isSubSignature(e.sym.type, type))) {
- return e.sym;
+ (sym.flags() & STATIC) != 0 &&
+ types.isSubSignature(sym.type, type))) {
+ return sym;
}
- e = e.next();
}
Symbol hiddenSym = null;
for (Type st : types.interfaces(currentClass.type)
@@ -632,7 +632,7 @@
public boolean isConstructor() { return other.isConstructor(); }
public Name getQualifiedName() { return other.getQualifiedName(); }
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 hasOuterInstance() { return other.hasOuterInstance(); }
public ClassSymbol enclClass() { return other.enclClass(); }
@@ -721,9 +721,9 @@
if (kind == TYP && type.hasTag(TYPEVAR)) {
return list;
}
- for (Scope.Entry e = members().elems; e != null; e = e.sibling) {
- if (e.sym != null && (e.sym.flags() & SYNTHETIC) == 0 && e.sym.owner == this)
- list = list.prepend(e.sym);
+ for (Symbol sym : members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && (sym.flags() & SYNTHETIC) == 0 && sym.owner == this)
+ list = list.prepend(sym);
}
return list;
}
@@ -818,7 +818,7 @@
public static class PackageSymbol extends TypeSymbol
implements PackageElement {
- public Scope members_field;
+ public WriteableScope members_field;
public Name fullname;
public ClassSymbol package_info; // see bug 6443073
@@ -845,7 +845,7 @@
return name.isEmpty() && owner != null;
}
- public Scope members() {
+ public WriteableScope members() {
if (completer != null) complete();
return members_field;
}
@@ -910,7 +910,7 @@
/** a scope for all class members; variables, methods and inner classes
* 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.
* null for anonymous classes
@@ -971,7 +971,7 @@
return flags_field;
}
- public Scope members() {
+ public WriteableScope members() {
if (completer != null) complete();
return members_field;
}
@@ -1397,15 +1397,13 @@
public Symbol implementedIn(TypeSymbol c, Types types) {
Symbol impl = null;
- for (Scope.Entry e = c.members().lookup(name);
- impl == null && e.scope != null;
- e = e.next()) {
- if (this.overrides(e.sym, (TypeSymbol)owner, types, true) &&
+ for (Symbol sym : c.members().getSymbolsByName(name)) {
+ if (this.overrides(sym, (TypeSymbol)owner, types, true) &&
// FIXME: I suspect the following requires a
// subst() for a parametric return type.
types.isSameType(type.getReturnType(),
- types.memberType(owner.type, e.sym).getReturnType())) {
- impl = e.sym;
+ types.memberType(owner.type, sym).getReturnType())) {
+ impl = sym;
}
}
return impl;
@@ -1441,12 +1439,10 @@
*/
public MethodSymbol binaryImplementation(ClassSymbol origin, Types types) {
for (TypeSymbol c = origin; c != null; c = types.supertype(c.type).tsym) {
- for (Scope.Entry e = c.members().lookup(name);
- e.scope != null;
- e = e.next()) {
- if (e.sym.kind == MTH &&
- ((MethodSymbol)e.sym).binaryOverrides(this, origin, types))
- return (MethodSymbol)e.sym;
+ for (Symbol sym : c.members().getSymbolsByName(name)) {
+ if (sym.kind == MTH &&
+ ((MethodSymbol)sym).binaryOverrides(this, origin, types))
+ return (MethodSymbol)sym;
}
}
return null;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symtab.java Thu Jul 10 12:39:26 2014 -0700
@@ -34,6 +34,7 @@
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.Completer;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
@@ -396,7 +397,7 @@
sym.completer = null;
sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
sym.erasure_field = type;
- sym.members_field = new Scope(sym);
+ sym.members_field = WriteableScope.create(sym);
type.typarams_field = List.nil();
type.allparams_field = List.nil();
type.supertype_field = annotationType;
@@ -466,7 +467,7 @@
// Create class to hold all predefined constants and operations.
predefClass = new ClassSymbol(PUBLIC|ACYCLIC, names.empty, rootPackage);
- Scope scope = new Scope(predefClass);
+ WriteableScope scope = WriteableScope.create(predefClass);
predefClass.members_field = scope;
// Get the initial completer for Symbols from the ClassFinder
@@ -578,7 +579,7 @@
ClassType arrayClassType = (ClassType)arrayClass.type;
arrayClassType.supertype_field = objectType;
arrayClassType.interfaces_field = List.of(cloneableType, serializableType);
- arrayClass.members_field = new Scope(arrayClass);
+ arrayClass.members_field = WriteableScope.create(arrayClass);
lengthVar = new VarSymbol(
PUBLIC | FINAL,
names.length,
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java Thu Jul 10 12:39:26 2014 -0700
@@ -1050,6 +1050,10 @@
public <R, P> R accept(TypeVisitor<R, P> v, P p) {
return v.visitUnion(this, p);
}
+
+ public Iterable<? extends Type> getAlternativeTypes() {
+ return alternatives_field;
+ }
}
// a clone of a ClassType that knows about the bounds of an intersection type.
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Jul 10 12:39:26 2014 -0700
@@ -403,7 +403,7 @@
}
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);
if (abstracts.isEmpty() ||
(sym.name == abstracts.first().name &&
@@ -633,7 +633,7 @@
Type descType = findDescriptorType(targets.head);
ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass());
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);
csym.members_field.enter(instDescSym);
Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym,
@@ -655,7 +655,7 @@
Symbol descSym = findDescriptorSymbol(origin);
CompoundScope members = membersClosure(origin.type, false);
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;
else if (descSym.overrides(m2, origin, Types.this, false)) {
for (Symbol m3 : overridden) {
@@ -1312,7 +1312,8 @@
UndetVar undetvar = (UndetVar)t;
WildcardType wt = (WildcardType)s;
switch(wt.kind) {
- case UNBOUND: //similar to ? extends Object
+ case UNBOUND:
+ break;
case EXTENDS: {
Type bound = wildUpperBound(s);
undetvar.addBound(InferenceBound.UPPER, bound, this);
@@ -2289,7 +2290,7 @@
bc.erasure_field = (bounds.head.hasTag(TYPEVAR)) ?
syms.objectType : // error condition, recover
erasure(firstExplicitBound);
- bc.members_field = new Scope(bc);
+ bc.members_field = WriteableScope.create(bc);
return bc.type;
}
@@ -2618,8 +2619,8 @@
}
public boolean overridesObjectMethod(TypeSymbol origin, Symbol msym) {
- for (Scope.Entry e = syms.objectType.tsym.members().lookup(msym.name) ; e.scope != null ; e = e.next()) {
- if (msym.overrides(e.sym, origin, Types.this, true)) {
+ for (Symbol sym : syms.objectType.tsym.members().getSymbolsByName(msym.name)) {
+ if (msym.overrides(sym, origin, Types.this, true)) {
return true;
}
}
@@ -2679,12 +2680,10 @@
while (t.hasTag(TYPEVAR))
t = t.getUpperBound();
TypeSymbol c = t.tsym;
- for (Scope.Entry e = c.members().lookup(ms.name, implFilter);
- e.scope != null;
- e = e.next(implFilter)) {
- if (e.sym != null &&
- e.sym.overrides(ms, origin, Types.this, checkResult))
- return (MethodSymbol)e.sym;
+ for (Symbol sym : c.members().getSymbolsByName(ms.name, implFilter)) {
+ if (sym != null &&
+ sym.overrides(ms, origin, Types.this, checkResult))
+ return (MethodSymbol)sym;
}
}
return null;
@@ -2741,11 +2740,11 @@
CompoundScope membersClosure = new CompoundScope(csym);
if (!skipInterface) {
for (Type i : interfaces(t)) {
- membersClosure.addSubScope(visit(i, skipInterface));
+ membersClosure.prependSubScope(visit(i, skipInterface));
}
}
- membersClosure.addSubScope(visit(supertype(t), skipInterface));
- membersClosure.addSubScope(csym.members());
+ membersClosure.prependSubScope(visit(supertype(t), skipInterface));
+ membersClosure.prependSubScope(csym.members());
e = new Entry(skipInterface, membersClosure);
_map.put(csym, e);
}
@@ -2774,7 +2773,7 @@
public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
Filter<Symbol> filter = new MethodFilter(ms, site);
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()) {
return List.of((MethodSymbol)s);
} else if (!candidates.contains(s)) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java Thu Jul 10 12:39:26 2014 -0700
@@ -690,7 +690,7 @@
Scope scope = targetContainerType.tsym.members();
int nr_value_elems = 0;
boolean error = false;
- for(Symbol elm : scope.getElementsByName(names.value)) {
+ for(Symbol elm : scope.getSymbolsByName(names.value)) {
nr_value_elems++;
if (nr_value_elems == 1 &&
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
import com.sun.source.util.SimpleTreeVisitor;
import com.sun.tools.javac.code.*;
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.Type.*;
import com.sun.tools.javac.comp.Check.CheckContext;
@@ -618,14 +619,11 @@
return newEnv;
}
- Scope copyScope(Scope sc) {
- Scope newScope = new Scope(sc.owner);
+ WriteableScope copyScope(WriteableScope sc) {
+ WriteableScope newScope = WriteableScope.create(sc.owner);
List<Symbol> elemsList = List.nil();
- while (sc != null) {
- for (Scope.Entry e = sc.elems ; e != null ; e = e.sibling) {
- elemsList = elemsList.prepend(e.sym);
- }
- sc = sc.next;
+ for (Symbol sym : sc.getSymbols()) {
+ elemsList = elemsList.prepend(sym);
}
for (Symbol s : elemsList) {
newScope.enter(s);
@@ -1140,12 +1138,12 @@
// Block is a static or instance initializer;
// let the owner of the environment be a freshly
// created BLOCK-method.
- final Env<AttrContext> localEnv =
- env.dup(tree, env.info.dup(env.info.scope.dupUnshared()));
- localEnv.info.scope.owner =
+ Symbol fakeOwner =
new MethodSymbol(tree.flags | BLOCK |
env.info.scope.owner.flags() & STRICTFP, names.empty, null,
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++;
attribStats(tree.stats, localEnv);
@@ -1328,7 +1326,7 @@
}
// where
/** 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) {
JCTree stat = stats.head;
if (stat.hasTag(VARDEF))
@@ -1344,10 +1342,9 @@
}
JCIdent ident = (JCIdent)tree;
Name name = ident.name;
- for (Scope.Entry e = enumType.tsym.members().lookup(name);
- e.scope != null; e = e.next()) {
- if (e.sym.kind == VAR) {
- Symbol s = ident.sym = e.sym;
+ for (Symbol sym : enumType.tsym.members().getSymbolsByName(name)) {
+ if (sym.kind == VAR) {
+ Symbol s = ident.sym = sym;
((VarSymbol)s).getConstValue(); // ensure initializer is evaluated
ident.type = s.type;
return ((s.flags_field & Flags.ENUM) == 0)
@@ -2343,7 +2340,7 @@
Symbol descriptor = types.findDescriptorSymbol(clazztype.tsym);
int count = 0;
boolean found = false;
- for (Symbol sym : csym.members().getElements()) {
+ for (Symbol sym : csym.members().getSymbols()) {
if ((sym.flags() & SYNTHETIC) != 0 ||
sym.isConstructor()) continue;
count++;
@@ -2774,15 +2771,15 @@
Symbol owner = env.info.scope.owner;
if (owner.kind == VAR && owner.owner.kind == TYP) {
//field initializer
- lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared()));
ClassSymbol enclClass = owner.enclClass();
+ Symbol newScopeOwner = env.info.scope.owner;
/* 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
* LTM code is doing to look for type annotations so we are fine.
*/
if ((owner.flags() & STATIC) == 0) {
- for (Symbol s : enclClass.members_field.getElementsByName(names.init)) {
- lambdaEnv.info.scope.owner = s;
+ for (Symbol s : enclClass.members_field.getSymbolsByName(names.init)) {
+ newScopeOwner = s;
break;
}
} else {
@@ -2798,8 +2795,9 @@
clinit.params = List.<VarSymbol>nil();
clinits.put(enclClass, clinit);
}
- lambdaEnv.info.scope.owner = clinit;
+ newScopeOwner = clinit;
}
+ lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dupUnshared(newScopeOwner)));
} else {
lambdaEnv = env.dup(that, env.info.dup(env.info.scope.dup()));
}
@@ -4515,7 +4513,7 @@
for (List<JCTypeParameter> l = tree.typarams;
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
@@ -4602,16 +4600,21 @@
private void checkSerialVersionUID(JCClassDecl tree, ClassSymbol c) {
// check for presence of serialVersionUID
- Scope.Entry e = c.members().lookup(names.serialVersionUID);
- while (e.scope != null && e.sym.kind != VAR) e = e.next();
- if (e.scope == null) {
+ VarSymbol svuid = null;
+ for (Symbol sym : c.members().getSymbolsByName(names.serialVersionUID)) {
+ if (sym.kind == VAR) {
+ svuid = (VarSymbol)sym;
+ break;
+ }
+ }
+
+ if (svuid == null) {
log.warning(LintCategory.SERIAL,
tree.pos(), "missing.SVUID", c);
return;
}
// check that it is static final
- VarSymbol svuid = (VarSymbol)e.sym;
if ((svuid.flags() & (STATIC | FINAL)) !=
(STATIC | FINAL))
log.warning(LintCategory.SERIAL,
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Jul 10 12:39:26 2014 -0700
@@ -27,6 +27,7 @@
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Scope.WriteableScope;
/** Contains information specific to the attribute and enter
* passes, to be used in place of the generic field in environments.
@@ -40,7 +41,7 @@
/** The scope of local symbols.
*/
- Scope scope = null;
+ WriteableScope scope = null;
/** The number of enclosing `static' modifiers.
*/
@@ -87,7 +88,7 @@
/** Duplicate this context, replacing scope field and copying all others.
*/
- AttrContext dup(Scope scope) {
+ AttrContext dup(WriteableScope scope) {
AttrContext info = new AttrContext();
info.scope = scope;
info.staticLevel = staticLevel;
@@ -112,7 +113,7 @@
public Iterable<Symbol> getLocalElements() {
if (scope == null)
return List.nil();
- return scope.getElements();
+ return scope.getSymbols();
}
boolean lastResolveVarargs() {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
import java.util.*;
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Attribute.Compound;
@@ -39,6 +40,8 @@
import com.sun.tools.javac.code.Lint;
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.Symbol.*;
import com.sun.tools.javac.comp.DeferredAttr.DeferredAttrContext;
@@ -51,6 +54,7 @@
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.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.WILDCARD;
@@ -362,16 +366,13 @@
* @param s The scope.
*/
void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
- if (s.next != null) {
- for (Scope.Entry e = s.next.lookup(v.name);
- e.scope != null && e.sym.owner == v.owner;
- e = e.next()) {
- if (e.sym.kind == VAR &&
- (e.sym.owner.kind & (VAR | MTH)) != 0 &&
- v.name != names.error) {
- duplicateError(pos, e.sym);
- return;
- }
+ for (Symbol sym : s.getSymbolsByName(v.name)) {
+ if (sym.owner != v.owner) break;
+ if (sym.kind == VAR &&
+ (sym.owner.kind & (VAR | MTH)) != 0 &&
+ v.name != names.error) {
+ duplicateError(pos, sym);
+ return;
}
}
}
@@ -383,16 +384,13 @@
* @param s The scope.
*/
void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
- if (s.next != null) {
- for (Scope.Entry e = s.next.lookup(c.name);
- e.scope != null && e.sym.owner == c.owner;
- e = e.next()) {
- if (e.sym.kind == TYP && !e.sym.type.hasTag(TYPEVAR) &&
- (e.sym.owner.kind & (VAR | MTH)) != 0 &&
- c.name != names.error) {
- duplicateError(pos, e.sym);
- return;
- }
+ for (Symbol sym : s.getSymbolsByName(c.name)) {
+ if (sym.owner != c.owner) break;
+ if (sym.kind == TYP && !sym.type.hasTag(TYPEVAR) &&
+ (sym.owner.kind & (VAR | MTH)) != 0 &&
+ c.name != names.error) {
+ duplicateError(pos, sym);
+ return;
}
}
}
@@ -405,9 +403,9 @@
* @param s The enclosing scope.
*/
boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
- for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
- if (e.sym.kind == TYP && e.sym.name != names.error) {
- duplicateError(pos, e.sym);
+ for (Symbol sym : s.getSymbolsByName(name, NON_RECURSIVE)) {
+ if (sym.kind == TYP && sym.name != names.error) {
+ duplicateError(pos, sym);
return false;
}
}
@@ -1778,10 +1776,7 @@
for (Type t1 = sup;
t1.hasTag(CLASS) && t1.tsym.type.isParameterized();
t1 = types.supertype(t1)) {
- for (Scope.Entry e1 = t1.tsym.members().elems;
- e1 != null;
- e1 = e1.sibling) {
- Symbol s1 = e1.sym;
+ for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
if (s1.kind != MTH ||
(s1.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
!s1.isInheritedIn(site.tsym, types) ||
@@ -1796,10 +1791,7 @@
for (Type t2 = sup;
t2.hasTag(CLASS);
t2 = types.supertype(t2)) {
- for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name);
- e2.scope != null;
- e2 = e2.next()) {
- Symbol s2 = e2.sym;
+ for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
if (s2 == s1 ||
s2.kind != MTH ||
(s2.flags() & (STATIC|SYNTHETIC|BRIDGE)) != 0 ||
@@ -1893,15 +1885,13 @@
/** Return the first method in t2 that conflicts with a method from t1. */
private Symbol firstDirectIncompatibility(DiagnosticPosition pos, Type t1, Type t2, Type site) {
- for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
- Symbol s1 = e1.sym;
+ for (Symbol s1 : t1.tsym.members().getSymbols(NON_RECURSIVE)) {
Type st1 = null;
if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
(s1.flags() & SYNTHETIC) != 0) continue;
Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
- for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
- Symbol s2 = e2.sym;
+ for (Symbol s2 : t2.tsym.members().getSymbolsByName(s1.name)) {
if (s1 == s2) continue;
if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
(s2.flags() & SYNTHETIC) != 0) continue;
@@ -1944,8 +1934,7 @@
Type st2 = types.memberType(site, s2);
closure(site, supertypes);
for (Type t : supertypes.values()) {
- for (Scope.Entry e = t.tsym.members().lookup(s1.name); e.scope != null; e = e.next()) {
- Symbol s3 = e.sym;
+ for (Symbol s3 : t.tsym.members().getSymbolsByName(s1.name)) {
if (s3 == s1 || s3 == s2 || s3.kind != MTH || (s3.flags() & (BRIDGE|SYNTHETIC)) != 0) continue;
Type st3 = types.memberType(site,s3);
if (types.overrideEquivalent(st3, st1) &&
@@ -1995,14 +1984,12 @@
void checkOverride(JCTree tree, Type site, ClassSymbol origin, MethodSymbol m) {
TypeSymbol c = site.tsym;
- Scope.Entry e = c.members().lookup(m.name);
- while (e.scope != null) {
- if (m.overrides(e.sym, origin, types, false)) {
- if ((e.sym.flags() & ABSTRACT) == 0) {
- checkOverride(tree, m, (MethodSymbol)e.sym, origin);
+ for (Symbol sym : c.members().getSymbolsByName(m.name)) {
+ if (m.overrides(sym, origin, types, false)) {
+ if ((sym.flags() & ABSTRACT) == 0) {
+ checkOverride(tree, m, (MethodSymbol)sym, origin);
}
}
- e = e.next();
}
}
@@ -2037,9 +2024,9 @@
ClassSymbol someClass) {
if (lint.isEnabled(LintCategory.OVERRIDES)) {
MethodSymbol equalsAtObject = (MethodSymbol)syms.objectType
- .tsym.members().lookup(names.equals).sym;
+ .tsym.members().findFirst(names.equals);
MethodSymbol hashCodeAtObject = (MethodSymbol)syms.objectType
- .tsym.members().lookup(names.hashCode).sym;
+ .tsym.members().findFirst(names.hashCode);
boolean overridesEquals = types.implementation(equalsAtObject,
someClass, false, equalsHasCodeFilter).owner == someClass;
boolean overridesHashCode = types.implementation(hashCodeAtObject,
@@ -2095,12 +2082,10 @@
// since they cannot have abstract members.
if (c == impl || (c.flags() & (ABSTRACT | INTERFACE)) != 0) {
Scope s = c.members();
- for (Scope.Entry e = s.elems;
- undef == null && e != null;
- e = e.sibling) {
- if (e.sym.kind == MTH &&
- (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
- MethodSymbol absmeth = (MethodSymbol)e.sym;
+ for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == MTH &&
+ (sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
+ MethodSymbol absmeth = (MethodSymbol)sym;
MethodSymbol implmeth = absmeth.implementation(impl, types, true);
if (implmeth == null || implmeth == absmeth) {
//look for default implementations
@@ -2113,6 +2098,7 @@
}
if (implmeth == null || implmeth == absmeth) {
undef = absmeth;
+ break;
}
}
}
@@ -2336,10 +2322,10 @@
for (List<Type> l = types.closure(ic.type); l.nonEmpty(); l = l.tail) {
ClassSymbol lc = (ClassSymbol)l.head.tsym;
if ((allowGenerics || origin != lc) && (lc.flags() & ABSTRACT) != 0) {
- for (Scope.Entry e=lc.members().elems; e != null; e=e.sibling) {
- if (e.sym.kind == MTH &&
- (e.sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
- MethodSymbol absmeth = (MethodSymbol)e.sym;
+ for (Symbol sym : lc.members().getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == MTH &&
+ (sym.flags() & (STATIC|ABSTRACT)) == ABSTRACT) {
+ MethodSymbol absmeth = (MethodSymbol)sym;
MethodSymbol implmeth = absmeth.implementation(origin, types, false);
if (implmeth != null && implmeth != absmeth &&
(implmeth.owner.flags() & INTERFACE) ==
@@ -2382,15 +2368,15 @@
void checkConflicts(DiagnosticPosition pos, Symbol sym, TypeSymbol c) {
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
- if (sym.kind == e.sym.kind &&
- types.isSameType(types.erasure(sym.type), types.erasure(e.sym.type)) &&
- sym != e.sym &&
- (sym.flags() & Flags.SYNTHETIC) != (e.sym.flags() & Flags.SYNTHETIC) &&
- (sym.flags() & IPROXY) == 0 && (e.sym.flags() & IPROXY) == 0 &&
- (sym.flags() & BRIDGE) == 0 && (e.sym.flags() & BRIDGE) == 0) {
- syntheticError(pos, (e.sym.flags() & SYNTHETIC) == 0 ? e.sym : sym);
+ if (sym.kind == sym2.kind &&
+ types.isSameType(types.erasure(sym.type), types.erasure(sym2.type)) &&
+ sym != sym2 &&
+ (sym.flags() & Flags.SYNTHETIC) != (sym2.flags() & Flags.SYNTHETIC) &&
+ (sym.flags() & IPROXY) == 0 && (sym2.flags() & IPROXY) == 0 &&
+ (sym.flags() & BRIDGE) == 0 && (sym2.flags() & BRIDGE) == 0) {
+ syntheticError(pos, (sym2.flags() & SYNTHETIC) == 0 ? sym2 : sym);
return;
}
}
@@ -2411,7 +2397,7 @@
List<MethodSymbol> potentiallyAmbiguousList = List.nil();
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 (m1 == sym) {
continue;
@@ -2429,7 +2415,7 @@
}
//...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 (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
@@ -2466,7 +2452,7 @@
void checkHideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
ClashFilter cf = new ClashFilter(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
//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)) {
@@ -2508,7 +2494,7 @@
void checkDefaultMethodClashes(DiagnosticPosition pos, Type 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);
List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
if (prov.size() > 1) {
@@ -2772,11 +2758,11 @@
void validateAnnotationMethod(DiagnosticPosition pos, MethodSymbol m) {
for (Type sup = syms.annotationType; sup.hasTag(CLASS); sup = types.supertype(sup)) {
Scope s = sup.tsym.members();
- for (Scope.Entry e = s.lookup(m.name); e.scope != null; e = e.next()) {
- if (e.sym.kind == MTH &&
- (e.sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
- types.overrideEquivalent(m.type, e.sym.type))
- log.error(pos, "intf.annotation.member.clash", e.sym, sup);
+ for (Symbol sym : s.getSymbolsByName(m.name)) {
+ if (sym.kind == MTH &&
+ (sym.flags() & (PUBLIC | PROTECTED)) != 0 &&
+ types.overrideEquivalent(m.type, sym.type))
+ log.error(pos, "intf.annotation.member.clash", sym, sup);
}
}
}
@@ -2856,9 +2842,9 @@
}
private void validateValue(TypeSymbol container, TypeSymbol contained, DiagnosticPosition pos) {
- Scope.Entry e = container.members().lookup(names.value);
- if (e.scope != null && e.sym.kind == MTH) {
- MethodSymbol m = (MethodSymbol) e.sym;
+ Symbol sym = container.members().findFirst(names.value);
+ if (sym != null && sym.kind == MTH) {
+ MethodSymbol m = (MethodSymbol) sym;
Type ret = m.getReturnType();
if (!(ret.hasTag(ARRAY) && types.isSameType(((ArrayType)ret).elemtype, contained.type))) {
log.error(pos, "invalid.repeatable.annotation.value.return",
@@ -3003,7 +2989,7 @@
private void validateDefault(Symbol container, DiagnosticPosition pos) {
// validate that all other elements of containing type has defaults
Scope scope = container.members();
- for(Symbol elm : scope.getElements()) {
+ for(Symbol elm : scope.getSymbols()) {
if (elm.name != names.value &&
elm.kind == Kinds.MTH &&
((MethodSymbol)elm).defaultValue == null) {
@@ -3025,8 +3011,8 @@
if (sup == owner.type)
continue; // skip "this"
Scope scope = sup.tsym.members();
- for (Scope.Entry e = scope.lookup(m.name); e.scope != null; e = e.next()) {
- if (!e.sym.isStatic() && m.overrides(e.sym, owner, types, true))
+ for (Symbol sym : scope.getSymbolsByName(m.name)) {
+ if (!sym.isStatic() && m.overrides(sym, owner, types, true))
return true;
}
}
@@ -3160,12 +3146,10 @@
boolean isValid = true;
// collect an inventory of the annotation elements
Set<MethodSymbol> members = new LinkedHashSet<>();
- for (Scope.Entry e = a.annotationType.type.tsym.members().elems;
- e != null;
- e = e.sibling)
- if (e.sym.kind == MTH && e.sym.name != names.clinit &&
- (e.sym.flags() & SYNTHETIC) == 0)
- members.add((MethodSymbol) e.sym);
+ for (Symbol sym : a.annotationType.type.tsym.members().getSymbols(NON_RECURSIVE))
+ if (sym.kind == MTH && sym.name != names.clinit &&
+ (sym.flags() & SYNTHETIC) == 0)
+ members.add((MethodSymbol) sym);
// remove the ones that are assigned values
for (JCTree arg : a.args) {
@@ -3293,8 +3277,7 @@
}
try {
tsym.flags_field |= LOCKED;
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- Symbol s = e.sym;
+ for (Symbol s : tsym.members().getSymbols(NON_RECURSIVE)) {
if (s.kind != Kinds.MTH)
continue;
checkAnnotationResType(pos, ((MethodSymbol)s).type.getReturnType());
@@ -3436,23 +3419,23 @@
if (sym.type.isErroneous())
return true;
if (sym.owner.name == names.any) return false;
- for (Scope.Entry e = s.lookup(sym.name); e.scope == s; e = e.next()) {
- if (sym != e.sym &&
- (e.sym.flags() & CLASH) == 0 &&
- sym.kind == e.sym.kind &&
+ for (Symbol byName : s.getSymbolsByName(sym.name, NON_RECURSIVE)) {
+ if (sym != byName &&
+ (byName.flags() & CLASH) == 0 &&
+ sym.kind == byName.kind &&
sym.name != names.error &&
(sym.kind != MTH ||
- types.hasSameArgs(sym.type, e.sym.type) ||
- types.hasSameArgs(types.erasure(sym.type), types.erasure(e.sym.type)))) {
- if ((sym.flags() & VARARGS) != (e.sym.flags() & VARARGS)) {
- varargsDuplicateError(pos, sym, e.sym);
+ types.hasSameArgs(sym.type, byName.type) ||
+ types.hasSameArgs(types.erasure(sym.type), types.erasure(byName.type)))) {
+ if ((sym.flags() & VARARGS) != (byName.flags() & VARARGS)) {
+ varargsDuplicateError(pos, sym, byName);
return true;
- } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, e.sym.type, false)) {
- duplicateErasureError(pos, sym, e.sym);
+ } else if (sym.kind == MTH && !types.hasSameArgs(sym.type, byName.type, false)) {
+ duplicateErasureError(pos, sym, byName);
sym.flags_field |= CLASH;
return true;
} else {
- duplicateError(pos, e.sym);
+ duplicateError(pos, byName);
return false;
}
}
@@ -3471,47 +3454,50 @@
/** 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.
* @param pos Position for error reporting.
+ * @param toplevel The file in which in the check is performed.
* @param sym The symbol.
- * @param s The scope
*/
- boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s) {
- return checkUniqueImport(pos, sym, s, false);
+ boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
+ return checkUniqueImport(pos, toplevel, sym, false);
}
/** 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.
* @param pos Position for error reporting.
+ * @param toplevel The file in which in the check is performed.
* @param sym The symbol.
- * @param s The scope
*/
- boolean checkUniqueStaticImport(DiagnosticPosition pos, Symbol sym, Scope s) {
- return checkUniqueImport(pos, sym, s, true);
+ boolean checkUniqueStaticImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
+ return checkUniqueImport(pos, toplevel, sym, true);
}
/** 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.
* @param pos Position for error reporting.
+ * @param toplevel The file in which in the check is performed.
* @param sym The symbol.
- * @param s The scope.
* @param staticImport Whether or not this was a static import
*/
- private boolean checkUniqueImport(DiagnosticPosition pos, Symbol sym, Scope s, boolean staticImport) {
- for (Scope.Entry e = s.lookup(sym.name); e.scope != null; e = e.next()) {
+ private boolean checkUniqueImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym, boolean staticImport) {
+ NamedImportScope namedImportScope = toplevel.namedImportScope;
+ WriteableScope topLevelScope = toplevel.toplevelScope;
+
+ for (Symbol byName : namedImportScope.getSymbolsByName(sym.name)) {
// is encountered class entered via a class declaration?
- boolean isClassDecl = e.scope == s;
- if ((isClassDecl || sym != e.sym) &&
- sym.kind == e.sym.kind &&
+ boolean isClassDecl = namedImportScope.getOrigin(byName) == topLevelScope;
+ if ((isClassDecl || sym != byName) &&
+ sym.kind == byName.kind &&
sym.name != names.error &&
- (!staticImport || !e.isStaticallyImported())) {
- if (!e.sym.type.isErroneous()) {
+ (!staticImport || !namedImportScope.isStaticallyImported(byName))) {
+ if (!byName.type.isErroneous()) {
if (!isClassDecl) {
if (staticImport)
- log.error(pos, "already.defined.static.single.import", e.sym);
+ log.error(pos, "already.defined.static.single.import", byName);
else
- log.error(pos, "already.defined.single.import", e.sym);
+ log.error(pos, "already.defined.single.import", byName);
}
- else if (sym != e.sym)
- log.error(pos, "already.defined.this.unit", e.sym);
+ else if (sym != byName)
+ log.error(pos, "already.defined.this.unit", byName);
}
return false;
}
@@ -3610,4 +3596,68 @@
}
}
}
+
+ 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;
+ }
+ }
+
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java Thu Jul 10 12:39:26 2014 -0700
@@ -376,9 +376,8 @@
ResultInfo resultInfo,
Annotate.PositionCreator creator) {
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.scope.owner = env.info.scope.owner;
Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
new Log.DeferredDiagnosticHandler(log, new Filter<JCDiagnostic>() {
public boolean accepts(final JCDiagnostic d) {
@@ -517,13 +516,11 @@
}
}
if (!progress) {
- DeferredAttrContext dac = this;
- while (dac != emptyDeferredAttrContext) {
- if (dac.mode == AttrMode.SPECULATIVE) {
- //unsticking does not take place during overload
- break;
+ if (insideOverloadPhase()) {
+ for (DeferredAttrNode deferredNode: deferredAttrNodes) {
+ deferredNode.dt.tree.type = Type.noType;
}
- dac = dac.parent;
+ return;
}
//remove all variables that have already been instantiated
//from the list of stuck variables
@@ -539,6 +536,17 @@
}
}
}
+
+ private boolean insideOverloadPhase() {
+ DeferredAttrContext dac = this;
+ if (dac == emptyDeferredAttrContext) {
+ return false;
+ }
+ if (dac.mode == AttrMode.SPECULATIVE) {
+ return true;
+ }
+ return dac.parent.insideOverloadPhase();
+ }
}
/**
@@ -599,6 +607,8 @@
return false;
}
} else {
+ Assert.check(!deferredAttrContext.insideOverloadPhase(),
+ "attribution shouldn't be happening here");
ResultInfo instResultInfo =
resultInfo.dup(deferredAttrContext.inferenceContext.asInstType(resultInfo.pt));
dt.check(instResultInfo, dummyStuckPolicy, basicCompleter);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Enter.java Thu Jul 10 12:39:26 2014 -0700
@@ -191,7 +191,7 @@
*/
public Env<AttrContext> classEnv(JCClassDecl tree, Env<AttrContext> env) {
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.outer = env;
localEnv.info.isSelfCall = false;
@@ -207,9 +207,10 @@
Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
localEnv.toplevel = tree;
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);
- localEnv.info.scope = tree.namedImportScope;
+ localEnv.info.scope = tree.toplevelScope;
localEnv.info.lint = lint;
return localEnv;
}
@@ -218,7 +219,7 @@
Env<AttrContext> localEnv = new Env<>(tree, new AttrContext());
localEnv.toplevel = tree;
localEnv.enclClass = predefClassDef;
- localEnv.info.scope = tree.namedImportScope;
+ localEnv.info.scope = tree.toplevelScope;
localEnv.info.lint = lint;
return localEnv;
}
@@ -228,7 +229,7 @@
* where the local scope is for type variables, and the this and super symbol
* 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))
? ((JCClassDecl) env.tree).sym.members_field
: env.info.scope;
@@ -324,7 +325,7 @@
c.flatname = names.fromString(tree.packge + "." + name);
c.sourcefile = tree.sourcefile;
c.completer = null;
- c.members_field = new Scope(c);
+ c.members_field = WriteableScope.create(c);
tree.packge.package_info = c;
}
classEnter(tree.defs, topEnv);
@@ -338,7 +339,7 @@
@Override
public void visitClassDef(JCClassDecl tree) {
Symbol owner = env.info.scope.owner;
- Scope enclScope = enterScope(env);
+ WriteableScope enclScope = enterScope(env);
ClassSymbol c;
if (owner.kind == PCK) {
// We are seeing a toplevel class.
@@ -392,7 +393,7 @@
c.completer = memberEnter;
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
c.sourcefile = env.toplevel.sourcefile;
- c.members_field = new Scope(c);
+ c.members_field = WriteableScope.create(c);
ClassType ct = (ClassType)c.type;
if (owner.kind != PCK && (c.flags_field & STATIC) == 0) {
@@ -495,7 +496,7 @@
// if there remain any unimported toplevels (these must have
// no classes at all), process their import statements as well.
for (JCCompilationUnit tree : trees) {
- if (tree.starImportScope.elems == null) {
+ if (tree.starImportScope.isEmpty()) {
JavaFileObject prev = log.useSource(tree.sourcefile);
Env<AttrContext> topEnv = topLevelEnv(tree);
memberEnter.memberEnter(tree, topEnv);
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java Thu Jul 10 12:39:26 2014 -0700
@@ -30,6 +30,7 @@
import java.util.HashMap;
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.util.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -1419,7 +1420,7 @@
/** The list of unreferenced automatic resources.
*/
- Scope unrefdResources;
+ WriteableScope unrefdResources;
/** Set when processing a loop body the second time for DU analysis. */
FlowKind flowKind = FlowKind.NORMAL;
@@ -2410,7 +2411,7 @@
nextadr = 0;
pendingExits = new ListBuffer<>();
this.classDef = null;
- unrefdResources = new Scope(env.enclClass.sym);
+ unrefdResources = WriteableScope.create(env.enclClass.sym);
scan(tree);
} finally {
// note that recursive invocations of this method fail hard
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Jul 10 12:39:26 2014 -0700
@@ -31,7 +31,7 @@
import com.sun.tools.javac.tree.TreeTranslator;
import com.sun.tools.javac.code.Attribute;
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.ClassSymbol;
import com.sun.tools.javac.code.Symbol.DynamicMethodSymbol;
@@ -448,7 +448,7 @@
make.at(prevPos);
}
// Replace the entered symbol for this variable
- Scope sc = tree.sym.owner.members();
+ WriteableScope sc = tree.sym.owner.members();
if (sc != null) {
sc.remove(tree.sym);
sc.enter(xsym);
@@ -1475,7 +1475,7 @@
return clinit;
} else {
//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;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
import java.util.*;
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.main.Option.PkgInfo;
import com.sun.tools.javac.tree.*;
@@ -45,6 +46,7 @@
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Flags.BLOCK;
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.jvm.ByteCodes.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
@@ -299,7 +301,7 @@
Symbol sym = _sym;
if (sym.kind == VAR || sym.kind == MTH) {
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) {
VarSymbol v = (VarSymbol)sym;
if (v.getConstValue() == null) {
@@ -644,7 +646,7 @@
}
c.sourcefile = owner.sourcefile;
c.completer = null;
- c.members_field = new Scope(c);
+ c.members_field = WriteableScope.create(c);
c.flags_field = flags;
ClassType ctype = (ClassType) c.type;
ctype.supertype_field = syms.objectType;
@@ -678,7 +680,7 @@
* @param sym The symbol.
* @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);
}
@@ -746,7 +748,7 @@
* @param name The name.
*/
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;
}
@@ -901,11 +903,9 @@
/** Return binary operator that corresponds to given access code.
*/
private OperatorSymbol binaryAccessOperator(int acode) {
- for (Scope.Entry e = syms.predefClass.members().elems;
- e != null;
- e = e.sibling) {
- if (e.sym instanceof OperatorSymbol) {
- OperatorSymbol op = (OperatorSymbol)e.sym;
+ for (Symbol sym : syms.predefClass.members().getSymbols(NON_RECURSIVE)) {
+ if (sym instanceof OperatorSymbol) {
+ OperatorSymbol op = (OperatorSymbol)sym;
if (accessCode(op.opcode) == acode) return op;
}
}
@@ -1143,7 +1143,7 @@
return makeLit(sym.type, cv);
}
// 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);
tree = make.at(tree.pos).Ident(sym);
}
@@ -1459,12 +1459,12 @@
* in an additional innermost scope, where they represent the constructor
* parameters.
*/
- Scope proxies;
+ WriteableScope proxies;
/** A scope containing all unnamed resource variables/saved
* exception variables for translated TWR blocks
*/
- Scope twrVars;
+ WriteableScope twrVars;
/** A stack containing the this$n field of the currently translated
* classes (if needed) in innermost first order.
@@ -1519,7 +1519,7 @@
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());
return result;
}
@@ -1859,10 +1859,10 @@
* name is the name of a free variable.
*/
JCStatement initField(int pos, Name name) {
- Scope.Entry e = proxies.lookup(name);
- Symbol rhs = e.sym;
+ Iterator<Symbol> it = proxies.getSymbolsByName(name).iterator();
+ Symbol rhs = it.next();
Assert.check(rhs.owner.kind == MTH);
- Symbol lhs = e.next().sym;
+ Symbol lhs = it.next();
Assert.check(rhs.owner.owner == lhs.owner);
make.at(pos);
return
@@ -1903,10 +1903,10 @@
if ((clazz.flags() & INTERFACE) == 0 &&
!target.useInnerCacheClass()) return clazz;
Scope s = clazz.members();
- for (Scope.Entry e = s.elems; e != null; e = e.sibling)
- if (e.sym.kind == TYP &&
- e.sym.name == names.empty &&
- (e.sym.flags() & INTERFACE) == 0) return (ClassSymbol) e.sym;
+ for (Symbol sym : s.getSymbols(NON_RECURSIVE))
+ if (sym.kind == TYP &&
+ sym.name == names.empty &&
+ (sym.flags() & INTERFACE) == 0) return (ClassSymbol) sym;
return makeEmptyClass(STATIC | SYNTHETIC, clazz).sym;
}
@@ -2574,7 +2574,7 @@
// private static final T[] #VALUES = { a, b, c };
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());
Type arrayType = new ArrayType(types.erasure(tree.type),
syms.arrayClass, Type.noAnnotations);
@@ -2602,7 +2602,7 @@
} else {
// template: T[] $result = new T[$values.length];
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());
VarSymbol resultVar = new VarSymbol(FINAL|SYNTHETIC,
resultName,
@@ -2683,8 +2683,7 @@
private MethodSymbol systemArraycopyMethod;
private boolean useClone() {
try {
- Scope.Entry e = syms.objectType.tsym.members().lookup(names.clone);
- return (e.sym != null);
+ return syms.objectType.tsym.members().findFirst(names.clone) != null;
}
catch (CompletionFailure e) {
return false;
@@ -2786,7 +2785,7 @@
final Name pName = proxyName(l.head.name);
m.capturedLocals =
m.capturedLocals.append((VarSymbol)
- (proxies.lookup(pName).sym));
+ (proxies.findFirst(pName)));
added = added.prepend(
initField(tree.body.pos, pName));
}
@@ -3969,8 +3968,8 @@
classdefs = new HashMap<>();
actualSymbols = new HashMap<>();
freevarCache = new HashMap<>();
- proxies = new Scope(syms.noSymbol);
- twrVars = new Scope(syms.noSymbol);
+ proxies = WriteableScope.create(syms.noSymbol);
+ twrVars = WriteableScope.create(syms.noSymbol);
outerThisStack = List.nil();
accessNums = new HashMap<>();
accessSyms = new HashMap<>();
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Jul 10 12:39:26 2014 -0700
@@ -25,12 +25,18 @@
package com.sun.tools.javac.comp;
+import java.util.Collections;
import java.util.HashSet;
+import java.util.IdentityHashMap;
import java.util.Set;
import javax.tools.JavaFileObject;
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.tree.*;
import com.sun.tools.javac.util.*;
@@ -43,6 +49,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.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.ERROR;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
@@ -151,7 +158,7 @@
final TypeSymbol tsym,
Env<AttrContext> env) {
// 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 (((PackageSymbol)tsym).fullname.equals(names.java_lang)) {
JCDiagnostic msg = diags.fragment("fatal.err.no.java.lang");
@@ -160,7 +167,7 @@
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.
@@ -171,82 +178,16 @@
private void importStaticAll(int pos,
final TypeSymbol tsym,
Env<AttrContext> env) {
- final JavaFileObject sourcefile = env.toplevel.sourcefile;
- final Scope toScope = env.toplevel.starImportScope;
+ final StarImportScope toScope = env.toplevel.starImportScope;
final PackageSymbol packge = env.toplevel.packge;
final TypeSymbol origin = tsym;
// enter imported types immediately
- new Object() {
- Set<Symbol> processed = new HashSet<>();
- 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.kind == TYP &&
- (sym.flags() & STATIC) != 0 &&
- staticImportAccessible(sym, packge) &&
- sym.isMemberOf(origin, types) &&
- !toScope.includes(sym))
- toScope.enter(sym, fromScope, origin.members(), true);
- }
+ new SymbolImporter() {
+ void doImport(TypeSymbol tsym) {
+ toScope.importAll(tsym.members(), origin.members(), staticImportFilter, true);
}
}.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.
@@ -265,12 +206,46 @@
return;
}
- final Scope toScope = env.toplevel.namedImportScope;
- final PackageSymbol packge = env.toplevel.packge;
- final TypeSymbol origin = tsym;
+ final NamedImportScope toScope = env.toplevel.namedImportScope;
+ final Scope originMembers = tsym.members();
// enter imported types immediately
- new Object() {
+ new SymbolImporter() {
+ void doImport(TypeSymbol tsym) {
+ Set<Symbol> maskedOut = null;
+ for (Symbol sym : tsym.members().getSymbolsByName(name)) {
+ if (sym.kind == TYP &&
+ staticImportFilter.accepts(originMembers, sym) &&
+ !chk.checkUniqueStaticImport(pos, env.toplevel, sym)) {
+ if (maskedOut == null)
+ maskedOut = Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>());
+ maskedOut.add(sym);
+ }
+ }
+ ImportFilter importFilter = maskedOut != null ?
+ new MaskedImportFilter(staticImportFilter, maskedOut) :
+ staticImportFilter;
+ toScope.importByName(tsym.members(), originMembers, name, importFilter);
+ }
+ }.importFrom(tsym);
+ }
+ //where:
+ class MaskedImportFilter implements ImportFilter {
+
+ private final ImportFilter delegate;
+ private final Set<Symbol> maskedOut;
+
+ public MaskedImportFilter(ImportFilter delegate, Set<Symbol> maskedOut) {
+ 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) {
if (tsym == null || !processed.add(tsym))
@@ -281,78 +256,21 @@
for (Type t : types.interfaces(tsym.type))
importFrom(t.tsym);
- 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);
- }
+ doImport(tsym);
}
- }.importFrom(tsym);
-
- // enter non-types before annotations that might use them
- annotate.earlier(new Annotate.Worker() {
- Set<Symbol> processed = new HashSet<>();
- boolean found = false;
-
- public String toString() {
- return "import static " + tsym + "." + name;
- }
- 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);
+ abstract void doImport(TypeSymbol tsym);
+ }
- for (Scope.Entry e = tsym.members().lookup(name);
- 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() {
- 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.
* @param pos Position to be used for error reporting.
* @param tsym The class to be imported.
* @param env The environment containing the named import
* 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 &&
- chk.checkUniqueImport(pos, tsym, env.toplevel.namedImportScope))
- env.toplevel.namedImportScope.enter(tsym, tsym.owner.members());
+ chk.checkUniqueImport(pos, env.toplevel, tsym))
+ env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
}
/** Construct method type from method signature.
@@ -482,6 +400,32 @@
* 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
*/
protected Env<AttrContext> env;
@@ -570,7 +514,7 @@
}
public void visitTopLevel(JCCompilationUnit tree) {
- if (tree.starImportScope.elems != null) {
+ if (!tree.starImportScope.isEmpty()) {
// we must have already processed this toplevel
return;
}
@@ -640,7 +584,7 @@
}
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);
m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
tree.sym = m;
@@ -696,9 +640,8 @@
*/
Env<AttrContext> methodEnv(JCMethodDecl tree, Env<AttrContext> env) {
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.info.scope.owner = tree.sym;
if (tree.sym.type != null) {
//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());
@@ -739,7 +682,7 @@
ArrayType atype = (ArrayType)tree.vartype.type;
tree.vartype.type = atype.makeVarargs();
}
- Scope enclScope = enter.enterScope(env);
+ WriteableScope enclScope = enter.enterScope(env);
VarSymbol v =
new VarSymbol(0, tree.name, tree.vartype.type, enclScope.owner);
v.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, v, tree);
@@ -875,8 +818,7 @@
Env<AttrContext> initEnv(JCVariableDecl tree, Env<AttrContext> env) {
Env<AttrContext> localEnv = env.dupto(new AttrContextEnv(tree, env.info.dup()));
if (tree.sym.owner.kind == TYP) {
- localEnv.info.scope = env.info.scope.dupUnshared();
- localEnv.info.scope.owner = tree.sym;
+ localEnv.info.scope = env.info.scope.dupUnshared(tree.sym);
}
if ((tree.mods.flags & STATIC) != 0 ||
((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
@@ -1220,23 +1162,30 @@
// Enter all member fields and methods of a set of half completed
// classes in a second phase.
if (wasFirst) {
+ Set<JCCompilationUnit> topLevels = new HashSet<>();
try {
while (halfcompleted.nonEmpty()) {
Env<AttrContext> toFinish = halfcompleted.next();
+ topLevels.add(toFinish.toplevel);
finish(toFinish);
}
} finally {
isFirst = true;
}
+
+ for (JCCompilationUnit toplevel : topLevels) {
+ chk.checkImportsResolvable(toplevel);
+ }
+
}
}
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
- for (Scope.Entry e = env.outer.info.scope.elems ; e != null ; e = e.sibling) {
- if (e.sym.isLocal()) {
- baseScope.enter(e.sym);
+ for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
+ if (sym.isLocal()) {
+ baseScope.enter(sym);
}
}
//import current type-parameters into base scope
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Jul 10 12:39:26 2014 -0700
@@ -28,6 +28,7 @@
import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
import com.sun.tools.javac.api.Formattable.LocalizedString;
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.Type.*;
import com.sun.tools.javac.comp.Attr.ResultInfo;
@@ -95,12 +96,12 @@
public final boolean varargsEnabled;
public final boolean allowMethodHandles;
public final boolean allowFunctionalInterfaceMostSpecific;
- public final boolean checkVarargsAccessDuringResolution;
+ public final boolean checkVarargsAccessAfterResolution;
private final boolean debugResolve;
private final boolean compactMethodDiags;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
- Scope polymorphicSignatureScope;
+ WriteableScope polymorphicSignatureScope;
protected Resolve(Context context) {
context.put(resolveKey, this);
@@ -137,9 +138,9 @@
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
allowFunctionalInterfaceMostSpecific = source.allowFunctionalInterfaceMostSpecific();
- checkVarargsAccessDuringResolution =
+ checkVarargsAccessAfterResolution =
source.allowPostApplicabilityVarargsAccessCheck();
- polymorphicSignatureScope = new Scope(syms.noSymbol);
+ polymorphicSignatureScope = WriteableScope.create(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
}
@@ -836,13 +837,16 @@
Warner warn) {
super.argumentsAcceptable(env, deferredAttrContext, argtypes, formals, warn);
//should we expand formals?
- if ((!checkVarargsAccessDuringResolution ||
- (checkVarargsAccessDuringResolution &&
- deferredAttrContext.mode == AttrMode.CHECK)) &&
- deferredAttrContext.phase.isVarargsRequired()) {
- //check varargs element type accessibility
- varargsAccessible(env, types.elemtype(formals.last()),
- deferredAttrContext.inferenceContext);
+ if (deferredAttrContext.phase.isVarargsRequired()) {
+ Type typeToCheck = null;
+ if (!checkVarargsAccessAfterResolution) {
+ typeToCheck = types.elemtype(formals.last());
+ } else if (deferredAttrContext.mode == AttrMode.CHECK) {
+ typeToCheck = types.erasure(types.elemtype(formals.last()));
+ }
+ if (typeToCheck != null) {
+ varargsAccessible(env, typeToCheck, deferredAttrContext.inferenceContext);
+ }
}
}
@@ -1296,13 +1300,11 @@
c = c.type.getUpperBound().tsym;
Symbol bestSoFar = varNotFound;
Symbol sym;
- Scope.Entry e = c.members().lookup(name);
- while (e.scope != null) {
- if (e.sym.kind == VAR && (e.sym.flags_field & SYNTHETIC) == 0) {
- return isAccessible(env, site, e.sym)
- ? e.sym : new AccessError(env, site, e.sym);
+ for (Symbol s : c.members().getSymbolsByName(name)) {
+ if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
+ return isAccessible(env, site, s)
+ ? s : new AccessError(env, site, s);
}
- e = e.next();
}
Type st = types.supertype(c.type);
if (st != null && (st.hasTag(CLASS) || st.hasTag(TYPEVAR))) {
@@ -1345,20 +1347,20 @@
*/
Symbol findVar(Env<AttrContext> env, Name name) {
Symbol bestSoFar = varNotFound;
- Symbol sym;
Env<AttrContext> env1 = env;
boolean staticOnly = false;
while (env1.outer != null) {
+ Symbol sym = null;
if (isStatic(env1)) staticOnly = true;
- Scope.Entry e = env1.info.scope.lookup(name);
- while (e.scope != null &&
- (e.sym.kind != VAR ||
- (e.sym.flags_field & SYNTHETIC) != 0))
- e = e.next();
- sym = (e.scope != null)
- ? e.sym
- : findField(
- env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
+ for (Symbol s : env1.info.scope.getSymbolsByName(name)) {
+ if (s.kind == VAR && (s.flags_field & SYNTHETIC) == 0) {
+ sym = s;
+ break;
+ }
+ }
+ if (sym == null) {
+ sym = findField(env1, env1.enclClass.sym.type, name, env1.enclClass.sym);
+ }
if (sym.exists()) {
if (staticOnly &&
sym.kind == VAR &&
@@ -1375,7 +1377,7 @@
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())
return sym;
if (bestSoFar.exists())
@@ -1383,18 +1385,16 @@
Symbol origin = null;
for (Scope sc : new Scope[] { env.toplevel.namedImportScope, env.toplevel.starImportScope }) {
- Scope.Entry e = sc.lookup(name);
- for (; e.scope != null; e = e.next()) {
- sym = e.sym;
- if (sym.kind != VAR)
+ for (Symbol currentSymbol : sc.getSymbolsByName(name)) {
+ if (currentSymbol.kind != VAR)
continue;
// invariant: sym.kind == VAR
- if (bestSoFar.kind < AMBIGUOUS && sym.owner != bestSoFar.owner)
- return new AmbiguityError(bestSoFar, sym);
+ if (bestSoFar.kind < AMBIGUOUS && currentSymbol.owner != bestSoFar.owner)
+ return new AmbiguityError(bestSoFar, currentSymbol);
else if (bestSoFar.kind >= VAR) {
- origin = e.getOrigin().owner;
- bestSoFar = isAccessible(env, origin.type, sym)
- ? sym : new AccessError(env, origin.type, sym);
+ origin = sc.getOrigin(currentSymbol).owner;
+ bestSoFar = isAccessible(env, origin.type, currentSymbol)
+ ? currentSymbol : new AccessError(env, origin.type, currentSymbol);
}
}
if (bestSoFar.exists()) break;
@@ -1624,7 +1624,7 @@
boolean useVarargs,
boolean operator,
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, allowBoxing, useVarargs, operator);
}
@@ -1824,12 +1824,11 @@
List<Type> argtypes, List<Type> typeargtypes,
boolean allowBoxing, boolean useVarargs) {
Symbol bestSoFar = methodNotFound;
- Symbol sym;
Env<AttrContext> env1 = env;
boolean staticOnly = false;
while (env1.outer != null) {
if (isStatic(env1)) staticOnly = true;
- sym = findMethod(
+ Symbol sym = findMethod(
env1, env1.enclClass.sym.type, name, argtypes, typeargtypes,
allowBoxing, useVarargs, false);
if (sym.exists()) {
@@ -1845,41 +1844,37 @@
env1 = env1.outer;
}
- sym = findMethod(env, syms.predefClass.type, name, argtypes,
- typeargtypes, allowBoxing, useVarargs, false);
+ Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
+ typeargtypes, allowBoxing, useVarargs, false);
if (sym.exists())
return sym;
- Scope.Entry e = env.toplevel.namedImportScope.lookup(name);
- for (; e.scope != null; e = e.next()) {
- sym = e.sym;
- Type origin = e.getOrigin().owner.type;
- if (sym.kind == MTH) {
- if (e.sym.owner.type != origin)
- sym = sym.clone(e.getOrigin().owner);
- if (!isAccessible(env, origin, sym))
- sym = new AccessError(env, origin, sym);
- bestSoFar = selectBest(env, origin,
+ for (Symbol currentSym : env.toplevel.namedImportScope.getSymbolsByName(name)) {
+ Symbol origin = env.toplevel.namedImportScope.getOrigin(currentSym).owner;
+ if (currentSym.kind == MTH) {
+ if (currentSym.owner.type != origin.type)
+ currentSym = currentSym.clone(origin);
+ if (!isAccessible(env, origin.type, currentSym))
+ currentSym = new AccessError(env, origin.type, currentSym);
+ bestSoFar = selectBest(env, origin.type,
argtypes, typeargtypes,
- sym, bestSoFar,
+ currentSym, bestSoFar,
allowBoxing, useVarargs, false);
}
}
if (bestSoFar.exists())
return bestSoFar;
- e = env.toplevel.starImportScope.lookup(name);
- for (; e.scope != null; e = e.next()) {
- sym = e.sym;
- Type origin = e.getOrigin().owner.type;
- if (sym.kind == MTH) {
- if (e.sym.owner.type != origin)
- sym = sym.clone(e.getOrigin().owner);
- if (!isAccessible(env, origin, sym))
- sym = new AccessError(env, origin, sym);
- bestSoFar = selectBest(env, origin,
+ for (Symbol currentSym : env.toplevel.starImportScope.getSymbolsByName(name)) {
+ Symbol origin = env.toplevel.starImportScope.getOrigin(currentSym).owner;
+ if (currentSym.kind == MTH) {
+ if (currentSym.owner.type != origin.type)
+ currentSym = currentSym.clone(origin);
+ if (!isAccessible(env, origin.type, currentSym))
+ currentSym = new AccessError(env, origin.type, currentSym);
+ bestSoFar = selectBest(env, origin.type,
argtypes, typeargtypes,
- sym, bestSoFar,
+ currentSym, bestSoFar,
allowBoxing, useVarargs, false);
}
}
@@ -1918,14 +1913,12 @@
Type site,
Name name,
TypeSymbol c) {
- Scope.Entry e = c.members().lookup(name);
- while (e.scope != null) {
- if (e.sym.kind == TYP) {
- return isAccessible(env, site, e.sym)
- ? e.sym
- : new AccessError(env, site, e.sym);
+ for (Symbol sym : c.members().getSymbolsByName(name)) {
+ if (sym.kind == TYP) {
+ return isAccessible(env, site, sym)
+ ? sym
+ : new AccessError(env, site, sym);
}
- e = e.next();
}
return typeNotFound;
}
@@ -1992,8 +1985,8 @@
*/
Symbol findGlobalType(Env<AttrContext> env, Scope scope, Name name) {
Symbol bestSoFar = typeNotFound;
- for (Scope.Entry e = scope.lookup(name); e.scope != null; e = e.next()) {
- Symbol sym = loadClass(env, e.sym.flatName());
+ for (Symbol s : scope.getSymbolsByName(name)) {
+ Symbol sym = loadClass(env, s.flatName());
if (bestSoFar.kind == TYP && sym.kind == TYP &&
bestSoFar != sym)
return new AmbiguityError(bestSoFar, sym);
@@ -2004,15 +1997,13 @@
}
Symbol findTypeVar(Env<AttrContext> env, Name name, boolean staticOnly) {
- for (Scope.Entry e = env.info.scope.lookup(name);
- e.scope != null;
- e = e.next()) {
- if (e.sym.kind == TYP) {
+ for (Symbol sym : env.info.scope.getSymbolsByName(name)) {
+ if (sym.kind == TYP) {
if (staticOnly &&
- e.sym.type.hasTag(TYPEVAR) &&
- e.sym.owner.kind == TYP)
- return new StaticError(e.sym);
- return e.sym;
+ sym.type.hasTag(TYPEVAR) &&
+ sym.owner.kind == TYP)
+ return new StaticError(sym);
+ return sym;
}
}
return typeNotFound;
@@ -2320,42 +2311,6 @@
}
/* ***************************************************************************
- * 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
* Naming conventions are as for symbol lookup
* Unlike the find... methods these methods will report access errors
@@ -2453,7 +2408,7 @@
List<Type> argtypes) {
Type mtype = infer.instantiatePolymorphicSignatureInstance(env,
(MethodSymbol)spMethod, currentResolutionContext, argtypes);
- for (Symbol sym : polymorphicSignatureScope.getElementsByName(spMethod.name)) {
+ for (Symbol sym : polymorphicSignatureScope.getSymbolsByName(spMethod.name)) {
if (types.isSameType(mtype, sym.type)) {
return sym;
}
@@ -2626,14 +2581,11 @@
boolean allowBoxing,
boolean useVarargs) {
Symbol bestSoFar = methodNotFound;
- for (Scope.Entry e = site.tsym.members().lookup(names.init);
- e.scope != null;
- e = e.next()) {
- final Symbol sym = e.sym;
+ for (final Symbol sym : site.tsym.members().getSymbolsByName(names.init)) {
//- System.out.println(" e " + e.sym);
if (sym.kind == MTH &&
(sym.flags_field & SYNTHETIC) == 0) {
- List<Type> oldParams = e.sym.type.hasTag(FORALL) ?
+ List<Type> oldParams = sym.type.hasTag(FORALL) ?
((ForAll)sym.type).tvars :
List.<Type>nil();
Type constrType = new ForAll(site.tsym.type.getTypeArguments().appendList(oldParams),
@@ -3249,7 +3201,7 @@
@Override
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);
arrayConstr.type = new MethodType(List.<Type>of(syms.intType), site, List.<Type>nil(), syms.methodClass);
sc.enter(arrayConstr);
@@ -3359,7 +3311,7 @@
while (env1.outer != null) {
if (isStatic(env1)) staticOnly = true;
if (env1.enclClass.sym == c) {
- Symbol sym = env1.info.scope.lookup(name).sym;
+ Symbol sym = env1.info.scope.findFirst(name);
if (sym != null) {
if (staticOnly) sym = new StaticError(sym);
return accessBase(sym, pos, env.enclClass.sym.type,
@@ -3446,7 +3398,7 @@
while (env1 != null && env1.outer != null) {
if (isStatic(env1)) staticOnly = true;
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 (staticOnly) sym = new StaticError(sym);
return sym;
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java Thu Jul 10 12:39:26 2014 -0700
@@ -37,6 +37,7 @@
import static com.sun.tools.javac.code.Flags.*;
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.TYPEVAR;
import static com.sun.tools.javac.code.TypeTag.VOID;
@@ -449,8 +450,8 @@
TypeSymbol i,
ClassSymbol origin,
ListBuffer<JCTree> bridges) {
- for (Scope.Entry e = i.members().elems; e != null; e = e.sibling)
- addBridgeIfNeeded(pos, e.sym, origin, bridges);
+ for (Symbol sym : i.members().getSymbols(NON_RECURSIVE))
+ addBridgeIfNeeded(pos, sym, origin, bridges);
for (List<Type> l = types.interfaces(i.type); l.nonEmpty(); l = l.tail)
addBridges(pos, l.head.tsym, origin, bridges);
}
@@ -529,14 +530,12 @@
}
// Check that we do not introduce a name clash by erasing types.
- for (Scope.Entry e = tree.sym.owner.members().lookup(tree.name);
- e.sym != null;
- e = e.next()) {
- if (e.sym != tree.sym &&
- types.isSameType(erasure(e.sym.type), tree.type)) {
+ for (Symbol sym : tree.sym.owner.members().getSymbolsByName(tree.name)) {
+ if (sym != tree.sym &&
+ types.isSameType(erasure(sym.type), tree.type)) {
log.error(tree.pos(),
"name.clash.same.erasure", tree.sym,
- e.sym);
+ sym);
return;
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Jul 10 12:39:26 2014 -0700
@@ -42,6 +42,7 @@
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Lint.LintCategory;
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.Symtab;
import com.sun.tools.javac.file.BaseFileObject;
@@ -141,7 +142,7 @@
/** The current scope where type variables are entered.
*/
- protected Scope typevars;
+ protected WriteableScope typevars;
/** The path name of the class file currently being read.
*/
@@ -231,7 +232,7 @@
profile = Profile.instance(context);
- typevars = new Scope(syms.noSymbol);
+ typevars = WriteableScope.create(syms.noSymbol);
lintClassfile = Lint.instance(context).isEnabled(LintCategory.CLASSFILE);
@@ -832,9 +833,9 @@
/** Find type variable with given name in `typevars' scope.
*/
Type findTypeVar(Name name) {
- Scope.Entry e = typevars.lookup(name);
- if (e.scope != null) {
- return e.sym.type;
+ Symbol s = typevars.findFirst(name);
+ if (s != null) {
+ return s.type;
} else {
if (readingClassAttr) {
// While reading the class attribute, the supertypes
@@ -1228,9 +1229,10 @@
MethodType type = nt.uniqueType.type.asMethodType();
- for (Scope.Entry e = scope.lookup(nt.name); e.scope != null; e = e.next())
- if (e.sym.kind == MTH && isSameBinaryType(e.sym.type.asMethodType(), type))
- return (MethodSymbol)e.sym;
+ for (Symbol sym : scope.getSymbolsByName(nt.name)) {
+ if (sym.kind == MTH && isSameBinaryType(sym.type.asMethodType(), type))
+ return (MethodSymbol)sym;
+ }
if (nt.name != names.init)
// not a constructor
@@ -1769,10 +1771,7 @@
MethodSymbol findAccessMethod(Type container, Name name) {
CompletionFailure failure = null;
try {
- for (Scope.Entry e = container.tsym.members().lookup(name);
- e.scope != null;
- e = e.next()) {
- Symbol sym = e.sym;
+ for (Symbol sym : container.tsym.members().getSymbolsByName(name)) {
if (sym.kind == MTH && sym.type.getParameterTypes().length() == 0)
return (MethodSymbol) sym;
}
@@ -1852,11 +1851,9 @@
VarSymbol enumerator = null;
CompletionFailure failure = null;
try {
- for (Scope.Entry e = enumTypeSym.members().lookup(proxy.enumerator);
- e.scope != null;
- e = e.next()) {
- if (e.sym.kind == VAR) {
- enumerator = (VarSymbol)e.sym;
+ for (Symbol sym : enumTypeSym.members().getSymbolsByName(proxy.enumerator)) {
+ if (sym.kind == VAR) {
+ enumerator = (VarSymbol)sym;
break;
}
}
@@ -2197,7 +2194,7 @@
ClassType ct = (ClassType)c.type;
// allocate scope for members
- c.members_field = new Scope(c);
+ c.members_field = WriteableScope.create(c);
// prepare type variable table
typevars = typevars.dup(currentOwner);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,6 +49,7 @@
import static com.sun.tools.javac.code.Flags.*;
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.jvm.UninitializedType.*;
import static com.sun.tools.javac.main.Option.*;
@@ -1563,12 +1564,12 @@
}
}
- void writeFields(Scope.Entry e) {
+ void writeFields(Scope s) {
// process them in reverse sibling order;
// i.e., process them in declaration order.
List<VarSymbol> vars = List.nil();
- for (Scope.Entry i = e; i != null; i = i.sibling) {
- if (i.sym.kind == VAR) vars = vars.prepend((VarSymbol)i.sym);
+ for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == VAR) vars = vars.prepend((VarSymbol)sym);
}
while (vars.nonEmpty()) {
writeField(vars.head);
@@ -1576,11 +1577,11 @@
}
}
- void writeMethods(Scope.Entry e) {
+ void writeMethods(Scope s) {
List<MethodSymbol> methods = List.nil();
- for (Scope.Entry i = e; i != null; i = i.sibling) {
- if (i.sym.kind == MTH && (i.sym.flags() & HYPOTHETICAL) == 0)
- methods = methods.prepend((MethodSymbol)i.sym);
+ for (Symbol sym : s.getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == MTH && (sym.flags() & HYPOTHETICAL) == 0)
+ methods = methods.prepend((MethodSymbol)sym);
}
while (methods.nonEmpty()) {
writeMethod(methods.head);
@@ -1654,12 +1655,12 @@
databuf.appendChar(pool.put(l.head.tsym));
int fieldsCount = 0;
int methodsCount = 0;
- for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) {
- switch (e.sym.kind) {
+ for (Symbol sym : c.members().getSymbols(NON_RECURSIVE)) {
+ switch (sym.kind) {
case VAR: fieldsCount++; break;
- case MTH: if ((e.sym.flags() & HYPOTHETICAL) == 0) methodsCount++;
+ case MTH: if ((sym.flags() & HYPOTHETICAL) == 0) methodsCount++;
break;
- case TYP: enterInner((ClassSymbol)e.sym); break;
+ case TYP: enterInner((ClassSymbol)sym); break;
default : Assert.error();
}
}
@@ -1671,9 +1672,9 @@
}
databuf.appendChar(fieldsCount);
- writeFields(c.members().elems);
+ writeFields(c.members());
databuf.appendChar(methodsCount);
- writeMethods(c.members().elems);
+ writeMethods(c.members());
int acountIdx = beginAttrs();
int acount = 0;
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Jul 10 12:39:26 2014 -0700
@@ -45,6 +45,7 @@
import static com.sun.tools.javac.code.Flags.*;
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.jvm.ByteCodes.*;
import static com.sun.tools.javac.jvm.CRTFlags.*;
@@ -302,7 +303,7 @@
if (!target.interfaceObjectOverridesBinaryCompatibility()) {
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;
}
@@ -651,13 +652,10 @@
void implementInterfaceMethods(ClassSymbol c, ClassSymbol site) {
for (List<Type> l = types.interfaces(c.type); l.nonEmpty(); l = l.tail) {
ClassSymbol i = (ClassSymbol)l.head.tsym;
- for (Scope.Entry e = i.members().elems;
- e != null;
- e = e.sibling)
- {
- if (e.sym.kind == MTH && (e.sym.flags() & STATIC) == 0)
+ for (Symbol sym : i.members().getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == MTH && (sym.flags() & STATIC) == 0)
{
- MethodSymbol absMeth = (MethodSymbol)e.sym;
+ MethodSymbol absMeth = (MethodSymbol)sym;
MethodSymbol implMeth = absMeth.binaryImplementation(site, types);
if (implMeth == null)
addAbstractMethod(site, absMeth);
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/JNIWriter.java Thu Jul 10 12:39:26 2014 -0700
@@ -37,7 +37,6 @@
import com.sun.tools.javac.code.Attribute;
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.ClassSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
@@ -53,6 +52,7 @@
import static com.sun.tools.javac.main.Option.*;
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.
*
@@ -146,8 +146,7 @@
if (c.isLocal() || isSynthetic(c))
return false;
- for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
- Symbol sym = i.sym;
+ for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
if (sym.kind == MTH && isNative(sym))
return true;
for (Attribute.Compound a: sym.getDeclarationAttributes()) {
@@ -156,8 +155,7 @@
}
}
if (checkNestedClasses) {
- for (Scope.Entry i = c.members_field.elems; i != null; i = i.sibling) {
- Symbol sym = i.sym;
+ for (Symbol sym : c.members_field.getSymbols(NON_RECURSIVE)) {
if ((sym.kind == TYP) && needsHeader(((ClassSymbol) sym), true))
return true;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/AnnotationProxyMaker.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,7 @@
import com.sun.tools.javac.code.Type.ArrayType;
import com.sun.tools.javac.util.*;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/**
* A generator of dynamic proxy implementations of
@@ -119,9 +120,9 @@
// First find the default values.
ClassSymbol sym = (ClassSymbol) anno.type.tsym;
- for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
- if (e.sym.kind == Kinds.MTH) {
- MethodSymbol m = (MethodSymbol) e.sym;
+ for (Symbol s : sym.members().getSymbols(NON_RECURSIVE)) {
+ if (s.kind == Kinds.MTH) {
+ MethodSymbol m = (MethodSymbol) s;
Attribute def = m.getDefaultValue();
if (def != null)
res.put(m, def);
--- a/langtools/src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/FilteredMemberList.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,11 +27,12 @@
import java.util.AbstractList;
import java.util.Iterator;
-import java.util.NoSuchElementException;
import com.sun.tools.javac.code.Scope;
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.Scope.LookupKind.NON_RECURSIVE;
/**
* Utility to construct a view of a symbol's members,
@@ -53,56 +54,28 @@
public int size() {
int cnt = 0;
- for (Scope.Entry e = scope.elems; e != null; e = e.sibling) {
- if (!unwanted(e.sym))
+ for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
+ if (!unwanted(sym))
cnt++;
}
return cnt;
}
public Symbol get(int index) {
- for (Scope.Entry e = scope.elems; e != null; e = e.sibling) {
- if (!unwanted(e.sym) && (index-- == 0))
- return e.sym;
+ for (Symbol sym : scope.getSymbols(NON_RECURSIVE)) {
+ if (!unwanted(sym) && (index-- == 0))
+ return sym;
}
throw new IndexOutOfBoundsException();
}
// A more efficient implementation than AbstractList's.
public Iterator<Symbol> iterator() {
- return new Iterator<Symbol>() {
-
- /** The next entry to examine, or null if none. */
- 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;
+ return scope.getSymbols(new Filter<Symbol>() {
+ public boolean accepts(Symbol t) {
+ return !unwanted(t);
}
-
- 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();
- }
- };
+ }, NON_RECURSIVE).iterator();
}
/**
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Jul 10 12:39:26 2014 -0700
@@ -35,6 +35,7 @@
import static javax.lang.model.util.ElementFilter.methodsIn;
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.comp.AttrContext;
import com.sun.tools.javac.comp.Enter;
@@ -47,6 +48,7 @@
import com.sun.tools.javac.tree.TreeScanner;
import com.sun.tools.javac.util.*;
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.tree.JCTree.Tag.*;
@@ -356,35 +358,31 @@
*/
public FilteredMemberList getAllMembers(TypeElement element) {
Symbol sym = cast(Symbol.class, element);
- Scope scope = sym.members().dupUnshared();
+ WriteableScope scope = sym.members().dupUnshared();
List<Type> closure = types.closure(sym.asType());
for (Type t : closure)
addMembers(scope, t);
return new FilteredMemberList(scope);
}
// where
- private void addMembers(Scope scope, Type type) {
+ private void addMembers(WriteableScope scope, Type type) {
members:
- for (Scope.Entry e = type.asElement().members().elems; e != null; e = e.sibling) {
- Scope.Entry overrider = scope.lookup(e.sym.getSimpleName());
- while (overrider.scope != null) {
- if (overrider.sym.kind == e.sym.kind
- && (overrider.sym.flags() & Flags.SYNTHETIC) == 0)
- {
- if (overrider.sym.getKind() == ElementKind.METHOD
- && overrides((ExecutableElement)overrider.sym, (ExecutableElement)e.sym, (TypeElement)type.asElement())) {
+ for (Symbol e : type.asElement().members().getSymbols(NON_RECURSIVE)) {
+ for (Symbol overrider : scope.getSymbolsByName(e.getSimpleName())) {
+ if (overrider.kind == e.kind && (overrider.flags() & Flags.SYNTHETIC) == 0) {
+ if (overrider.getKind() == ElementKind.METHOD &&
+ overrides((ExecutableElement)overrider, (ExecutableElement)e, (TypeElement)type.asElement())) {
continue members;
}
}
- overrider = overrider.next();
}
- boolean derived = e.sym.getEnclosingElement() != scope.owner;
- ElementKind kind = e.sym.getKind();
+ boolean derived = e.getEnclosingElement() != scope.owner;
+ ElementKind kind = e.getKind();
boolean initializer = kind == ElementKind.CONSTRUCTOR
|| kind == ElementKind.INSTANCE_INIT
|| kind == ElementKind.STATIC_INIT;
- if (!derived || (!initializer && e.sym.isInheritedIn(scope.owner, types)))
- scope.enter(e.sym);
+ if (!derived || (!initializer && e.isInheritedIn(scope.owner, types)))
+ scope.enter(e);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacTypes.java Thu Jul 10 12:39:26 2014 -0700
@@ -310,9 +310,9 @@
for (Type t : types.closure(origin.type)) {
if (t != origin.type) {
ClassSymbol c = (ClassSymbol) t.tsym;
- for (Scope.Entry e = c.members().lookup(m.name); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH && m.overrides(e.sym, origin, types, true)) {
- results.add((MethodSymbol) e.sym);
+ for (Symbol sym : c.members().getSymbolsByName(m.name)) {
+ if (sym.kind == Kinds.MTH && m.overrides(sym, origin, types, true)) {
+ results.add((MethodSymbol) sym);
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/sym/CreateSymbols.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
import com.sun.tools.javac.api.JavacTaskImpl;
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.Attribute;
@@ -189,7 +189,7 @@
new Attribute.Compound(syms.proprietaryType,
List.<Pair<Symbol.MethodSymbol,Attribute>>nil());
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++) {
profileAnnos[i] = new Attribute.Compound(syms.profileType,
List.<Pair<Symbol.MethodSymbol, Attribute>>of(
@@ -259,9 +259,9 @@
pool.reset();
cs.pool = pool;
writer.writeClass(cs);
- for (Scope.Entry e = cs.members().elems; e != null; e = e.sibling) {
- if (e.sym.kind == Kinds.TYP) {
- ClassSymbol nestedClass = (ClassSymbol)e.sym;
+ for (Symbol sym : cs.members().getSymbols(NON_RECURSIVE)) {
+ if (sym.kind == Kinds.TYP) {
+ ClassSymbol nestedClass = (ClassSymbol)sym;
nestedClass.complete();
writeClass(pool, nestedClass, writer);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -488,8 +488,10 @@
public JavaFileObject sourcefile;
/** The package to which this compilation unit belongs. */
public PackageSymbol packge;
+ /** A scope containing top level classes. */
+ public WriteableScope toplevelScope;
/** A scope for all named imports. */
- public ImportScope namedImportScope;
+ public NamedImportScope namedImportScope;
/** A scope for all import-on-demands. */
public StarImportScope starImportScope;
/** Line starting positions, defined only if option -g is set. */
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
package com.sun.tools.javac.tree;
+import java.util.Iterator;
+
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
@@ -692,13 +694,36 @@
break;
}
case CLASS:
- Type outer = t.getEnclosingType();
- JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
- ? Select(Type(outer), t.tsym)
- : QualIdent(t.tsym);
- tp = t.getTypeArguments().isEmpty()
- ? clazz
- : TypeApply(clazz, Types(t.getTypeArguments()));
+ switch (t.getKind()) {
+ case UNION: {
+ UnionClassType tu = (UnionClassType)t;
+ ListBuffer<JCExpression> la = new ListBuffer<>();
+ for (Type ta : tu.getAlternativeTypes()) {
+ la.add(Type(ta));
+ }
+ tp = TypeUnion(la.toList());
+ break;
+ }
+ case INTERSECTION: {
+ IntersectionClassType it = (IntersectionClassType)t;
+ ListBuffer<JCExpression> la = new ListBuffer<>();
+ for (Type ta : it.getExplicitComponents()) {
+ la.add(Type(ta));
+ }
+ tp = TypeIntersection(la.toList());
+ break;
+ }
+ default: {
+ Type outer = t.getEnclosingType();
+ JCExpression clazz = outer.hasTag(CLASS) && t.tsym.owner.kind == TYP
+ ? Select(Type(outer), t.tsym)
+ : QualIdent(t.tsym);
+ tp = t.getTypeArguments().isEmpty()
+ ? clazz
+ : TypeApply(clazz, Types(t.getTypeArguments()));
+ break;
+ }
+ }
break;
case ARRAY:
tp = TypeArray(Type(types.elemtype(t)));
@@ -955,24 +980,26 @@
sym.owner.kind == MTH || sym.owner.kind == VAR) {
return true;
} else if (sym.kind == TYP && toplevel != null) {
- Scope.Entry e;
- e = toplevel.namedImportScope.lookup(sym.name);
- if (e.scope != null) {
+ Iterator<Symbol> it = toplevel.namedImportScope.getSymbolsByName(sym.name).iterator();
+ if (it.hasNext()) {
+ Symbol s = it.next();
return
- e.sym == sym &&
- e.next().scope == null;
+ s == sym &&
+ !it.hasNext();
}
- e = toplevel.packge.members().lookup(sym.name);
- if (e.scope != null) {
+ it = toplevel.packge.members().getSymbolsByName(sym.name).iterator();
+ if (it.hasNext()) {
+ Symbol s = it.next();
return
- e.sym == sym &&
- e.next().scope == null;
+ s == sym &&
+ !it.hasNext();
}
- e = toplevel.starImportScope.lookup(sym.name);
- if (e.scope != null) {
+ it = toplevel.starImportScope.getSymbolsByName(sym.name).iterator();
+ if (it.hasNext()) {
+ Symbol s = it.next();
return
- e.sym == sym &&
- e.next().scope == null;
+ s == sym &&
+ !it.hasNext();
}
}
return false;
--- a/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,10 +29,12 @@
import com.sun.source.util.TreePath;
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.util.List;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+
/**
* Represents an annotation type.
*
@@ -91,9 +93,9 @@
*/
public AnnotationTypeElementDoc[] elements() {
List<AnnotationTypeElementDoc> elements = List.nil();
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null && e.sym.kind == Kinds.MTH) {
- MethodSymbol s = (MethodSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kinds.MTH) {
+ MethodSymbol s = (MethodSymbol)sym;
elements = elements.prepend(env.getAnnotationTypeElementDoc(s));
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/ClassDocImpl.java Thu Jul 10 12:39:26 2014 -0700
@@ -59,6 +59,7 @@
import com.sun.tools.javac.util.Names;
import com.sun.tools.javac.util.Position;
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.tree.JCTree.Tag.*;
@@ -589,9 +590,9 @@
*/
private FieldDoc[] fields(boolean filter, boolean enumConstants) {
List<FieldDocImpl> fields = List.nil();
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null && e.sym.kind == VAR) {
- VarSymbol s = (VarSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == VAR) {
+ VarSymbol s = (VarSymbol)sym;
boolean isEnum = ((s.flags() & Flags.ENUM) != 0) &&
!env.legacyDoclet;
if (isEnum == enumConstants &&
@@ -614,12 +615,12 @@
public MethodDoc[] methods(boolean filter) {
Names names = tsym.name.table.names;
List<MethodDocImpl> methods = List.nil();
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null
- && e.sym.kind == Kinds.MTH
- && e.sym.name != names.init
- && e.sym.name != names.clinit) {
- MethodSymbol s = (MethodSymbol)e.sym;
+ for (Symbol sym :tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null
+ && sym.kind == Kinds.MTH
+ && sym.name != names.init
+ && sym.name != names.clinit) {
+ MethodSymbol s = (MethodSymbol)sym;
if (!filter || env.shouldDocument(s)) {
methods = methods.prepend(env.getMethodDoc(s));
}
@@ -649,10 +650,10 @@
public ConstructorDoc[] constructors(boolean filter) {
Names names = tsym.name.table.names;
List<ConstructorDocImpl> constructors = List.nil();
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null &&
- e.sym.kind == Kinds.MTH && e.sym.name == names.init) {
- MethodSymbol s = (MethodSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null &&
+ sym.kind == Kinds.MTH && sym.name == names.init) {
+ MethodSymbol s = (MethodSymbol)sym;
if (!filter || env.shouldDocument(s)) {
constructors = constructors.prepend(env.getConstructorDoc(s));
}
@@ -685,10 +686,9 @@
if (l.contains(this)) return;
l.append(this);
List<ClassDocImpl> more = List.nil();
- for (Scope.Entry e = tsym.members().elems; e != null;
- e = e.sibling) {
- if (e.sym != null && e.sym.kind == Kinds.TYP) {
- ClassSymbol s = (ClassSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kinds.TYP) {
+ ClassSymbol s = (ClassSymbol)sym;
ClassDocImpl c = env.getClassDoc(s);
if (c.isSynthetic()) continue;
if (c != null) more = more.prepend(c);
@@ -713,9 +713,9 @@
*/
public ClassDoc[] innerClasses(boolean filter) {
ListBuffer<ClassDocImpl> innerClasses = new ListBuffer<>();
- for (Scope.Entry e = tsym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null && e.sym.kind == Kinds.TYP) {
- ClassSymbol s = (ClassSymbol)e.sym;
+ for (Symbol sym : tsym.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kinds.TYP) {
+ ClassSymbol s = (ClassSymbol)sym;
if ((s.flags_field & Flags.SYNTHETIC) != 0) continue;
if (!filter || env.isVisible(s)) {
innerClasses.prepend(env.getClassDoc(s));
@@ -809,17 +809,17 @@
if (compenv == null) return null;
Scope s = compenv.toplevel.namedImportScope;
- for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.TYP) {
- ClassDoc c = env.getClassDoc((ClassSymbol)e.sym);
+ for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
+ if (sym.kind == Kinds.TYP) {
+ ClassDoc c = env.getClassDoc((ClassSymbol)sym);
return c;
}
}
s = compenv.toplevel.starImportScope;
- for (Scope.Entry e = s.lookup(names.fromString(className)); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.TYP) {
- ClassDoc c = env.getClassDoc((ClassSymbol)e.sym);
+ for (Symbol sym : s.getSymbolsByName(names.fromString(className))) {
+ if (sym.kind == Kinds.TYP) {
+ ClassDoc c = env.getClassDoc((ClassSymbol)sym);
return c;
}
}
@@ -918,7 +918,6 @@
*---------------------------------*/
// search current class
- Scope.Entry e = tsym.members().lookup(names.fromString(methodName));
//### Using modifier filter here isn't really correct,
//### but emulates the old behavior. Instead, we should
@@ -931,11 +930,11 @@
// In order to provide textually identical results, we
// attempt to emulate the old behavior.
MethodSymbol lastFound = null;
- for (; e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH) {
+ for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
+ if (sym.kind == Kinds.MTH) {
//### Should intern methodName as Name.
- if (e.sym.name.toString().equals(methodName)) {
- lastFound = (MethodSymbol)e.sym;
+ if (sym.name.toString().equals(methodName)) {
+ lastFound = (MethodSymbol)sym;
}
}
}
@@ -943,12 +942,12 @@
return env.getMethodDoc(lastFound);
}
} else {
- for (; e.scope != null; e = e.next()) {
- if (e.sym != null &&
- e.sym.kind == Kinds.MTH) {
+ for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(methodName))) {
+ if (sym != null &&
+ sym.kind == Kinds.MTH) {
//### Should intern methodName as Name.
- if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) {
- return env.getMethodDoc((MethodSymbol)e.sym);
+ if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
+ return env.getMethodDoc((MethodSymbol)sym);
}
}
}
@@ -1005,10 +1004,10 @@
public ConstructorDoc findConstructor(String constrName,
String[] paramTypes) {
Names names = tsym.name.table.names;
- for (Scope.Entry e = tsym.members().lookup(names.fromString("<init>")); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH) {
- if (hasParameterTypes((MethodSymbol)e.sym, paramTypes)) {
- return env.getConstructorDoc((MethodSymbol)e.sym);
+ for (Symbol sym : tsym.members().getSymbolsByName(names.fromString("<init>"))) {
+ if (sym.kind == Kinds.MTH) {
+ if (hasParameterTypes((MethodSymbol)sym, paramTypes)) {
+ return env.getConstructorDoc((MethodSymbol)sym);
}
}
}
@@ -1047,10 +1046,10 @@
}
searched.add(this);
- for (Scope.Entry e = tsym.members().lookup(names.fromString(fieldName)); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.VAR) {
+ for (Symbol sym : tsym.members().getSymbolsByName(names.fromString(fieldName))) {
+ if (sym.kind == Kinds.VAR) {
//### Should intern fieldName as Name.
- return env.getFieldDoc((VarSymbol)e.sym);
+ return env.getFieldDoc((VarSymbol)sym);
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/MethodDocImpl.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -128,8 +128,8 @@
t.hasTag(CLASS);
t = env.types.supertype(t)) {
ClassSymbol c = (ClassSymbol)t.tsym;
- for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) {
- if (sym.overrides(e.sym, origin, env.types, true)) {
+ for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
+ if (sym.overrides(sym2, origin, env.types, true)) {
return TypeMaker.getType(env, t);
}
}
@@ -160,9 +160,9 @@
t.hasTag(CLASS);
t = env.types.supertype(t)) {
ClassSymbol c = (ClassSymbol)t.tsym;
- for (Scope.Entry e = c.members().lookup(sym.name); e.scope != null; e = e.next()) {
- if (sym.overrides(e.sym, origin, env.types, true)) {
- return env.getMethodDoc((MethodSymbol)e.sym);
+ for (Symbol sym2 : c.members().getSymbolsByName(sym.name)) {
+ if (sym.overrides(sym2, origin, env.types, true)) {
+ return env.getMethodDoc((MethodSymbol)sym2);
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/PackageDocImpl.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
import com.sun.javadoc.*;
import com.sun.source.util.TreePath;
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.PackageSymbol;
import com.sun.tools.javac.tree.JCTree;
@@ -43,6 +43,8 @@
import com.sun.tools.javac.util.Name;
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
* about the package, the package's comment and tags, and the
@@ -146,9 +148,9 @@
return allClassesFiltered;
}
ListBuffer<ClassDocImpl> classes = new ListBuffer<>();
- for (Scope.Entry e = sym.members().elems; e != null; e = e.sibling) {
- if (e.sym != null) {
- ClassSymbol s = (ClassSymbol)e.sym;
+ for (Symbol enumerated : sym.members().getSymbols(NON_RECURSIVE)) {
+ if (enumerated != null) {
+ ClassSymbol s = (ClassSymbol)enumerated;
ClassDocImpl c = env.getClassDoc(s);
if (c != null && !c.isSynthetic())
c.addAllClasses(classes, filtered);
--- a/langtools/src/share/classes/com/sun/tools/javadoc/SerializedForm.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/SerializedForm.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,15 +26,13 @@
package com.sun.tools.javadoc;
import com.sun.javadoc.*;
-import com.sun.tools.javac.code.Flags;
-import com.sun.tools.javac.code.Kinds;
-import com.sun.tools.javac.code.Scope;
+import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.ClassSymbol;
import com.sun.tools.javac.code.Symbol.MethodSymbol;
import com.sun.tools.javac.code.Symbol.VarSymbol;
-import com.sun.tools.javac.util.ListBuffer;
-import com.sun.tools.javac.util.Name;
-import com.sun.tools.javac.util.Names;
+import com.sun.tools.javac.util.*;
+
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
/**
* The serialized form is the specification of a class' serialization
@@ -159,9 +157,9 @@
/* SERIALIZABLE_FIELDS can be private,
* 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()) {
- if (e.sym.kind == Kinds.VAR) {
- VarSymbol f = (VarSymbol)e.sym;
+ for (Symbol sym : def.members().getSymbolsByName(names.fromString(SERIALIZABLE_FIELDS))) {
+ if (sym.kind == Kinds.VAR) {
+ VarSymbol f = (VarSymbol)sym;
if ((f.flags() & Flags.STATIC) != 0 &&
(f.flags() & Flags.PRIVATE) != 0) {
return f;
@@ -180,9 +178,9 @@
private void computeDefaultSerializableFields(DocEnv env,
ClassSymbol def,
ClassDocImpl cd) {
- for (Scope.Entry e = def.members().elems; e != null; e = e.sibling) {
- if (e.sym != null && e.sym.kind == Kinds.VAR) {
- VarSymbol f = (VarSymbol)e.sym;
+ for (Symbol sym : def.members().getSymbols(NON_RECURSIVE)) {
+ if (sym != null && sym.kind == Kinds.VAR) {
+ VarSymbol f = (VarSymbol)sym;
if ((f.flags() & Flags.STATIC) == 0 &&
(f.flags() & Flags.TRANSIENT) == 0) {
//### No modifier filtering applied here.
@@ -209,9 +207,9 @@
private void addMethodIfExist(DocEnv env, ClassSymbol def, String methodName) {
Names names = def.name.table.names;
- for (Scope.Entry e = def.members().lookup(names.fromString(methodName)); e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.MTH) {
- MethodSymbol md = (MethodSymbol)e.sym;
+ for (Symbol sym : def.members().getSymbolsByName(names.fromString(methodName))) {
+ if (sym.kind == Kinds.MTH) {
+ MethodSymbol md = (MethodSymbol)sym;
if ((md.flags() & Flags.STATIC) == 0) {
/*
* WARNING: not robust if unqualifiedMethodName is overloaded
@@ -241,10 +239,9 @@
Name fieldName = names.fromString(tag.fieldName());
// Look for a FieldDocImpl that is documented by serialFieldTagImpl.
- for (Scope.Entry e = def.members().lookup(fieldName);
- e.scope != null; e = e.next()) {
- if (e.sym.kind == Kinds.VAR) {
- VarSymbol f = (VarSymbol) e.sym;
+ for (Symbol sym : def.members().getSymbolsByName(fieldName)) {
+ if (sym.kind == Kinds.VAR) {
+ VarSymbol f = (VarSymbol) sym;
FieldDocImpl fdi = env.getFieldDoc(f);
((SerialFieldTagImpl) (tag)).mapToFieldDocImpl(fdi);
break;
--- a/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Analyzer.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,16 +26,13 @@
import com.sun.tools.classfile.Dependency.Location;
import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
-import java.util.ArrayList;
+import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import java.util.SortedMap;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
/**
* Dependency Analyzer.
@@ -52,7 +49,16 @@
VERBOSE
}
+ /**
+ * Filter to be applied when analyzing the dependencies from the given archives.
+ * Only the accepted dependencies are recorded.
+ */
+ interface Filter {
+ boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive);
+ }
+
private final Type type;
+ private final Filter filter;
private final Map<Archive, ArchiveDeps> results = new HashMap<>();
private final Map<Location, Archive> map = new HashMap<>();
private final Archive NOT_FOUND
@@ -62,9 +68,11 @@
* Constructs an Analyzer instance.
*
* @param type Type of the dependency analysis
+ * @param filter
*/
- public Analyzer(Type type) {
+ public Analyzer(Type type, Filter filter) {
this.type = type;
+ this.filter = filter;
}
/**
@@ -72,6 +80,18 @@
*/
public void run(List<Archive> archives) {
// build a map from Location to Archive
+ buildLocationArchiveMap(archives);
+
+ // traverse and analyze all dependencies
+ for (Archive archive : archives) {
+ ArchiveDeps deps = new ArchiveDeps(archive, type);
+ archive.visitDependences(deps);
+ results.put(archive, deps);
+ }
+ }
+
+ private void buildLocationArchiveMap(List<Archive> archives) {
+ // build a map from Location to Archive
for (Archive archive: archives) {
for (Location l: archive.getClasses()) {
if (!map.containsKey(l)) {
@@ -81,190 +101,202 @@
}
}
}
- // traverse and analyze all dependencies
- for (Archive archive : archives) {
- ArchiveDeps deps;
- if (type == Type.CLASS || type == Type.VERBOSE) {
- deps = new ClassVisitor(archive);
- } else {
- deps = new PackageVisitor(archive);
- }
- archive.visitDependences(deps);
- results.put(archive, deps);
- }
}
public boolean hasDependences(Archive archive) {
if (results.containsKey(archive)) {
- return results.get(archive).deps.size() > 0;
+ return results.get(archive).dependencies().size() > 0;
}
return false;
}
public interface Visitor {
/**
- * Visits the source archive to its destination archive of
- * a recorded dependency.
- */
- void visitArchiveDependence(Archive origin, Archive target, Profile profile);
- /**
* Visits a recorded dependency from origin to target which can be
- * a fully-qualified classname, a package name, a profile or
+ * a fully-qualified classname, a package name, a module or
* archive name depending on the Analyzer's type.
*/
- void visitDependence(String origin, Archive source, String target, Archive archive, Profile profile);
+ public void visitDependence(String origin, Archive originArchive,
+ String target, Archive targetArchive);
}
- public void visitArchiveDependences(Archive source, Visitor v) {
- ArchiveDeps r = results.get(source);
- for (ArchiveDeps.Dep d: r.requireArchives()) {
- v.visitArchiveDependence(r.archive, d.archive, d.profile);
+ /**
+ * Visit the dependencies of the given source.
+ * If the requested level is SUMMARY, it will visit the required archives list.
+ */
+ public void visitDependences(Archive source, Visitor v, Type level) {
+ if (level == Type.SUMMARY) {
+ final ArchiveDeps result = results.get(source);
+ result.requires().stream()
+ .sorted(Comparator.comparing(Archive::getName))
+ .forEach(archive -> {
+ Profile profile = result.getTargetProfile(archive);
+ v.visitDependence(source.getName(), source,
+ profile != null ? profile.profileName() : archive.getName(), archive);
+ });
+ } else {
+ ArchiveDeps result = results.get(source);
+ if (level != type) {
+ // requesting different level of analysis
+ result = new ArchiveDeps(source, level);
+ source.visitDependences(result);
+ }
+ result.dependencies().stream()
+ .sorted(Comparator.comparing(Dep::origin)
+ .thenComparing(Dep::target))
+ .forEach(d -> v.visitDependence(d.origin(), d.originArchive(), d.target(), d.targetArchive()));
}
}
public void visitDependences(Archive source, Visitor v) {
- ArchiveDeps r = results.get(source);
- for (Map.Entry<String, SortedSet<ArchiveDeps.Dep>> e: r.deps.entrySet()) {
- String origin = e.getKey();
- for (ArchiveDeps.Dep d: e.getValue()) {
- // filter intra-dependency unless in verbose mode
- if (type == Type.VERBOSE || d.archive != source) {
- v.visitDependence(origin, source, d.target, d.archive, d.profile);
- }
- }
- }
+ visitDependences(source, v, type);
}
/**
- * ArchiveDeps contains the dependencies for an Archive that
- * can have one or more classes.
+ * ArchiveDeps contains the dependencies for an Archive that can have one or
+ * more classes.
*/
- private abstract class ArchiveDeps implements Archive.Visitor {
- final Archive archive;
- final SortedMap<String, SortedSet<Dep>> deps;
- ArchiveDeps(Archive archive) {
+ class ArchiveDeps implements Archive.Visitor {
+ protected final Archive archive;
+ protected final Set<Archive> requires;
+ protected final Set<Dep> deps;
+ protected final Type level;
+ private Profile profile;
+ ArchiveDeps(Archive archive, Type level) {
this.archive = archive;
- this.deps = new TreeMap<>();
- }
-
- void add(String origin, String target, Archive targetArchive, String pkgName) {
- SortedSet<Dep> set = deps.get(origin);
- if (set == null) {
- deps.put(origin, set = new TreeSet<>());
- }
- Profile p = targetArchive instanceof JDKArchive
- ? Profile.getProfile(pkgName) : null;
- set.add(new Dep(target, targetArchive, p));
+ this.deps = new HashSet<>();
+ this.requires = new HashSet<>();
+ this.level = level;
}
- /**
- * Returns the list of Archive dependences. The returned
- * list contains one {@code Dep} instance per one archive
- * and with the minimum profile this archive depends on.
- */
- List<Dep> requireArchives() {
- Map<Archive,Profile> map = new HashMap<>();
- for (Set<Dep> set: deps.values()) {
- for (Dep d: set) {
- if (this.archive != d.archive) {
- Profile p = map.get(d.archive);
- if (p == null || (d.profile != null && p.profile < d.profile.profile)) {
- map.put(d.archive, d.profile);
- }
- }
- }
+ Set<Dep> dependencies() {
+ return deps;
+ }
+
+ Set<Archive> requires() {
+ return requires;
+ }
+
+ Profile getTargetProfile(Archive target) {
+ return JDKArchive.isProfileArchive(target) ? profile : null;
+ }
+
+ Archive findArchive(Location t) {
+ Archive target = archive.getClasses().contains(t) ? archive : map.get(t);
+ if (target == null) {
+ map.put(t, target = NOT_FOUND);
}
- List<Dep> list = new ArrayList<>();
- for (Map.Entry<Archive,Profile> e: map.entrySet()) {
- list.add(new Dep("", e.getKey(), e.getValue()));
- }
- return list;
+ return target;
}
- /**
- * Dep represents a dependence where the target can be
- * a classname or packagename and the archive and profile
- * the target belongs to.
- */
- class Dep implements Comparable<Dep> {
- final String target;
- final Archive archive;
- final Profile profile;
- Dep(String target, Archive archive, Profile p) {
- this.target = target;
- this.archive = archive;
- this.profile = p;
+ // return classname or package name depedning on the level
+ private String getLocationName(Location o) {
+ if (level == Type.CLASS || level == Type.VERBOSE) {
+ return o.getClassName();
+ } else {
+ String pkg = o.getPackageName();
+ return pkg.isEmpty() ? "<unnamed>" : pkg;
+ }
+ }
+
+ @Override
+ public void visit(Location o, Location t) {
+ Archive targetArchive = findArchive(t);
+ if (filter.accepts(o, archive, t, targetArchive)) {
+ addDep(o, t);
+ if (!requires.contains(targetArchive)) {
+ requires.add(targetArchive);
+ }
}
+ if (targetArchive instanceof JDKArchive) {
+ Profile p = Profile.getProfile(t.getPackageName());
+ if (profile == null || (p != null && p.compareTo(profile) > 0)) {
+ profile = p;
+ }
+ }
+ }
- @Override
- public boolean equals(Object o) {
- if (o instanceof Dep) {
- Dep d = (Dep)o;
- return this.archive == d.archive && this.target.equals(d.target);
- }
- return false;
+ private Dep curDep;
+ protected Dep addDep(Location o, Location t) {
+ String origin = getLocationName(o);
+ String target = getLocationName(t);
+ Archive targetArchive = findArchive(t);
+ if (curDep != null &&
+ curDep.origin().equals(origin) &&
+ curDep.originArchive() == archive &&
+ curDep.target().equals(target) &&
+ curDep.targetArchive() == targetArchive) {
+ return curDep;
}
- @Override
- public int hashCode() {
- int hash = 3;
- hash = 17 * hash + Objects.hashCode(this.archive);
- hash = 17 * hash + Objects.hashCode(this.target);
- return hash;
- }
-
- @Override
- public int compareTo(Dep o) {
- if (this.target.equals(o.target)) {
- if (this.archive == o.archive) {
- return 0;
- } else {
- return this.archive.getFileName().compareTo(o.archive.getFileName());
+ Dep e = new Dep(origin, archive, target, targetArchive);
+ if (deps.contains(e)) {
+ for (Dep e1 : deps) {
+ if (e.equals(e1)) {
+ curDep = e1;
}
}
- return this.target.compareTo(o.target);
+ } else {
+ deps.add(e);
+ curDep = e;
}
- }
- public abstract void visit(Location o, Location t);
- }
-
- private class ClassVisitor extends ArchiveDeps {
- ClassVisitor(Archive archive) {
- super(archive);
- }
- @Override
- public void visit(Location o, Location t) {
- Archive targetArchive =
- this.archive.getClasses().contains(t) ? this.archive : map.get(t);
- if (targetArchive == null) {
- map.put(t, targetArchive = NOT_FOUND);
- }
-
- String origin = o.getClassName();
- String target = t.getClassName();
- add(origin, target, targetArchive, t.getPackageName());
+ return curDep;
}
}
- private class PackageVisitor extends ArchiveDeps {
- PackageVisitor(Archive archive) {
- super(archive);
+ /*
+ * Class-level or package-level dependency
+ */
+ class Dep {
+ final String origin;
+ final Archive originArchive;
+ final String target;
+ final Archive targetArchive;
+
+ Dep(String origin, Archive originArchive, String target, Archive targetArchive) {
+ this.origin = origin;
+ this.originArchive = originArchive;
+ this.target = target;
+ this.targetArchive = targetArchive;
}
+
+ String origin() {
+ return origin;
+ }
+
+ Archive originArchive() {
+ return originArchive;
+ }
+
+ String target() {
+ return target;
+ }
+
+ Archive targetArchive() {
+ return targetArchive;
+ }
+
@Override
- public void visit(Location o, Location t) {
- Archive targetArchive =
- this.archive.getClasses().contains(t) ? this.archive : map.get(t);
- if (targetArchive == null) {
- map.put(t, targetArchive = NOT_FOUND);
+ @SuppressWarnings("unchecked")
+ public boolean equals(Object o) {
+ if (o instanceof Dep) {
+ Dep d = (Dep) o;
+ return this.origin.equals(d.origin) &&
+ this.originArchive == d.originArchive &&
+ this.target.equals(d.target) &&
+ this.targetArchive == d.targetArchive;
}
+ return false;
+ }
- String origin = packageOf(o);
- String target = packageOf(t);
- add(origin, target, targetArchive, t.getPackageName());
- }
- public String packageOf(Location o) {
- String pkg = o.getPackageName();
- return pkg.isEmpty() ? "<unnamed>" : pkg;
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 67*hash + Objects.hashCode(this.origin)
+ + Objects.hashCode(this.originArchive)
+ + Objects.hashCode(this.target)
+ + Objects.hashCode(this.targetArchive);
+ return hash;
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Archive.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,28 +25,34 @@
package com.sun.tools.jdeps;
import com.sun.tools.classfile.Dependency.Location;
+
+import java.io.IOException;
import java.nio.file.Path;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Represents the source of the class files.
*/
public class Archive {
+ public static Archive getInstance(Path p) throws IOException {
+ return new Archive(p, ClassFileReader.newInstance(p));
+ }
+
private final Path path;
private final String filename;
private final ClassFileReader reader;
- private final Map<Location, Set<Location>> deps = new HashMap<>();
+ protected Map<Location, Set<Location>> deps = new ConcurrentHashMap<>();
- public Archive(String name) {
+ protected Archive(String name) {
this.path = null;
this.filename = name;
this.reader = null;
}
- public Archive(Path p, ClassFileReader reader) {
+ protected Archive(Path p, ClassFileReader reader) {
this.path = p;
this.filename = path.getFileName().toString();
this.reader = reader;
@@ -56,7 +62,7 @@
return reader;
}
- public String getFileName() {
+ public String getName() {
return filename;
}
@@ -89,6 +95,10 @@
}
}
+ public boolean isEmpty() {
+ return getClasses().isEmpty();
+ }
+
public String getPathName() {
return path != null ? path.toString() : filename;
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/ClassFileReader.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -68,7 +68,8 @@
protected final Path path;
protected final String baseFileName;
- private ClassFileReader(Path path) {
+ protected final List<String> skippedEntries = new ArrayList<>();
+ protected ClassFileReader(Path path) {
this.path = path;
this.baseFileName = path.getFileName() != null
? path.getFileName().toString()
@@ -79,6 +80,10 @@
return baseFileName;
}
+ public List<String> skippedEntries() {
+ return skippedEntries;
+ }
+
/**
* Returns the ClassFile matching the given binary name
* or a fully-qualified class name.
@@ -232,11 +237,12 @@
}
}
- private static class JarFileReader extends ClassFileReader {
- final JarFile jarfile;
+ static class JarFileReader extends ClassFileReader {
+ private final JarFile jarfile;
JarFileReader(Path path) throws IOException {
- this(path, new JarFile(path.toFile()));
+ this(path, new JarFile(path.toFile(), false));
}
+
JarFileReader(Path path, JarFile jf) throws IOException {
super(path);
this.jarfile = jf;
@@ -252,18 +258,18 @@
+ entryName.substring(i + 1, entryName.length()));
}
if (e != null) {
- return readClassFile(e);
+ return readClassFile(jarfile, e);
}
} else {
JarEntry e = jarfile.getJarEntry(name + ".class");
if (e != null) {
- return readClassFile(e);
+ return readClassFile(jarfile, e);
}
}
return null;
}
- private ClassFile readClassFile(JarEntry e) throws IOException {
+ protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException {
InputStream is = null;
try {
is = jarfile.getInputStream(e);
@@ -277,60 +283,76 @@
}
public Iterable<ClassFile> getClassFiles() throws IOException {
- final Iterator<ClassFile> iter = new JarFileIterator();
+ final Iterator<ClassFile> iter = new JarFileIterator(this, jarfile);
return new Iterable<ClassFile>() {
public Iterator<ClassFile> iterator() {
return iter;
}
};
}
+ }
- class JarFileIterator implements Iterator<ClassFile> {
- private Enumeration<JarEntry> entries;
- private JarEntry nextEntry;
- JarFileIterator() {
- this.entries = jarfile.entries();
- while (entries.hasMoreElements()) {
- JarEntry e = entries.nextElement();
- String name = e.getName();
- if (name.endsWith(".class")) {
- this.nextEntry = e;
- break;
- }
+ class JarFileIterator implements Iterator<ClassFile> {
+ protected final JarFileReader reader;
+ protected Enumeration<JarEntry> entries;
+ protected JarFile jf;
+ protected JarEntry nextEntry;
+ protected ClassFile cf;
+ JarFileIterator(JarFileReader reader) {
+ this(reader, null);
+ }
+ JarFileIterator(JarFileReader reader, JarFile jarfile) {
+ this.reader = reader;
+ setJarFile(jarfile);
+ }
+
+ void setJarFile(JarFile jarfile) {
+ if (jarfile == null) return;
+
+ this.jf = jarfile;
+ this.entries = jf.entries();
+ this.nextEntry = nextEntry();
+ }
+
+ public boolean hasNext() {
+ if (nextEntry != null && cf != null) {
+ return true;
+ }
+ while (nextEntry != null) {
+ try {
+ cf = reader.readClassFile(jf, nextEntry);
+ return true;
+ } catch (ClassFileError | IOException ex) {
+ skippedEntries.add(nextEntry.getName());
+ }
+ nextEntry = nextEntry();
+ }
+ return false;
+ }
+
+ public ClassFile next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ ClassFile classFile = cf;
+ cf = null;
+ nextEntry = nextEntry();
+ return classFile;
+ }
+
+ protected JarEntry nextEntry() {
+ while (entries.hasMoreElements()) {
+ JarEntry e = entries.nextElement();
+ String name = e.getName();
+ if (name.endsWith(".class")) {
+ return e;
}
}
-
- public boolean hasNext() {
- return nextEntry != null;
- }
-
- public ClassFile next() {
- if (!hasNext()) {
- throw new NoSuchElementException();
- }
+ return null;
+ }
- ClassFile cf;
- try {
- cf = readClassFile(nextEntry);
- } catch (IOException ex) {
- throw new ClassFileError(ex);
- }
- JarEntry entry = nextEntry;
- nextEntry = null;
- while (entries.hasMoreElements()) {
- JarEntry e = entries.nextElement();
- String name = e.getName();
- if (name.endsWith(".class")) {
- nextEntry = e;
- break;
- }
- }
- return cf;
- }
-
- public void remove() {
- throw new UnsupportedOperationException("Not supported yet.");
- }
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/JdepsTask.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,9 @@
import com.sun.tools.classfile.Dependencies;
import com.sun.tools.classfile.Dependencies.ClassFileError;
import com.sun.tools.classfile.Dependency;
+import com.sun.tools.classfile.Dependency.Location;
import com.sun.tools.jdeps.PlatformClassPath.JDKArchive;
+import static com.sun.tools.jdeps.Analyzer.Type.*;
import java.io.*;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
@@ -110,7 +112,7 @@
void process(JdepsTask task, String opt, String arg) throws BadArgs {
Path p = Paths.get(arg);
if (Files.exists(p) && (!Files.isDirectory(p) || !Files.isWritable(p))) {
- throw new BadArgs("err.dot.output.path", arg);
+ throw new BadArgs("err.invalid.path", arg);
}
task.options.dotOutputDir = arg;
}
@@ -118,25 +120,26 @@
new Option(false, "-s", "-summary") {
void process(JdepsTask task, String opt, String arg) {
task.options.showSummary = true;
- task.options.verbose = Analyzer.Type.SUMMARY;
+ task.options.verbose = SUMMARY;
}
},
new Option(false, "-v", "-verbose",
"-verbose:package",
- "-verbose:class")
- {
+ "-verbose:class") {
void process(JdepsTask task, String opt, String arg) throws BadArgs {
switch (opt) {
case "-v":
case "-verbose":
- task.options.verbose = Analyzer.Type.VERBOSE;
+ task.options.verbose = VERBOSE;
+ task.options.filterSameArchive = false;
+ task.options.filterSamePackage = false;
break;
case "-verbose:package":
- task.options.verbose = Analyzer.Type.PACKAGE;
- break;
+ task.options.verbose = PACKAGE;
+ break;
case "-verbose:class":
- task.options.verbose = Analyzer.Type.CLASS;
- break;
+ task.options.verbose = CLASS;
+ break;
default:
throw new BadArgs("err.invalid.arg.for.option", opt);
}
@@ -157,6 +160,32 @@
task.options.regex = arg;
}
},
+
+ new Option(true, "-f", "-filter") {
+ void process(JdepsTask task, String opt, String arg) {
+ task.options.filterRegex = arg;
+ }
+ },
+ new Option(false, "-filter:package",
+ "-filter:archive",
+ "-filter:none") {
+ void process(JdepsTask task, String opt, String arg) {
+ switch (opt) {
+ case "-filter:package":
+ task.options.filterSamePackage = true;
+ task.options.filterSameArchive = false;
+ break;
+ case "-filter:archive":
+ task.options.filterSameArchive = true;
+ task.options.filterSamePackage = false;
+ break;
+ case "-filter:none":
+ task.options.filterSameArchive = false;
+ task.options.filterSamePackage = false;
+ break;
+ }
+ }
+ },
new Option(true, "-include") {
void process(JdepsTask task, String opt, String arg) throws BadArgs {
task.options.includePattern = Pattern.compile(arg);
@@ -178,12 +207,15 @@
new Option(false, "-R", "-recursive") {
void process(JdepsTask task, String opt, String arg) {
task.options.depth = 0;
+ // turn off filtering
+ task.options.filterSameArchive = false;
+ task.options.filterSamePackage = false;
}
},
new Option(false, "-jdkinternals") {
void process(JdepsTask task, String opt, String arg) {
task.options.findJDKInternals = true;
- task.options.verbose = Analyzer.Type.CLASS;
+ task.options.verbose = CLASS;
if (task.options.includePattern == null) {
task.options.includePattern = Pattern.compile(".*");
}
@@ -262,7 +294,7 @@
showHelp();
return EXIT_CMDERR;
}
- if (options.showSummary && options.verbose != Analyzer.Type.SUMMARY) {
+ if (options.showSummary && options.verbose != SUMMARY) {
showHelp();
return EXIT_CMDERR;
}
@@ -283,9 +315,28 @@
private final List<Archive> sourceLocations = new ArrayList<>();
private boolean run() throws IOException {
+ // parse classfiles and find all dependencies
findDependencies();
- Analyzer analyzer = new Analyzer(options.verbose);
+
+ Analyzer analyzer = new Analyzer(options.verbose, new Analyzer.Filter() {
+ @Override
+ public boolean accepts(Location origin, Archive originArchive, Location target, Archive targetArchive) {
+ if (options.findJDKInternals) {
+ // accepts target that is JDK class but not exported
+ return isJDKArchive(targetArchive) &&
+ !((JDKArchive) targetArchive).isExported(target.getClassName());
+ } else if (options.filterSameArchive) {
+ // accepts origin and target that from different archive
+ return originArchive != targetArchive;
+ }
+ return true;
+ }
+ });
+
+ // analyze the dependencies
analyzer.run(sourceLocations);
+
+ // output result
if (options.dotOutputDir != null) {
Path dir = Paths.get(options.dotOutputDir);
Files.createDirectories(dir);
@@ -296,27 +347,34 @@
return true;
}
- private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
+ private void generateSummaryDotFile(Path dir, Analyzer analyzer) throws IOException {
+ // If verbose mode (-v or -verbose option),
+ // the summary.dot file shows package-level dependencies.
+ Analyzer.Type summaryType =
+ (options.verbose == PACKAGE || options.verbose == SUMMARY) ? SUMMARY : PACKAGE;
Path summary = dir.resolve("summary.dot");
- boolean verbose = options.verbose == Analyzer.Type.VERBOSE;
- DotGraph<?> graph = verbose ? new DotSummaryForPackage()
- : new DotSummaryForArchive();
- for (Archive archive : sourceLocations) {
- analyzer.visitArchiveDependences(archive, graph);
- if (verbose || options.showLabel) {
- // traverse detailed dependences to generate package-level
- // summary or build labels for edges
- analyzer.visitDependences(archive, graph);
+ try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary));
+ SummaryDotFile dotfile = new SummaryDotFile(sw, summaryType)) {
+ for (Archive archive : sourceLocations) {
+ if (!archive.isEmpty()) {
+ if (options.verbose == PACKAGE || options.verbose == SUMMARY) {
+ if (options.showLabel) {
+ // build labels listing package-level dependencies
+ analyzer.visitDependences(archive, dotfile.labelBuilder(), PACKAGE);
+ }
+ }
+ analyzer.visitDependences(archive, dotfile, summaryType);
+ }
}
}
- try (PrintWriter sw = new PrintWriter(Files.newOutputStream(summary))) {
- graph.writeTo(sw);
- }
+ }
+
+ private void generateDotFiles(Path dir, Analyzer analyzer) throws IOException {
// output individual .dot file for each archive
- if (options.verbose != Analyzer.Type.SUMMARY) {
+ if (options.verbose != SUMMARY) {
for (Archive archive : sourceLocations) {
if (analyzer.hasDependences(archive)) {
- Path dotfile = dir.resolve(archive.getFileName() + ".dot");
+ Path dotfile = dir.resolve(archive.getName() + ".dot");
try (PrintWriter pw = new PrintWriter(Files.newOutputStream(dotfile));
DotFileFormatter formatter = new DotFileFormatter(pw, archive)) {
analyzer.visitDependences(archive, formatter);
@@ -324,17 +382,23 @@
}
}
}
+ // generate summary dot file
+ generateSummaryDotFile(dir, analyzer);
}
private void printRawOutput(PrintWriter writer, Analyzer analyzer) {
+ RawOutputFormatter depFormatter = new RawOutputFormatter(writer);
+ RawSummaryFormatter summaryFormatter = new RawSummaryFormatter(writer);
for (Archive archive : sourceLocations) {
- RawOutputFormatter formatter = new RawOutputFormatter(writer);
- analyzer.visitArchiveDependences(archive, formatter);
- if (options.verbose != Analyzer.Type.SUMMARY) {
- analyzer.visitDependences(archive, formatter);
+ if (!archive.isEmpty()) {
+ analyzer.visitDependences(archive, summaryFormatter, SUMMARY);
+ if (analyzer.hasDependences(archive) && options.verbose != SUMMARY) {
+ analyzer.visitDependences(archive, depFormatter);
+ }
}
}
}
+
private boolean isValidClassName(String name) {
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
return false;
@@ -348,21 +412,54 @@
return true;
}
- private Dependency.Filter getDependencyFilter() {
- if (options.regex != null) {
- return Dependencies.getRegexFilter(Pattern.compile(options.regex));
- } else if (options.packageNames.size() > 0) {
- return Dependencies.getPackageFilter(options.packageNames, false);
- } else {
- return new Dependency.Filter() {
- @Override
- public boolean accepts(Dependency dependency) {
- return !dependency.getOrigin().equals(dependency.getTarget());
- }
- };
+ /*
+ * Dep Filter configured based on the input jdeps option
+ * 1. -p and -regex to match target dependencies
+ * 2. -filter:package to filter out same-package dependencies
+ *
+ * This filter is applied when jdeps parses the class files
+ * and filtered dependencies are not stored in the Analyzer.
+ *
+ * -filter:archive is applied later in the Analyzer as the
+ * containing archive of a target class may not be known until
+ * the entire archive
+ */
+ class DependencyFilter implements Dependency.Filter {
+ final Dependency.Filter filter;
+ final Pattern filterPattern;
+ DependencyFilter() {
+ if (options.regex != null) {
+ this.filter = Dependencies.getRegexFilter(Pattern.compile(options.regex));
+ } else if (options.packageNames.size() > 0) {
+ this.filter = Dependencies.getPackageFilter(options.packageNames, false);
+ } else {
+ this.filter = null;
+ }
+
+ this.filterPattern =
+ options.filterRegex != null ? Pattern.compile(options.filterRegex) : null;
+ }
+ @Override
+ public boolean accepts(Dependency d) {
+ if (d.getOrigin().equals(d.getTarget())) {
+ return false;
+ }
+ String pn = d.getTarget().getPackageName();
+ if (options.filterSamePackage && d.getOrigin().getPackageName().equals(pn)) {
+ return false;
+ }
+
+ if (filterPattern != null && filterPattern.matcher(pn).matches()) {
+ return false;
+ }
+ return filter != null ? filter.accepts(d) : true;
}
}
+ /**
+ * Tests if the given class matches the pattern given in the -include option
+ * or if it's a public class if -apionly option is specified
+ */
private boolean matches(String classname, AccessFlags flags) {
if (options.apiOnly && !flags.is(AccessFlags.ACC_PUBLIC)) {
return false;
@@ -377,14 +474,14 @@
Dependency.Finder finder =
options.apiOnly ? Dependencies.getAPIFinder(AccessFlags.ACC_PROTECTED)
: Dependencies.getClassDependencyFinder();
- Dependency.Filter filter = getDependencyFilter();
+ Dependency.Filter filter = new DependencyFilter();
List<Archive> archives = new ArrayList<>();
Deque<String> roots = new LinkedList<>();
for (String s : classes) {
Path p = Paths.get(s);
if (Files.exists(p)) {
- archives.add(new Archive(p, ClassFileReader.newInstance(p)));
+ archives.add(Archive.getInstance(p));
} else {
if (isValidClassName(s)) {
roots.add(s);
@@ -421,19 +518,26 @@
throw new ClassFileError(e);
}
- if (matches(classFileName, cf.access_flags)) {
- if (!doneClasses.contains(classFileName)) {
- doneClasses.add(classFileName);
+ // tests if this class matches the -include or -apiOnly option if specified
+ if (!matches(classFileName, cf.access_flags)) {
+ continue;
+ }
+
+ if (!doneClasses.contains(classFileName)) {
+ doneClasses.add(classFileName);
+ }
+
+ for (Dependency d : finder.findDependencies(cf)) {
+ if (filter.accepts(d)) {
+ String cn = d.getTarget().getName();
+ if (!doneClasses.contains(cn) && !deque.contains(cn)) {
+ deque.add(cn);
+ }
+ a.addClass(d.getOrigin(), d.getTarget());
}
- for (Dependency d : finder.findDependencies(cf)) {
- if (filter.accepts(d)) {
- String cn = d.getTarget().getName();
- if (!doneClasses.contains(cn) && !deque.contains(cn)) {
- deque.add(cn);
- }
- a.addClass(d.getOrigin(), d.getTarget());
- }
- }
+ }
+ for (String name : a.reader().skippedEntries()) {
+ warning("warn.skipped.entry", name, a.getPathName());
}
}
}
@@ -462,6 +566,10 @@
// if name is a fully-qualified class name specified
// from command-line, this class might already be parsed
doneClasses.add(classFileName);
+ // process @jdk.Exported for JDK classes
+ if (isJDKArchive(a)) {
+ ((JDKArchive)a).processJdkExported(cf);
+ }
for (Dependency d : finder.findDependencies(cf)) {
if (depth == 0) {
// ignore the dependency
@@ -544,7 +652,7 @@
for (Option o : recognizedOptions) {
String name = o.aliases[0].substring(1); // there must always be at least one name
name = name.charAt(0) == '-' ? name.substring(1) : name;
- if (o.isHidden() || name.equals("h")) {
+ if (o.isHidden() || name.equals("h") || name.startsWith("filter:")) {
continue;
}
log.println(getMessage("main.opt." + name));
@@ -582,14 +690,18 @@
boolean fullVersion;
boolean showProfile;
boolean showSummary;
- boolean wildcard;
boolean apiOnly;
boolean showLabel;
boolean findJDKInternals;
+ // default is to show package-level dependencies
+ // and filter references from same package
+ Analyzer.Type verbose = PACKAGE;
+ boolean filterSamePackage = true;
+ boolean filterSameArchive = false;
+ String filterRegex;
String dotOutputDir;
String classpath = "";
int depth = 1;
- Analyzer.Type verbose = Analyzer.Type.PACKAGE;
Set<String> packageNames = new HashSet<>();
String regex; // apply to the dependences
Pattern includePattern; // apply to classes
@@ -613,19 +725,6 @@
}
}
- private List<Archive> getArchives(List<String> filenames) throws IOException {
- List<Archive> result = new ArrayList<>();
- for (String s : filenames) {
- Path p = Paths.get(s);
- if (Files.exists(p)) {
- result.add(new Archive(p, ClassFileReader.newInstance(p)));
- } else {
- warning("warn.file.not.exist", s);
- }
- }
- return result;
- }
-
private List<Archive> getClassPathArchives(String paths) throws IOException {
List<Archive> result = new ArrayList<>();
if (paths.isEmpty()) {
@@ -648,7 +747,7 @@
}
for (Path f : files) {
if (Files.exists(f)) {
- result.add(new Archive(f, ClassFileReader.newInstance(f)));
+ result.add(Archive.getInstance(f));
}
}
}
@@ -656,81 +755,50 @@
return result;
}
- /**
- * If the given archive is JDK archive and non-null Profile,
- * this method returns the profile name only if -profile option is specified;
- * a null profile indicates it accesses a private JDK API and this method
- * will return "JDK internal API".
- *
- * For non-JDK archives, this method returns the file name of the archive.
- */
- private String getProfileArchiveInfo(Archive source, Profile profile) {
- if (options.showProfile && profile != null)
- return profile.toString();
-
- if (source instanceof JDKArchive) {
- return profile == null ? "JDK internal API (" + source.getFileName() + ")" : "";
- }
- return source.getFileName();
- }
-
- /**
- * Returns the profile name or "JDK internal API" for JDK archive;
- * otherwise empty string.
- */
- private String profileName(Archive archive, Profile profile) {
- if (archive instanceof JDKArchive) {
- return Objects.toString(profile, "JDK internal API");
- } else {
- return "";
- }
- }
-
class RawOutputFormatter implements Analyzer.Visitor {
private final PrintWriter writer;
+ private String pkg = "";
RawOutputFormatter(PrintWriter writer) {
this.writer = writer;
}
-
- private String pkg = "";
@Override
- public void visitDependence(String origin, Archive source,
- String target, Archive archive, Profile profile) {
- if (options.findJDKInternals &&
- !(archive instanceof JDKArchive && profile == null)) {
- // filter dependences other than JDK internal APIs
- return;
- }
- if (options.verbose == Analyzer.Type.VERBOSE) {
- writer.format(" %-50s -> %-50s %s%n",
- origin, target, getProfileArchiveInfo(archive, profile));
+ public void visitDependence(String origin, Archive originArchive,
+ String target, Archive targetArchive) {
+ String tag = toTag(target, targetArchive);
+ if (options.verbose == VERBOSE) {
+ writer.format(" %-50s -> %-50s %s%n", origin, target, tag);
} else {
if (!origin.equals(pkg)) {
pkg = origin;
- writer.format(" %s (%s)%n", origin, source.getFileName());
+ writer.format(" %s (%s)%n", origin, originArchive.getName());
}
- writer.format(" -> %-50s %s%n",
- target, getProfileArchiveInfo(archive, profile));
- }
- }
-
- @Override
- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
- writer.format("%s -> %s", origin.getPathName(), target.getPathName());
- if (options.showProfile && profile != null) {
- writer.format(" (%s)%n", profile);
- } else {
- writer.format("%n");
+ writer.format(" -> %-50s %s%n", target, tag);
}
}
}
- class DotFileFormatter extends DotGraph<String> implements AutoCloseable {
+ class RawSummaryFormatter implements Analyzer.Visitor {
+ private final PrintWriter writer;
+ RawSummaryFormatter(PrintWriter writer) {
+ this.writer = writer;
+ }
+ @Override
+ public void visitDependence(String origin, Archive originArchive,
+ String target, Archive targetArchive) {
+ writer.format("%s -> %s", originArchive.getName(), targetArchive.getPathName());
+ if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
+ writer.format(" (%s)", target);
+ }
+ writer.format("%n");
+ }
+ }
+
+ class DotFileFormatter implements Analyzer.Visitor, AutoCloseable {
private final PrintWriter writer;
private final String name;
DotFileFormatter(PrintWriter writer, Archive archive) {
this.writer = writer;
- this.name = archive.getFileName();
+ this.name = archive.getName();
writer.format("digraph \"%s\" {%n", name);
writer.format(" // Path: %s%n", archive.getPathName());
}
@@ -741,173 +809,123 @@
}
@Override
- public void visitDependence(String origin, Archive source,
- String target, Archive archive, Profile profile) {
- if (options.findJDKInternals &&
- !(archive instanceof JDKArchive && profile == null)) {
- // filter dependences other than JDK internal APIs
- return;
- }
- // if -P option is specified, package name -> profile will
- // be shown and filter out multiple same edges.
- String name = getProfileArchiveInfo(archive, profile);
- writeEdge(writer, new Edge(origin, target, getProfileArchiveInfo(archive, profile)));
- }
- @Override
- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
- throw new UnsupportedOperationException();
- }
- }
-
- class DotSummaryForArchive extends DotGraph<Archive> {
- @Override
- public void visitDependence(String origin, Archive source,
- String target, Archive archive, Profile profile) {
- Edge e = findEdge(source, archive);
- assert e != null;
- // add the dependency to the label if enabled and not compact1
- if (profile == Profile.COMPACT1) {
- return;
- }
- e.addLabel(origin, target, profileName(archive, profile));
- }
- @Override
- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
- // add an edge with the archive's name with no tag
- // so that there is only one node for each JDK archive
- // while there may be edges to different profiles
- Edge e = addEdge(origin, target, "");
- if (target instanceof JDKArchive) {
- // add a label to print the profile
- if (profile == null) {
- e.addLabel("JDK internal API");
- } else if (options.showProfile && !options.showLabel) {
- e.addLabel(profile.toString());
- }
- }
+ public void visitDependence(String origin, Archive originArchive,
+ String target, Archive targetArchive) {
+ String tag = toTag(target, targetArchive);
+ writer.format(" %-50s -> \"%s\";%n",
+ String.format("\"%s\"", origin),
+ tag.isEmpty() ? target
+ : String.format("%s (%s)", target, tag));
}
}
- // DotSummaryForPackage generates the summary.dot file for verbose mode
- // (-v or -verbose option) that includes all class dependencies.
- // The summary.dot file shows package-level dependencies.
- class DotSummaryForPackage extends DotGraph<String> {
- private String packageOf(String cn) {
- int i = cn.lastIndexOf('.');
- return i > 0 ? cn.substring(0, i) : "<unnamed>";
+ class SummaryDotFile implements Analyzer.Visitor, AutoCloseable {
+ private final PrintWriter writer;
+ private final Analyzer.Type type;
+ private final Map<Archive, Map<Archive,StringBuilder>> edges = new HashMap<>();
+ SummaryDotFile(PrintWriter writer, Analyzer.Type type) {
+ this.writer = writer;
+ this.type = type;
+ writer.format("digraph \"summary\" {%n");
}
- @Override
- public void visitDependence(String origin, Archive source,
- String target, Archive archive, Profile profile) {
- // add a package dependency edge
- String from = packageOf(origin);
- String to = packageOf(target);
- Edge e = addEdge(from, to, getProfileArchiveInfo(archive, profile));
- // add the dependency to the label if enabled and not compact1
- if (!options.showLabel || profile == Profile.COMPACT1) {
- return;
- }
-
- // trim the package name of origin to shorten the label
- int i = origin.lastIndexOf('.');
- String n1 = i < 0 ? origin : origin.substring(i+1);
- e.addLabel(n1, target, profileName(archive, profile));
- }
@Override
- public void visitArchiveDependence(Archive origin, Archive target, Profile profile) {
- // nop
- }
- }
- abstract class DotGraph<T> implements Analyzer.Visitor {
- private final Set<Edge> edges = new LinkedHashSet<>();
- private Edge curEdge;
- public void writeTo(PrintWriter writer) {
- writer.format("digraph \"summary\" {%n");
- for (Edge e: edges) {
- writeEdge(writer, e);
- }
+ public void close() {
writer.println("}");
}
- void writeEdge(PrintWriter writer, Edge e) {
- writer.format(" %-50s -> \"%s\"%s;%n",
- String.format("\"%s\"", e.from.toString()),
- e.tag.isEmpty() ? e.to
- : String.format("%s (%s)", e.to, e.tag),
- getLabel(e));
+ @Override
+ public void visitDependence(String origin, Archive originArchive,
+ String target, Archive targetArchive) {
+ String targetName = type == PACKAGE ? target : targetArchive.getName();
+ if (type == PACKAGE) {
+ String tag = toTag(target, targetArchive, type);
+ if (!tag.isEmpty())
+ targetName += " (" + tag + ")";
+ } else if (options.showProfile && JDKArchive.isProfileArchive(targetArchive)) {
+ targetName += " (" + target + ")";
+ }
+ String label = getLabel(originArchive, targetArchive);
+ writer.format(" %-50s -> \"%s\"%s;%n",
+ String.format("\"%s\"", origin), targetName, label);
}
- Edge addEdge(T origin, T target, String tag) {
- Edge e = new Edge(origin, target, tag);
- if (e.equals(curEdge)) {
- return curEdge;
- }
+ String getLabel(Archive origin, Archive target) {
+ if (edges.isEmpty())
+ return "";
- if (edges.contains(e)) {
- for (Edge e1 : edges) {
- if (e.equals(e1)) {
- curEdge = e1;
- }
- }
- } else {
- edges.add(e);
- curEdge = e;
- }
- return curEdge;
- }
-
- Edge findEdge(T origin, T target) {
- for (Edge e : edges) {
- if (e.from.equals(origin) && e.to.equals(target)) {
- return e;
- }
- }
- return null;
- }
-
- String getLabel(Edge e) {
- String label = e.label.toString();
- return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label);
+ StringBuilder label = edges.get(origin).get(target);
+ return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString());
}
- class Edge {
- final T from;
- final T to;
- final String tag; // optional tag
- final StringBuilder label = new StringBuilder();
- Edge(T from, T to, String tag) {
- this.from = from;
- this.to = to;
- this.tag = tag;
- }
- void addLabel(String s) {
- label.append(s).append("\\n");
- }
- void addLabel(String origin, String target, String profile) {
- label.append(origin).append(" -> ").append(target);
- if (!profile.isEmpty()) {
- label.append(" (" + profile + ")");
+ Analyzer.Visitor labelBuilder() {
+ // show the package-level dependencies as labels in the dot graph
+ return new Analyzer.Visitor() {
+ @Override
+ public void visitDependence(String origin, Archive originArchive, String target, Archive targetArchive) {
+ edges.putIfAbsent(originArchive, new HashMap<>());
+ edges.get(originArchive).putIfAbsent(targetArchive, new StringBuilder());
+ StringBuilder sb = edges.get(originArchive).get(targetArchive);
+ String tag = toTag(target, targetArchive, PACKAGE);
+ addLabel(sb, origin, target, tag);
}
- label.append("\\n");
- }
- @Override @SuppressWarnings("unchecked")
- public boolean equals(Object o) {
- if (o instanceof DotGraph<?>.Edge) {
- DotGraph<?>.Edge e = (DotGraph<?>.Edge)o;
- return this.from.equals(e.from) &&
- this.to.equals(e.to) &&
- this.tag.equals(e.tag);
+
+ void addLabel(StringBuilder label, String origin, String target, String tag) {
+ label.append(origin).append(" -> ").append(target);
+ if (!tag.isEmpty()) {
+ label.append(" (" + tag + ")");
+ }
+ label.append("\\n");
}
- return false;
- }
- @Override
- public int hashCode() {
- int hash = 7;
- hash = 67 * hash + Objects.hashCode(this.from) +
- Objects.hashCode(this.to) + Objects.hashCode(this.tag);
- return hash;
- }
+ };
}
}
+
+ /**
+ * Test if the given archive is part of the JDK
+ */
+ private boolean isJDKArchive(Archive archive) {
+ return JDKArchive.class.isInstance(archive);
+ }
+
+ /**
+ * If the given archive is JDK archive, this method returns the profile name
+ * only if -profile option is specified; it accesses a private JDK API and
+ * the returned value will have "JDK internal API" prefix
+ *
+ * For non-JDK archives, this method returns the file name of the archive.
+ */
+ private String toTag(String name, Archive source, Analyzer.Type type) {
+ if (!isJDKArchive(source)) {
+ return source.getName();
+ }
+
+ JDKArchive jdk = (JDKArchive)source;
+ boolean isExported = false;
+ if (type == CLASS || type == VERBOSE) {
+ isExported = jdk.isExported(name);
+ } else {
+ isExported = jdk.isExportedPackage(name);
+ }
+ Profile p = getProfile(name, type);
+ if (isExported) {
+ // exported API
+ return options.showProfile && p != null ? p.profileName() : "";
+ } else {
+ return "JDK internal API (" + source.getName() + ")";
+ }
+ }
+
+ private String toTag(String name, Archive source) {
+ return toTag(name, source, options.verbose);
+ }
+
+ private Profile getProfile(String name, Analyzer.Type type) {
+ String pn = name;
+ if (type == CLASS || type == VERBOSE) {
+ int i = name.lastIndexOf('.');
+ pn = i > 0 ? name.substring(0, i) : "";
+ }
+ return Profile.getProfile(pn);
+ }
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/Main.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Main.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,4 +63,3 @@
return t.run(args);
}
}
-
--- a/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/PlatformClassPath.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,12 @@
*/
package com.sun.tools.jdeps;
+import com.sun.tools.classfile.Annotation;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.RuntimeAnnotations_attribute;
+import com.sun.tools.classfile.Dependencies.ClassFileError;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
@@ -33,11 +39,15 @@
import java.nio.file.attribute.BasicFileAttributes;
import java.util.*;
+import static com.sun.tools.classfile.Attribute.*;
+
/**
* ClassPath for Java SE and JDK
*/
class PlatformClassPath {
- private final static List<Archive> javaHomeArchives = init();
+ private static final List<String> NON_PLATFORM_JARFILES =
+ Arrays.asList("alt-rt.jar", "jfxrt.jar", "ant-javafx.jar", "javafx-mx.jar");
+ private static final List<Archive> javaHomeArchives = init();
static List<Archive> getArchives() {
return javaHomeArchives;
@@ -50,12 +60,19 @@
if (home.endsWith("jre")) {
// jar files in <javahome>/jre/lib
result.addAll(addJarFiles(home.resolve("lib")));
+ if (home.getParent() != null) {
+ // add tools.jar and other JDK jar files
+ Path lib = home.getParent().resolve("lib");
+ if (Files.exists(lib)) {
+ result.addAll(addJarFiles(lib));
+ }
+ }
} else if (Files.exists(home.resolve("lib"))) {
// either a JRE or a jdk build image
Path classes = home.resolve("classes");
if (Files.isDirectory(classes)) {
// jdk build outputdir
- result.add(new JDKArchive(classes, ClassFileReader.newInstance(classes)));
+ result.add(new JDKArchive(classes));
}
// add other JAR files
result.addAll(addJarFiles(home.resolve("lib")));
@@ -91,9 +108,9 @@
if (fn.endsWith(".jar")) {
// JDK may cobundle with JavaFX that doesn't belong to any profile
// Treat jfxrt.jar as regular Archive
- result.add(fn.equals("jfxrt.jar")
- ? new Archive(p, ClassFileReader.newInstance(p))
- : new JDKArchive(p, ClassFileReader.newInstance(p)));
+ result.add(NON_PLATFORM_JARFILES.contains(fn)
+ ? Archive.getInstance(p)
+ : new JDKArchive(p));
}
return FileVisitResult.CONTINUE;
}
@@ -106,8 +123,91 @@
* or implementation classes (i.e. JDK internal API)
*/
static class JDKArchive extends Archive {
- JDKArchive(Path p, ClassFileReader reader) {
- super(p, reader);
+ private static List<String> PROFILE_JARS = Arrays.asList("rt.jar", "jce.jar");
+ public static boolean isProfileArchive(Archive archive) {
+ if (archive instanceof JDKArchive) {
+ return PROFILE_JARS.contains(archive.getName());
+ }
+ return false;
+ }
+
+ private final Map<String,Boolean> exportedPackages = new HashMap<>();
+ private final Map<String,Boolean> exportedTypes = new HashMap<>();
+ JDKArchive(Path p) throws IOException {
+ super(p, ClassFileReader.newInstance(p));
+ }
+
+ /**
+ * Tests if a given fully-qualified name is an exported type.
+ */
+ public boolean isExported(String cn) {
+ int i = cn.lastIndexOf('.');
+ String pn = i > 0 ? cn.substring(0, i) : "";
+
+ boolean isJdkExported = isExportedPackage(pn);
+ if (exportedTypes.containsKey(cn)) {
+ return exportedTypes.get(cn);
+ }
+ return isJdkExported;
+ }
+
+ /**
+ * Tests if a given package name is exported.
+ */
+ public boolean isExportedPackage(String pn) {
+ if (Profile.getProfile(pn) != null) {
+ return true;
+ }
+ return exportedPackages.containsKey(pn) ? exportedPackages.get(pn) : false;
+ }
+
+ private static final String JDK_EXPORTED_ANNOTATION = "Ljdk/Exported;";
+ private Boolean isJdkExported(ClassFile cf) throws ConstantPoolException {
+ RuntimeAnnotations_attribute attr = (RuntimeAnnotations_attribute)
+ cf.attributes.get(RuntimeVisibleAnnotations);
+ if (attr != null) {
+ for (int i = 0; i < attr.annotations.length; i++) {
+ Annotation ann = attr.annotations[i];
+ String annType = cf.constant_pool.getUTF8Value(ann.type_index);
+ if (JDK_EXPORTED_ANNOTATION.equals(annType)) {
+ boolean isJdkExported = true;
+ for (int j = 0; j < ann.num_element_value_pairs; j++) {
+ Annotation.element_value_pair pair = ann.element_value_pairs[j];
+ Annotation.Primitive_element_value ev = (Annotation.Primitive_element_value) pair.value;
+ ConstantPool.CONSTANT_Integer_info info = (ConstantPool.CONSTANT_Integer_info)
+ cf.constant_pool.get(ev.const_value_index);
+ isJdkExported = info.value != 0;
+ }
+ return Boolean.valueOf(isJdkExported);
+ }
+ }
+ }
+ return null;
+ }
+
+ void processJdkExported(ClassFile cf) throws IOException {
+ try {
+ String cn = cf.getName();
+ String pn = cn.substring(0, cn.lastIndexOf('/')).replace('/', '.');
+
+ Boolean b = isJdkExported(cf);
+ if (b != null) {
+ exportedTypes.put(cn.replace('/', '.'), b);
+ }
+ if (!exportedPackages.containsKey(pn)) {
+ // check if package-info.class has @jdk.Exported
+ Boolean isJdkExported = null;
+ ClassFile pcf = reader().getClassFile(cn.substring(0, cn.lastIndexOf('/')+1) + "package-info");
+ if (pcf != null) {
+ isJdkExported = isJdkExported(pcf);
+ }
+ if (isJdkExported != null) {
+ exportedPackages.put(pn, isJdkExported);
+ }
+ }
+ } catch (ConstantPoolException e) {
+ throw new ClassFileError(e);
+ }
}
}
}
--- a/langtools/src/share/classes/com/sun/tools/jdeps/Profile.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/Profile.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,6 @@
* Build the profile information from ct.sym if exists.
*/
enum Profile {
-
COMPACT1("compact1", 1),
COMPACT2("compact2", 2),
COMPACT3("compact3", 3),
@@ -61,8 +60,7 @@
this.proprietaryPkgs = new HashSet<>();
}
- @Override
- public String toString() {
+ public String profileName() {
return name;
}
@@ -77,7 +75,7 @@
public static Profile getProfile(String pn) {
Profile profile = PackageToProfile.map.get(pn);
return (profile != null && profile.packages.contains(pn))
- ? profile : null;
+ ? profile : null;
}
static class PackageToProfile {
--- a/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/jdeps/resources/jdeps.properties Thu Jul 10 12:39:26 2014 -0700
@@ -1,6 +1,6 @@
main.usage.summary=\
Usage: {0} <options> <classes...>\n\
-use -h, -? or --help for a list of possible options
+use -h, -? or -help for a list of possible options
main.usage=\
Usage: {0} <options> <classes...>\n\
@@ -18,20 +18,29 @@
main.opt.v=\
\ -v -verbose Print all class level dependencies\n\
+\ Equivalent to -verbose:class -filter:none.\n\
\ -verbose:package Print package-level dependencies excluding\n\
-\ dependencies within the same archive\n\
+\ dependencies within the same package by default\n\
\ -verbose:class Print class-level dependencies excluding\n\
-\ dependencies within the same archive
+\ dependencies within the same package by default
+
+main.opt.f=\
+\ -f <regex> -filter <regex> Filter dependences matching the given pattern\n\
+\ If given multiple times, the last one will be used.\n\
+\ -filter:package Filter dependences within the same package (default)\n\
+\ -filter:archive Filter dependences within the same archive\n\
+\ -filter:none No -filter:package and -filter:archive filtering\n\
+\ Filtering specified via the -filter option still applies.
main.opt.s=\
\ -s -summary Print dependency summary only
main.opt.p=\
-\ -p <pkgname> -package <pkgname> Finds dependences in the given package\n\
+\ -p <pkgname> -package <pkgname> Finds dependences matching the given package name\n\
\ (may be given multiple times)
main.opt.e=\
-\ -e <regex> -regex <regex> Finds dependences in packages matching pattern\n\
+\ -e <regex> -regex <regex> Finds dependences matching the given pattern\n\
\ (-p and -e are exclusive)
main.opt.include=\
@@ -47,7 +56,10 @@
\ -cp <path> -classpath <path> Specify where to find class files
main.opt.R=\
-\ -R -recursive Recursively traverse all dependencies
+\ -R -recursive Recursively traverse all dependencies.\n\
+\ The -R option implies -filter:none. If -p, -e, -f\n\
+\ option is specified, only the matching dependences\n\
+\ are analyzed.
main.opt.apionly=\
\ -apionly Restrict analysis to APIs i.e. dependences\n\
@@ -74,12 +86,11 @@
err.unknown.option=unknown option: {0}
err.missing.arg=no value given for {0}
-err.internal.error=internal error: {0} {1} {2}
err.invalid.arg.for.option=invalid argument for option: {0}
err.option.after.class=option must be specified before classes: {0}
err.option.unsupported={0} not supported: {1}
err.profiles.msg=No profile information
-err.dot.output.path=invalid path: {0}
+err.invalid.path=invalid path: {0}
warn.invalid.arg=Invalid classname or pathname not exist: {0}
warn.split.package=package {0} defined in {1} {2}
--- a/langtools/test/tools/javac/6402516/CheckLocalElements.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/6402516/CheckLocalElements.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,19 +23,24 @@
/*
* @test
- * @bug 6402516
+ * @bug 6402516 8031569
* @summary need Trees.getScope(TreePath)
* @build Checker CheckLocalElements
* @run main CheckLocalElements
*/
+import java.io.IOException;
import java.util.*;
-import com.sun.source.tree.*;
+import java.util.regex.*;
+
import javax.lang.model.element.*;
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 static void main(String... args) throws Exception {
@@ -90,6 +95,16 @@
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) {
Element encl = e.getEnclosingElement();
return encl == null ? "" : encl.accept(qualNameVisitor, null);
--- a/langtools/test/tools/javac/6402516/Checker.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/6402516/Checker.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -67,6 +67,7 @@
for (CompilationUnitTree unit: units) {
TreePath p = new TreePath(unit);
s.scan(p, getTrees());
+ additionalChecks(getTrees(), unit);
}
task = null;
@@ -111,6 +112,9 @@
throw new IllegalStateException();
}
+ void additionalChecks(Trees trees, CompilationUnitTree topLevel) throws IOException {
+ }
+
void error(Scope s, String ref, String msg) {
System.err.println("Error: " + msg);
System.err.println("Scope: " + (s == null ? null : asList(s.getLocalElements())));
--- a/langtools/test/tools/javac/6402516/TestLocalElements.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/6402516/TestLocalElements.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
import java.util.List;
import java.io.*;
-
+//TOPLEVEL_SCOPE:List, Test2, Test; java.io.*, java.lang.*
class Test {
void m1(int m1_arg) {
String x = "x, m1_arg, super, this; List, Test2, Test; java.io.*, java.lang.*";
--- a/langtools/test/tools/javac/6889255/T6889255.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/6889255/T6889255.java Thu Jul 10 12:39:26 2014 -0700
@@ -32,7 +32,7 @@
import javax.tools.StandardLocation;
import com.sun.tools.javac.code.Flags;
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.Symtab;
import com.sun.tools.javac.code.Type;
@@ -43,6 +43,8 @@
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
+import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
+
public class T6889255 {
boolean testInterfaces = true;
boolean testSyntheticMethods = true;
@@ -380,11 +382,11 @@
if ((sym.flags() & Flags.INTERFACE) != 0 && !testInterfaces)
continue;
- for (Scope.Entry e = sym.members_field.elems; e != null; e = e.sibling) {
- System.err.println("Checking member " + e.sym);
- switch (e.sym.kind) {
+ for (Symbol s : sym.members_field.getSymbols(NON_RECURSIVE)) {
+ System.err.println("Checking member " + s);
+ switch (s.kind) {
case Kinds.TYP: {
- String name = e.sym.flatName().toString();
+ String name = s.flatName().toString();
if (!classes.contains(name)) {
classes.add(name);
work.add(name);
@@ -392,7 +394,7 @@
break;
}
case Kinds.MTH:
- verify((MethodSymbol) e.sym, expectNames);
+ verify((MethodSymbol) s, expectNames);
break;
}
--- a/langtools/test/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java Thu Jul 10 12:39:26 2014 -0700
@@ -45,7 +45,7 @@
*/
protected void compileAndTest(String sourceCode, String... classesToTest) throws Exception {
- Map<String, ? extends JavaFileObject> classes = compile(sourceCode);
+ Map<String, ? extends JavaFileObject> classes = compile(sourceCode).getClasses();
String fileName = ToolBox.getJavaFileNameFromSource(sourceCode);
for (String className : classesToTest) {
assertAttributePresent(ClassFile.read(classes.get(className).openInputStream()), fileName);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedPackageTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042261
+ * @summary Checking that deprecated attribute does not apply to classes of deprecated package.
+ * @library /tools/javac/lib ../lib
+ * @build DeprecatedPackageTest TestBase TestResult InMemoryFileManager ToolBox
+ * @run main DeprecatedPackageTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Deprecated_attribute;
+
+public class DeprecatedPackageTest extends TestResult {
+
+ private static final String[] sourceTest = new String[]{
+ "package deprecated;\n"
+ + "public class notDeprecated{}",
+ "package deprecated;\n"
+ + "public interface notDeprecated{}",
+ "package deprecated;\n"
+ + "public @interface notDeprecated{}",
+ "package deprecated;\n"
+ + "public enum notDeprecated{}"
+ };
+
+ private static final String CLASS_NAME = "deprecated.notDeprecated";
+
+ private static final String PACKAGE_INFO =
+ "@Deprecated\n" +
+ "package deprecated;";
+
+ public static void main(String[] args) throws TestFailedException {
+ new DeprecatedPackageTest().test();
+ }
+
+ private void test() throws TestFailedException {
+ try {
+ for (String src : sourceTest) {
+ test(PACKAGE_INFO, src);
+ test(PACKAGE_INFO.replaceAll("@Deprecated", "/** @deprecated */"), src);
+ }
+ } catch (Exception e) {
+ addFailure(e);
+ } finally {
+ checkStatus();
+ }
+ }
+
+ private void test(String package_info, String src) {
+ addTestCase(src);
+ printf("Testing test case: \n%s\n", src);
+ try {
+ ClassFile cf = ClassFile.read(compile(
+ new String[]{"package-info.java", package_info},
+ new String[]{"notDeprecated.java", src})
+ .getClasses().get(CLASS_NAME).openInputStream());
+ Deprecated_attribute attr =
+ (Deprecated_attribute) cf.getAttribute(Attribute.Deprecated);
+ assertNull(attr, "Class can not have deprecated attribute : " + CLASS_NAME);
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,314 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042261
+ * @summary Checking what attribute is generated by annotation Deprecated
+ * or javadoc deprecated for field, method, class(inner/local), interface.
+ * @library /tools/javac/lib ../lib
+ * @build DeprecatedTest TestBase TestResult InMemoryFileManager ToolBox
+ * @run main DeprecatedTest
+ */
+
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPoolException;
+import com.sun.tools.classfile.Deprecated_attribute;
+import com.sun.tools.classfile.Field;
+import com.sun.tools.classfile.InnerClasses_attribute;
+import com.sun.tools.classfile.InnerClasses_attribute.Info;
+import com.sun.tools.classfile.Method;
+
+import javax.tools.JavaFileObject;
+import java.io.IOException;
+import java.util.Map;
+
+public class DeprecatedTest extends TestResult {
+
+ private static final String[] sources = new String[]{
+ "@Deprecated public class deprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated public void deprecated() {}\n"
+ + "@Deprecated public int deprecated;\n"
+ + "public void notDeprecated() {}\n"
+ + "public int notDeprecated;\n"
+ + "public void f() {\n"
+ + " @Deprecated class deprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }\n"
+ + " class notDeprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }}\n"
+ + "}",
+ "@Deprecated public interface deprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated void deprecated01();\n"
+ + "void notDeprecated01();\n"
+ + "@Deprecated default void deprecated02() {}\n"
+ + "default void notDeprecated02() {}\n"
+ + "@Deprecated int deprecated = 0;\n"
+ + "int notDeprecated = 0;\n"
+ + "}",
+ "@Deprecated public enum deprecated {\n"
+ + "@Deprecated deprecated, notDeprecated;\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated public void deprecated() {}\n"
+ + "public void notDeprecated() {}\n"
+ + "public void f() {\n"
+ + " @Deprecated class deprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }\n"
+ + " class notDeprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }}\n"
+ + "}",
+ "@Deprecated public @interface deprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated int deprecated() default 0;\n"
+ + "int notDeprecated() default 0;\n"
+ + "@Deprecated int deprecated = 0;\n"
+ + "int notDeprecated = 0;\n"
+ + "}",
+ "public class notDeprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated public void deprecated() {}\n"
+ + "@Deprecated public int deprecated;\n"
+ + "public void notDeprecated() {}\n"
+ + "public int notDeprecated;\n"
+ + "public void f() {\n"
+ + " @Deprecated class deprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }\n"
+ + " class notDeprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }}\n"
+ + "}",
+ "public interface notDeprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated void deprecated01();\n"
+ + "void notDeprecated01();\n"
+ + "@Deprecated default void deprecated02() {}\n"
+ + "default void notDeprecated02() {}\n"
+ + "@Deprecated int deprecated = 0;\n"
+ + "int notDeprecated = 0;\n"
+ + "}",
+ "public enum notDeprecated {\n"
+ + "@Deprecated deprecated, notDeprecated;\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated public void deprecated() {}\n"
+ + "public void notDeprecated() {}\n"
+ + "public void f() {\n"
+ + " @Deprecated class deprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }\n"
+ + " class notDeprecatedLocal {\n"
+ + " @Deprecated int deprecated;\n"
+ + " @Deprecated void deprecated() {}\n"
+ + " int notDeprecated;\n"
+ + " void notDeprecated(){}\n"
+ + " }}\n"
+ + "}",
+ "public @interface notDeprecated {\n"
+ + "@Deprecated class deprecatedInner01 {}\n"
+ + "@Deprecated interface deprecatedInner02 {}\n"
+ + "@Deprecated enum deprecatedInner03 {}\n"
+ + "@Deprecated @interface deprecatedInner04 {}\n"
+ + "class notDeprecatedInner01 {}\n"
+ + "interface notDeprecatedInner02 {}\n"
+ + "enum notDeprecatedInner03 {}\n"
+ + "@interface notDeprecatedInner04 {}\n"
+ + "@Deprecated int deprecated() default 0;\n"
+ + "int notDeprecated() default 0;\n"
+ + "@Deprecated int deprecated = 0;\n"
+ + "int notDeprecated = 0;\n"
+ + "}"};
+
+ public static void main(String[] args) throws TestFailedException {
+ new DeprecatedTest().test();
+ }
+
+ public void test() throws TestFailedException {
+ try {
+ for (String src : sources) {
+ test(src);
+ test(src.replaceAll("@Deprecated", "/** @deprecated */"));
+ }
+ } catch (Exception e) {
+ addFailure(e);
+ } finally {
+ checkStatus();
+ }
+ }
+
+ private void test(String src) {
+ addTestCase(src);
+ printf("Testing test case :\n%s\n", src);
+ try {
+ Map<String, ? extends JavaFileObject> classes = compile(src).getClasses();
+ String outerClassName = classes.containsKey("deprecated")
+ ? "deprecated"
+ : "notDeprecated";
+ echo("Testing outer class : " + outerClassName);
+ ClassFile cf = ClassFile.read(classes.get(outerClassName).openInputStream());
+ Deprecated_attribute attr = (Deprecated_attribute)
+ cf.getAttribute(Attribute.Deprecated);
+ testAttribute(outerClassName, attr, cf);
+ testInnerClasses(cf, classes);
+ testMethods(cf);
+ testFields(cf);
+ } catch (Exception e) {
+ addFailure(e);
+ }
+ }
+
+ private void testInnerClasses(ClassFile cf, Map<String, ? extends JavaFileObject> classes)
+ throws ConstantPoolException, IOException {
+ InnerClasses_attribute innerAttr = (InnerClasses_attribute)
+ cf.getAttribute(Attribute.InnerClasses);
+ for (Info innerClass : innerAttr.classes) {
+ String innerClassName = cf.constant_pool.
+ getClassInfo(innerClass.inner_class_info_index).getName();
+ echo("Testing inner class : " + innerClassName);
+ ClassFile innerCf = ClassFile.read(classes.get(innerClassName).openInputStream());
+ Deprecated_attribute attr = (Deprecated_attribute)
+ innerCf.getAttribute(Attribute.Deprecated);
+ String innerClassSimpleName = innerClass.getInnerName(cf.constant_pool);
+ testAttribute(innerClassSimpleName, attr, innerCf);
+ if (innerClassName.contains("Local")) {
+ testMethods(innerCf);
+ testFields(innerCf);
+ }
+ }
+ }
+
+ private void testMethods(ClassFile cf)
+ throws ConstantPoolException {
+ for (Method m : cf.methods) {
+ String methodName = cf.constant_pool.getUTF8Value(m.name_index);
+ echo("Testing method : " + methodName);
+ Deprecated_attribute attr = (Deprecated_attribute)
+ m.attributes.get(Attribute.Deprecated);
+ testAttribute(methodName, attr, cf);
+ }
+ }
+
+ private void testFields(ClassFile cf) throws ConstantPoolException {
+ for (Field f : cf.fields) {
+ String fieldName = cf.constant_pool.getUTF8Value(f.name_index);
+ echo("Testing field : " + fieldName);
+ Deprecated_attribute attr = (Deprecated_attribute)
+ f.attributes.get(Attribute.Deprecated);
+ testAttribute(fieldName, attr, cf);
+ }
+ }
+
+ private void testAttribute(String name, Deprecated_attribute attr, ClassFile cf)
+ throws ConstantPoolException {
+ if (name.contains("deprecated")) {
+ testDeprecatedAttribute(name, attr, cf);
+ } else {
+ assertNull(attr, name + " should not have deprecated attribute");
+ }
+ }
+
+ private void testDeprecatedAttribute(String name, Deprecated_attribute attr, ClassFile cf)
+ throws ConstantPoolException {
+ assertNotNull(attr, name + " must have deprecated attribute");
+ assertEquals(0, attr.attribute_length,
+ "attribute_length should equal to 0");
+ assertEquals("Deprecated",
+ cf.constant_pool.getUTF8Value(attr.attribute_name_index),
+ name + " attribute_name_index");
+ }
+}
--- a/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestBase.java Thu Jul 10 12:39:26 2014 -0700
@@ -23,47 +23,85 @@
import java.io.File;
import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.io.PrintStream;
+import java.util.*;
+import java.util.function.Function;
import java.util.stream.Stream;
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.ToolProvider;
+import javax.tools.*;
import static java.lang.String.format;
+import static java.lang.System.lineSeparator;
+import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
+import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class TestBase {
- public Map<String, ? extends JavaFileObject> compile(String... sources) throws IOException,
+ public static final String LINE_SEPARATOR = lineSeparator();
+
+ private <S> InMemoryFileManager compile(
+ List<String> options,
+ Function<S, ? extends JavaFileObject> src2JavaFileObject,
+ List<S> sources)
+ throws IOException, CompilationException {
+
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ List<? extends JavaFileObject> src = sources.stream()
+ .map(src2JavaFileObject)
+ .collect(toList());
+
+ DiagnosticCollector<? super JavaFileObject> dc = new DiagnosticCollector<>();
+ try (InMemoryFileManager fileManager
+ = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
+ JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, dc, options, null, src);
+ boolean success = task.call();
+ if (!success) {
+ String errorMessage = dc.getDiagnostics().stream()
+ .map(Object::toString)
+ .collect(joining("\n"));
+ throw new CompilationException("Compilation Error\n\n" + errorMessage);
+ }
+ return fileManager;
+ }
+ }
+
+ public InMemoryFileManager compile(String... sources)
+ throws IOException, CompilationException {
+ return compile(emptyList(), sources);
+ }
+
+ /**
+ * @param options - compiler options
+ * @param sources
+ * @return map where key is className, value is corresponding ClassFile.
+ * @throws IOException
+ */
+ public InMemoryFileManager compile(List<String> options, String...sources)
+ throws IOException, CompilationException {
+ return compile(options, ToolBox.JavaSource::new, asList(sources));
+ }
+
+ public InMemoryFileManager compile(String[]... sources) throws IOException,
CompilationException {
return compile(emptyList(), sources);
}
/**
* @param options - compiler options
- * @param sources
+ * @param sources - sources[i][0] - name of file, sources[i][1] - sources
* @return map where key is className, value is corresponding ClassFile.
* @throws IOException
+ * @throws CompilationException
*/
- public Map<String, ? extends JavaFileObject> compile(List<String> options, String... sources) throws IOException,
- CompilationException {
-
- JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
- List<? extends JavaFileObject> src = Stream.of(sources).map(ToolBox.JavaSource::new).collect(toList());
-
- try (InMemoryFileManager fileManager = new InMemoryFileManager(compiler.getStandardFileManager(null, null, null))) {
- boolean success = compiler.getTask(null, fileManager, null, options, null, src).call();
- if (!success) throw new CompilationException("Compilation Error");
- return fileManager.getClasses();
- }
+ public InMemoryFileManager compile(List<String> options, String[]...sources)
+ throws IOException, CompilationException {
+ return compile(options, src -> new ToolBox.JavaSource(src[0], src[1]), asList(sources));
}
public void assertEquals(Object actual, Object expected, String message) {
if (!Objects.equals(actual, expected))
- throw new AssertionFailedException(format("%s%nGot: %s, Expected: ", message, actual, expected));
+ throw new AssertionFailedException(format("%s%nGot: %s, Expected: %s", message, actual, expected));
}
public void assertNull(Object actual, String message) {
@@ -80,18 +118,43 @@
assertEquals(actual, true, message);
}
+ public void assertFalse(boolean actual, String message) {
+ assertEquals(actual, false, message);
+ }
+
+ public File getSourceDir() {
+ return new File(System.getProperty("test.src", "."));
+ }
+
+ public File getClassDir() {
+ return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()));
+ }
+
public File getSourceFile(String fileName) {
- return new File(System.getProperty("test.src", "."), fileName);
+ return new File(getSourceDir(), fileName);
}
public File getClassFile(String fileName) {
- return new File(System.getProperty("test.classes", TestBase.class.getResource(".").getPath()), fileName);
+ return new File(getClassDir(), fileName);
}
public File getClassFile(Class clazz) {
return getClassFile(clazz.getName().replace(".", "/") + ".class");
}
+ public void echo(String message) {
+ System.err.println(message.replace("\n", LINE_SEPARATOR));
+ }
+
+ public void printf(String template, Object...args) {
+ System.err.printf(template, Stream.of(args)
+ .map(Objects::toString)
+ .map(m -> m.replace("\n", LINE_SEPARATOR))
+ .collect(toList())
+ .toArray());
+
+ }
+
public static class CompilationException extends Exception {
public CompilationException(String message) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/classfiles/attributes/lib/TestResult.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import static java.lang.String.format;
+import static java.util.stream.Collectors.joining;
+
+public class TestResult extends TestBase {
+
+ private final List<Info> testCases;
+
+ public TestResult() {
+ testCases = new ArrayList<>();
+ testCases.add(new Info("Global test info"));
+ }
+
+ public void addTestCase(String src) {
+ testCases.add(new Info(src));
+ }
+
+ public String errorMessage() {
+ return testCases.stream().filter(Info::isFailed)
+ .map(tc -> format("Failure in test case:\n%s\n%s", tc.info(),
+ (tc.asserts.size() > 0 ? tc.getAssertMessage() + "\n" : "")
+ + tc.getErrorMessage()))
+ .collect(joining("\n"));
+ }
+
+ @Override
+ public void assertEquals(Object actual, Object expected, String message) {
+ getLastTestCase().assertEquals(actual, expected, message);
+ }
+
+ @Override
+ public void assertNull(Object actual, String message) {
+ getLastTestCase().assertEquals(actual, null, message);
+ }
+
+ @Override
+ public void assertNotNull(Object actual, String message) {
+ getLastTestCase().assertNotNull(actual, message);
+ }
+
+ @Override
+ public void assertFalse(boolean actual, String message) {
+ getLastTestCase().assertEquals(actual, false, message);
+ }
+
+ @Override
+ public void assertTrue(boolean actual, String message) {
+ getLastTestCase().assertEquals(actual, true, message);
+ }
+
+ public void addFailure(Throwable th) {
+ getLastTestCase().addFailure(th);
+ }
+
+ private Info getLastTestCase() {
+ if (testCases.size() == 1) {
+ throw new IllegalStateException("Test case should be created");
+ }
+ return testCases.get(testCases.size() - 1);
+ }
+
+ public void checkStatus() throws TestFailedException {
+ if (testCases.stream().anyMatch(Info::isFailed)) {
+ echo(errorMessage());
+ throw new TestFailedException("Test failed");
+ }
+ }
+
+ private class Info {
+
+ private final String info;
+ private final List<String> asserts;
+ private final List<Throwable> errors;
+
+ private Info(String info) {
+ this.info = info;
+ asserts = new ArrayList<>();
+ errors = new ArrayList<>();
+ }
+
+ public String info() {
+ return info;
+ }
+
+ public boolean isFailed() {
+ return !asserts.isEmpty() || !errors.isEmpty();
+ }
+
+ public void addFailure(Throwable th) {
+ errors.add(th);
+ printf("[ERROR] : %s\n", getStackTrace(th));
+ }
+
+ public void addFailure(String message) {
+ asserts.add(message);
+ printf("[ASSERT] : %s\n", message);
+ }
+
+ public void assertEquals(Object actual, Object expected, String message) {
+ echo("Testing : " + message);
+ if (!Objects.equals(actual, expected)) {
+ addFailure(message + ": Got: " + actual + ", " + "Expected: " + expected);
+ }
+ }
+
+ public void assertNotNull(Object actual, String message) {
+ echo("Testing : " + message);
+ if (actual == null) {
+ addFailure(message + " : Expected not null value");
+ }
+ }
+
+ public String getAssertMessage() {
+ return asserts.stream()
+ .map(failure -> "[ASSERT] : " + failure)
+ .collect(joining("\n"));
+ }
+
+ public String getErrorMessage() {
+ return errors.stream()
+ .map(throwable ->
+ format("[ERROR] : %s", getStackTrace(throwable)))
+ .collect(joining("\n"));
+ }
+
+ public String getStackTrace(Throwable throwable) {
+ StringWriter stringWriter = new StringWriter();
+ try (PrintWriter printWriter = new PrintWriter(stringWriter)) {
+ throwable.printStackTrace(printWriter);
+ }
+ return stringWriter.toString();
+ }
+ }
+
+ public static class TestFailedException extends Exception {
+ public TestFailedException(String message) {
+ super(message);
+ }
+ }
+}
--- a/langtools/test/tools/javac/enum/AbstractEmptyEnum.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/AbstractEmptyEnum.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5009601
* @summary empty enum cannot be abstract
* @author Joseph D. Darcy
*
- * @compile/fail AbstractEmptyEnum.java
+ * @compile/fail/ref=AbstractEmptyEnum.out -XDrawDiagnostics AbstractEmptyEnum.java
*/
public enum AbstractEmptyEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/AbstractEmptyEnum.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+AbstractEmptyEnum.java:10:8: compiler.err.does.not.override.abstract: AbstractEmptyEnum, m(), AbstractEmptyEnum
+1 error
--- a/langtools/test/tools/javac/enum/Enum2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/Enum2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,8 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @summary enums: an enumeration type may not be extended
* @author gafter
- *
- * @compile/fail Enum2.java
+ * @compile/fail/ref=Enum2.out -XDrawDiagnostics Enum2.java
*/
public class Enum2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/Enum2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+Enum2.java:10:29: compiler.err.cant.inherit.from.final: Enum2.e1
+Enum2.java:10:12: compiler.err.enum.types.not.extensible
+2 errors
--- a/langtools/test/tools/javac/enum/FauxEnum1.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/FauxEnum1.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5009574
* @summary verify java.lang.Enum can't be directly subclassed
* @author Joseph D. Darcy
*
- * @compile/fail FauxEnum1.java
+ * @compile/fail/ref=FauxEnum1.out -XDrawDiagnostics FauxEnum1.java
*/
public class FauxEnum1 extends java.lang.Enum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/FauxEnum1.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxEnum1.java:10:8: compiler.err.enum.no.subclassing
+1 error
--- a/langtools/test/tools/javac/enum/FauxEnum3.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/FauxEnum3.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5009574
* @summary verify an enum type can't be directly subclassed
* @author Joseph D. Darcy
*
- * @compile/fail FauxEnum3.java
+ * @compile/fail/ref=FauxEnum3.out -XDrawDiagnostics FauxEnum3.java
*/
public class FauxEnum3 extends SpecializedEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/FauxEnum3.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxEnum3.java:10:8: compiler.err.enum.types.not.extensible
+1 error
--- a/langtools/test/tools/javac/enum/FauxSpecialEnum1.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/FauxSpecialEnum1.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5009601
* @summary verify specialized enum classes can't be abstract
* @author Joseph D. Darcy
*
- * @compile/fail FauxSpecialEnum1.java
+ * @compile/fail/ref=FauxSpecialEnum1.out -XDrawDiagnostics FauxSpecialEnum1.java
*/
public enum FauxSpecialEnum1 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/FauxSpecialEnum1.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxSpecialEnum1.java:14:5: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: FauxSpecialEnum1$2, test(), compiler.misc.anonymous.class: FauxSpecialEnum1$2
+1 error
--- a/langtools/test/tools/javac/enum/FauxSpecialEnum2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/FauxSpecialEnum2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5009601
* @summary verify specialized enum classes can't be abstract
* @author Joseph D. Darcy
*
- * @compile/fail FauxSpecialEnum2.java
+ * @compile/fail/ref=FauxSpecialEnum2.out -XDrawDiagnostics FauxSpecialEnum2.java
*/
public enum FauxSpecialEnum2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/FauxSpecialEnum2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+FauxSpecialEnum2.java:12:5: compiler.err.does.not.override.abstract: compiler.misc.anonymous.class: FauxSpecialEnum2$1, test(), compiler.misc.anonymous.class: FauxSpecialEnum2$1
+1 error
--- a/langtools/test/tools/javac/enum/LocalEnum.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/LocalEnum.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,9 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5019609
* @summary javac fails to reject local enums
* @author gafter
- *
- * @compile/fail LocalEnum.java
+ * @compile/fail/ref=LocalEnum.out -XDrawDiagnostics LocalEnum.java
*/
public class LocalEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/LocalEnum.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+LocalEnum.java:11:9: compiler.err.local.enum
+1 error
--- a/langtools/test/tools/javac/enum/NestedEnum.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NestedEnum.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5071831
* @summary javac allows enum in an inner class
* @author gafter
*
- * @compile/fail NestedEnum.java
+ * @compile/fail/ref=NestedEnum.out -XDrawDiagnostics NestedEnum.java
*/
class NestedEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NestedEnum.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NestedEnum.java:12:9: compiler.err.enums.must.be.static
+1 error
--- a/langtools/test/tools/javac/enum/NoFinal.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NoFinal.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5097250 5087624
* @summary Finalize methods on enums must be compile time error
* @author Peter von der Ah\u00e9
- * @compile/fail NoFinal.java
+ * @compile/fail/ref=NoFinal.out -XDrawDiagnostics NoFinal.java
*/
enum NoFinal {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NoFinal.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal.java:11:24: compiler.err.enum.no.finalize
+1 error
--- a/langtools/test/tools/javac/enum/NoFinal2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NoFinal2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5097250 5087624
* @summary Finalize methods on enums must be compile time error
* @author Peter von der Ah\u00e9
- * @compile/fail NoFinal2.java
+ * @compile/fail/ref=NoFinal2.out -XDrawDiagnostics NoFinal2.java
*/
enum NoFinal2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NoFinal2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal2.java:11:20: compiler.err.enum.no.finalize
+1 error
--- a/langtools/test/tools/javac/enum/NoFinal3.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NoFinal3.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5097250 5087624
* @summary Finalize methods on enums must be compile time error
* @author Peter von der Ah\u00e9
- * @compile/fail NoFinal3.java
+ * @compile/fail/ref=NoFinal3.out -XDrawDiagnostics NoFinal3.java
*/
enum NoFinal3 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NoFinal3.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal3.java:11:17: compiler.err.enum.no.finalize
+1 error
--- a/langtools/test/tools/javac/enum/NoFinal4.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NoFinal4.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5097250 5087624
* @summary Finalize methods on enums must be compile time error
* @author Peter von der Ah\u00e9
- * @compile/fail NoFinal4.java
+ * @compile/fail/ref=NoFinal4.out -XDrawDiagnostics NoFinal4.java
*/
enum NoFinal4 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NoFinal4.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal4.java:11:18: compiler.err.enum.no.finalize
+1 error
--- a/langtools/test/tools/javac/enum/NoFinal5.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/NoFinal5.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2004, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 5097250 5087624
* @summary Finalize methods on enums must be compile time error
* @author Peter von der Ah\u00e9
- * @compile/fail NoFinal5.java
+ * @compile/fail/ref=NoFinal5.out -XDrawDiagnostics NoFinal5.java
*/
enum NoFinal5 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/NoFinal5.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NoFinal5.java:11:10: compiler.err.enum.no.finalize
+1 error
--- a/langtools/test/tools/javac/enum/T5081785.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/T5081785.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,43 +1,31 @@
/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
+ * @test /nodynamiccopyright/
+ * @bug 5081785
+ * @summary Empty Enums allowed in non-static contexts
+ * @author Peter von der Ah\u00e9
+ * @compile/fail/ref=T5081785.out -XDrawDiagnostics T5081785.java
*/
-/*
- * @test
- * @bug 5081785
- *
- * @summary Empty Enums allowed in non-static contexts
- * @author Peter von der Ah\u00e9
- *
- * @compile/fail T5081785.java
- * @compile/fail T5081785a.java
- * @compile/fail T5081785b.java
- * @compile/fail T5081785c.java
- */
-
-class A {
+class A1 {
public void check() {
class Foo {
enum STRENGTH{};
};
}
}
+
+class A2 {
+ public A2 check() {
+ return new A2() { enum STRENGTH{}; };
+ }
+}
+
+class A3 {
+ Object o = new Object() { enum STRENGTH{}; };
+}
+
+class A4 {
+ class B {
+ enum C { X, Y, Z }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/T5081785.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,5 @@
+T5081785.java:29:9: compiler.err.enums.must.be.static
+T5081785.java:12:13: compiler.err.enums.must.be.static
+T5081785.java:19:27: compiler.err.enums.must.be.static
+T5081785.java:24:31: compiler.err.enums.must.be.static
+4 errors
--- a/langtools/test/tools/javac/enum/T5081785a.java Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
- public A check() {
- return new A() { enum STRENGTH{}; };
- }
-}
--- a/langtools/test/tools/javac/enum/T5081785b.java Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
- Object o = new Object() { enum STRENGTH{}; };
-}
--- a/langtools/test/tools/javac/enum/T5081785c.java Thu Jul 10 12:13:35 2014 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-class A {
- class B {
- enum C { X, Y, Z }
- }
-}
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum1.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum1.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6209839
* @summary Illegal forward reference to enum constants allowed by javac
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum1.java
+ * @compile/fail/ref=TestEnum1.out -XDrawDiagnostics TestEnum1.java
*/
enum TestEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum1.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+TestEnum1.java:11:39: compiler.err.illegal.enum.static.ref
+TestEnum1.java:12:40: compiler.err.illegal.enum.static.ref
+2 errors
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6209839
* @summary Illegal forward reference to enum constants allowed by javac
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum2.java
+ * @compile/fail/ref=TestEnum2.out -XDrawDiagnostics TestEnum2.java
*/
enum TestEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+TestEnum2.java:13:36: compiler.err.illegal.enum.static.ref
+TestEnum2.java:14:36: compiler.err.illegal.enum.static.ref
+2 errors
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum3.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum3.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6209839
* @summary Illegal forward reference to enum constants allowed by javac
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum3.java
+ * @compile/fail/ref=TestEnum3.out -XDrawDiagnostics TestEnum3.java
*/
enum TestEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum3.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum3.java:13:34: compiler.err.illegal.enum.static.ref
+1 error
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum4.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum4.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6209839
* @summary Illegal forward reference to enum constants allowed by javac
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum4.java
+ * @compile/fail/ref=TestEnum4.out -XDrawDiagnostics TestEnum4.java
*/
enum TestEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum4.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum4.java:14:24: compiler.err.illegal.enum.static.ref
+1 error
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum5.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum5.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6209839
* @summary Illegal forward reference to enum constants allowed by javac
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum5.java
+ * @compile/fail/ref=TestEnum5.out -XDrawDiagnostics TestEnum5.java
*/
enum TestEnum {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum5.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum5.java:15:20: compiler.err.illegal.enum.static.ref
+1 error
--- a/langtools/test/tools/javac/enum/forwardRef/TestEnum6.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum6.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 6424491
* @summary Cannot initialise nested enums
* @author Peter von der Ah\u00e9
- * @compile/fail TestEnum6.java
+ * @compile/fail/ref=TestEnum6.out -XDrawDiagnostics TestEnum6.java
*/
public enum TestEnum6 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/enum/forwardRef/TestEnum6.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+TestEnum6.java:10:18: compiler.err.illegal.self.ref
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8043926/T8043926.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8043926
+ * @summary javac, code valid in 7 is not compiling for 8
+ * @compile T8043926.java
+ */
+class T8043926 {
+ interface Iface<T1> {}
+
+ static class Impl implements Iface<Impl> {}
+
+ static class Acceptor<T2 extends Iface<T2>> {
+ public Acceptor(T2 obj) {}
+ }
+
+ void test(Impl impl) {
+ Acceptor<?> acceptor1 = new Acceptor<>(impl);
+ Acceptor<? extends Object> acceptor2 = new Acceptor<>(impl);
+ }
+}
--- a/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 1999, 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
+ * @test /nodynamiccopyright/
* @bug 4249111
* @summary 'new' of inner class should not be allowed unless outer is constructed
*
- * @compile/fail NewBeforeOuterConstructed.java
+ * @compile/fail/ref=NewBeforeOuterConstructed.out -XDrawDiagnostics NewBeforeOuterConstructed.java
*/
import java.io.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NewBeforeOuterConstructed.java:27:21: compiler.err.cant.ref.before.ctor.called: this
+1 error
--- a/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,32 +1,9 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- * @test
+ * @test /nodynamiccopyright/
* @bug 4689058
* @summary unverifiable code for implicit outer in super constructor call
*
- * @compile/fail NewBeforeOuterConstructed2.java
+ * @compile/fail/ref=NewBeforeOuterConstructed2.out -XDrawDiagnostics NewBeforeOuterConstructed2.java
*/
public class NewBeforeOuterConstructed2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/implicitThis/NewBeforeOuterConstructed2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NewBeforeOuterConstructed2.java:20:35: compiler.err.cant.ref.before.ctor.called: this
+1 error
--- a/langtools/test/tools/javac/importChecks/ImportCanonical1.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/importChecks/ImportCanonical1.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4462745
* @summary compiler permits to import class given by its non-canonical name
* @author gafter
*
- * @compile/fail ImportCanonical1.java ImportCanonical2.java
+ * @compile/fail/ref=ImportCanonical1.out -XDrawDiagnostics ImportCanonical1.java ImportCanonical2.java
*/
package p1;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importChecks/ImportCanonical1.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+ImportCanonical2.java:25:13: compiler.err.import.requires.canonical: p1.A1.I
+1 error
--- a/langtools/test/tools/javac/importChecks/ImportIsFullyQualified.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/importChecks/ImportIsFullyQualified.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4335264
* @summary Verify that import-on-demand must be fully qualified.
* @author maddox
*
- * @compile/fail ImportIsFullyQualified.java
+ * @compile/fail/ref=ImportIsFullyQualified.out -XDrawDiagnostics ImportIsFullyQualified.java
*/
import java.awt.*;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importChecks/ImportIsFullyQualified.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+ImportIsFullyQualified.java:11:1: compiler.err.doesnt.exist: JobAttributes
+1 error
--- a/langtools/test/tools/javac/importChecks/InvalidImportsNoClasses.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/importChecks/InvalidImportsNoClasses.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4312063
* @summary Verify that nonexistent imports detected when no classes declared in compilation unit.
* @author maddox
*
- * @compile/fail InvalidImportsNoClasses.java
+ * @compile/fail/ref=InvalidImportsNoClasses.out -XDrawDiagnostics InvalidImportsNoClasses.java
*/
import nonexistent.pack.cls;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importChecks/InvalidImportsNoClasses.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+InvalidImportsNoClasses.java:10:24: compiler.err.doesnt.exist: nonexistent.pack
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importOnDemand/ImportOnDemandConflicts.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+/* @test /nodynamiccopyright/
+ * @compile/fail/ref=ImportOnDemandConflicts.out -XDrawDiagnostics p1/Object.java p1/String.java p2/Boolean.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importOnDemand/ImportOnDemandConflicts.out Thu Jul 10 12:39:26 2014 -0700
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importOnDemand/p1/Object.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,5 @@
+package p1;
+
+public class Object {
+ public static void test() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importOnDemand/p1/String.java Thu Jul 10 12:39:26 2014 -0700
@@ -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);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importOnDemand/p2/Boolean.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,7 @@
+package p2;
+
+public class Boolean {
+ public static Boolean valueOf(boolean b) {
+ return null;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest1.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest1.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest1 {
+ interface SAM<T> {
+ T action(T t);
+ }
+
+ <T> T m(SAM<T> op) {
+ return null;
+ }
+
+ class B {
+ B x() {
+ return this;
+ }
+ }
+
+ class C {}
+
+ void foo(B arg) {}
+ void foo(C arg) {}
+
+ void bar() {
+ foo(m(arg -> new B()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest1.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+IgnoreLambdaBodyDuringResolutionTest1.java:29:9: compiler.err.ref.ambiguous: foo, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.B), IgnoreLambdaBodyDuringResolutionTest1, kindname.method, foo(IgnoreLambdaBodyDuringResolutionTest1.C), IgnoreLambdaBodyDuringResolutionTest1
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8033483
+ * @summary Should ignore nested lambda bodies during overload resolution
+ * @compile/fail/ref=IgnoreLambdaBodyDuringResolutionTest2.out -XDrawDiagnostics IgnoreLambdaBodyDuringResolutionTest2.java
+ */
+
+class IgnoreLambdaBodyDuringResolutionTest2 {
+ interface SAM<S> {
+ boolean test(S t);
+ }
+
+ <I, T extends I> I bar(final T l) {
+ return null;
+ }
+
+ class D<D1, D2> {
+ void foo() {
+ m(bar(e -> false));
+ }
+
+ void m(Class<D1> arg) {}
+ void m(SAM<D2> arg) {}
+ }
+
+ class F {
+ void foo() {
+ m(bar((String e) -> false));
+ }
+
+ <F1> void m(Class<F1> arg) {}
+ <F2> void m(SAM<F2> arg) {}
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8033483/IgnoreLambdaBodyDuringResolutionTest2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,6 @@
+IgnoreLambdaBodyDuringResolutionTest2.java:19:13: compiler.err.ref.ambiguous: m, kindname.method, m(java.lang.Class<D1>), IgnoreLambdaBodyDuringResolutionTest2.D, kindname.method, m(IgnoreLambdaBodyDuringResolutionTest2.SAM<D2>), IgnoreLambdaBodyDuringResolutionTest2.D
+IgnoreLambdaBodyDuringResolutionTest2.java:19:18: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Object))
+IgnoreLambdaBodyDuringResolutionTest2.java:19:14: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Class<D1>, <any>, kindname.class, IgnoreLambdaBodyDuringResolutionTest2.D<D1,D2>, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class)))
+IgnoreLambdaBodyDuringResolutionTest2.java:28:13: compiler.err.ref.ambiguous: m, kindname.method, <F1>m(java.lang.Class<F1>), IgnoreLambdaBodyDuringResolutionTest2.F, kindname.method, <F2>m(IgnoreLambdaBodyDuringResolutionTest2.SAM<F2>), IgnoreLambdaBodyDuringResolutionTest2.F
+IgnoreLambdaBodyDuringResolutionTest2.java:28:14: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.assignment.exists: I,T, (compiler.misc.not.a.functional.intf: java.lang.Class))
+5 errors
--- a/langtools/test/tools/javac/lib/DPrinter.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/lib/DPrinter.java Thu Jul 10 12:39:26 2014 -0700
@@ -31,6 +31,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -337,6 +338,8 @@
printList(label, (List) item);
} else if (item instanceof Name) {
printName(label, (Name) item);
+ } else if (item instanceof Scope) {
+ printScope(label, (Scope) item);
} else {
printString(label, String.valueOf(item));
}
@@ -356,7 +359,7 @@
out.print(label);
out.print(": [");
String sep = "";
- for (Symbol sym: scope.getElements()) {
+ for (Symbol sym: scope.getSymbols()) {
out.print(sep);
out.print(sym.name);
sep = ",";
@@ -370,19 +373,7 @@
out.println(label);
indent(+1);
- printImplClass(scope, Scope.class);
- 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);
- }
- }
+ printFullScopeImpl(scope);
indent(-1);
break;
}
@@ -390,6 +381,72 @@
}
}
+ 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) {
printString(label, Pretty.toSimpleString(tree, maxSrcLength));
}
@@ -552,6 +609,23 @@
}
}
+ 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 defaultstate="collapsed" desc="JCTree visitor methods">
--- a/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/scope/7017664/CompoundScopeTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -117,13 +117,13 @@
boolean subAdded = false;
for (int sc = 0 ; sc < 3 ; sc ++) {
if (scopeNesting[sc][i]) {
- sub.addSubScope(scopes[sc]);
+ sub.prependSubScope(scopes[sc]);
if (!subAdded) {
- root.addSubScope(sub);
+ root.prependSubScope(sub);
subAdded = true;
}
} else {
- root.addSubScope(scopes[sc]);
+ root.prependSubScope(scopes[sc]);
}
}
log("testing scope: " + root);
@@ -145,7 +145,7 @@
* Create a scope containing a given number of synthetic symbols
*/
Scope createScope(int nelems) {
- Scope s = new Scope(symtab.noSymbol);
+ WriteableScope s = WriteableScope.create(symtab.noSymbol);
for (int i = 0 ; i < nelems ; i++) {
Symbol sym = new TypeVariableSymbol(0, names.fromString("s" + i), null, null);
s.enter(sym);
@@ -181,7 +181,7 @@
elems :
filter(elems, sf);
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);
allSymbols = allSymbols.tail;
found.append(s);
@@ -204,7 +204,7 @@
filter(shadowedEntry.getValue(), sf);
int expectedCount = shadowed.length();
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);
shadowed = shadowed.tail;
count++;
--- a/langtools/test/tools/javac/scope/7017664/ImplementationCacheTest.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/scope/7017664/ImplementationCacheTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -98,7 +98,7 @@
MethodSymbol I_m = null;
- for (Symbol sym : i.members().getElements()) {
+ for (Symbol sym : i.members().getSymbols()) {
if (sym.name.contentEquals("m")) {
I_m = (MethodSymbol)sym;
}
--- a/langtools/test/tools/javac/scope/HashCollisionTest.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/scope/HashCollisionTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,16 +25,21 @@
* @test
* @bug 7004029
* @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.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.code.*;
import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.JavacFileManager;
-import static com.sun.tools.javac.code.Kinds.*;
public class HashCollisionTest {
public static void main(String... args) throws Exception {
@@ -47,12 +52,13 @@
JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
names = Names.instance(context); // Name.Table impls tied to an instance of Names
symtab = Symtab.instance(context);
+ trees = JavacTrees.instance(context);
// determine hashMask for an empty scope
- Scope emptyScope = new Scope(symtab.unnamedPackage); // any owner will do
- Field sHashMask = Scope.class.getDeclaredField("hashMask");
- sHashMask.setAccessible(true);
- scopeHashMask = sHashMask.getInt(emptyScope);
+ Scope emptyScope = WriteableScope.create(symtab.unnamedPackage); // any owner will do
+ Field field = emptyScope.getClass().getDeclaredField("hashMask");
+ field.setAccessible(true);
+ scopeHashMask = field.getInt(emptyScope);
log("scopeHashMask: " + scopeHashMask);
// 1. determine the Name.hashCode of "Entry", and therefore the index of
@@ -92,7 +98,7 @@
// 4. Create a package containing a nested class using the name from 2
PackageSymbol p = new PackageSymbol(names.fromString("p"), symtab.rootPackage);
- p.members_field = new Scope(p);
+ p.members_field = WriteableScope.create(p);
ClassSymbol inner = createClass(innerName, p);
// we'll need this later when we "rename" cn
ClassSymbol outer = createClass(outerName, p);
@@ -100,42 +106,25 @@
// 5. Create a star-import scope
log ("createStarImportScope");
- // if StarImportScope exists, use it, otherwise, for testing legacy code,
- // fall back on ImportScope
- Scope starImportScope;
- Method importAll;
PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
- try {
- Class<?> c = Class.forName("com.sun.tools.javac.code.Scope$StarImportScope");
- Constructor ctor = c.getDeclaredConstructor(new Class[] { Symbol.class });
- importAll = c.getDeclaredMethod("importAll", new Class[] { Scope.class });
- starImportScope = (Scope) ctor.newInstance(new Object[] { pkg });
- } catch (ClassNotFoundException e) {
- starImportScope = new ImportScope(pkg);
- importAll = null;
- }
+ StarImportScope starImportScope = new StarImportScope(pkg);
dump("initial", starImportScope);
// 6. Insert the contents of the package from 4.
- Scope p_members = p.members();
- if (importAll != null) {
- importAll.invoke(starImportScope, p_members);
- } else {
- Scope fromScope = p_members;
- Scope toScope = starImportScope;
- // 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);
+ Scope fromScope = p.members();
+ ImportFilter typeFilter = new ImportFilter() {
+ @Override
+ public boolean accepts(Scope origin, Symbol sym) {
+ return sym.kind == Kinds.TYP;
}
- }
+ };
+ starImportScope.importAll(fromScope, fromScope, typeFilter, false);
dump("imported p", starImportScope);
// 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);
/*
@@ -149,11 +138,11 @@
outer.members_field.enter(inner);
// 9. Lookup Entry
- Scope.Entry e = starImportScope.lookup(entry);
- dump("final", starImportScope);
+ Symbol found = starImportScope.findFirst(entry);
+ if (found != ce)
+ throw new Exception("correct symbol not found: " + entry + "; found=" + found);
- if (e.sym == null)
- throw new Exception("symbol not found: " + entry);
+ dump("final", starImportScope);
}
/*
@@ -170,7 +159,7 @@
*/
ClassSymbol createClass(Name name, Symbol owner) {
ClassSymbol sym = new ClassSymbol(0, name, owner);
- sym.members_field = new Scope(sym);
+ sym.members_field = WriteableScope.create(sym);
if (owner != symtab.unnamedPackage)
owner.members().enter(sym);
return sym;
@@ -180,58 +169,16 @@
* Dump the contents of a scope to System.err.
*/
void dump(String label, Scope s) throws Exception {
- dump(label, s, System.err);
- }
-
- /**
- * Dump the contents of a scope to a stream.
- */
- 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);
- 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();
+ PrintWriter pw = new PrintWriter(System.err);
+ new DPrinter(pw, trees).printScope(label, s);
+ pw.flush();
}
- /**
- * 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 + "]")
- : "")
- + ")";
- }
+ Object readField(Object scope, String fieldName) throws Exception {
+ Field field = scope.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
- <T> int indexOf(T[] array, T item) {
- for (int i = 0; i < array.length; i++) {
- if (array[i] == item)
- return i;
- }
- return -1;
+ return field.get(scope);
}
/**
@@ -246,4 +193,5 @@
Names names;
Symtab symtab;
+ Trees trees;
}
--- a/langtools/test/tools/javac/scope/StarImportTest.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/scope/StarImportTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,14 +27,17 @@
* @summary Basher for star-import scopes
*/
-import java.lang.reflect.*;
import java.util.*;
import java.util.List;
-import com.sun.tools.javac.util.*;
+
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.file.JavacFileManager;
+import com.sun.tools.javac.util.*;
+
import static com.sun.tools.javac.code.Kinds.*;
public class StarImportTest {
@@ -87,13 +90,9 @@
System.err.print(msg);
System.err.print(": ");
String sep = "(";
- for (Scope.Entry se = s.elems; se != null; se = se.sibling) {
- for (Scope.Entry e = se; e.sym != null; e = e.next()) {
- System.err.print(sep + e.sym.name + ":" + e.sym);
- sep = ",";
- }
- System.err.print(")");
- sep = ", (";
+ for (Symbol sym : s.getSymbols()) {
+ System.err.print(sep + sym.name + ":" + sym);
+ sep = ",";
}
System.err.println();
}
@@ -171,7 +170,7 @@
int count = rgen.nextInt(MAX_SETUP_PACKAGE_COUNT);
log("setup: creating package " + name + " with " + count + " entries");
PackageSymbol p = new PackageSymbol(name, symtab.rootPackage);
- p.members_field = new Scope(p);
+ p.members_field = WriteableScope.create(p);
for (int i = 0; i < count; i++) {
String outer = name + "c" + i;
String suffix = random(null, "$Entry", "$Entry2");
@@ -213,38 +212,21 @@
log ("createStarImportScope");
PackageSymbol pkg = new PackageSymbol(names.fromString("pkg"), symtab.rootPackage);
- // if StarImportScope exists, use it, otherwise, for testing legacy code,
- // 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;
- }
+ starImportScope = new StarImportScope(pkg);
starImportModel = new Model();
for (Symbol imp: imports) {
Scope members = imp.members();
- if (importAll != null) {
// log("importAll", members);
- importAll.invoke(starImportScope, members);
- } else {
- Scope fromScope = members;
- 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(members, members, new ImportFilter() {
+ @Override
+ public boolean accepts(Scope origin, Symbol t) {
+ return t.kind == TYP;
}
- }
+ }, false);
- for (Scope.Entry e = members.elems; e != null; e = e.sibling) {
- starImportModel.enter(e.sym);
+ for (Symbol sym : members.getSymbols()) {
+ starImportModel.enter(sym);
}
}
@@ -260,9 +242,9 @@
log ("test");
List<ClassSymbol> nestedClasses = new LinkedList<ClassSymbol>();
for (PackageSymbol p: packages) {
- for (Scope.Entry se = p.members_field.elems; se != null; se = se.sibling) {
- if (se.sym.name.toString().contains("$"))
- nestedClasses.add((ClassSymbol) se.sym);
+ for (Symbol sym : p.members_field.getSymbols()) {
+ if (sym.name.toString().contains("$"))
+ nestedClasses.add((ClassSymbol) sym);
}
}
@@ -283,8 +265,7 @@
// determine new owner
Name outerName = names.fromString(s.substring(0, dollar));
// log(sym + " owner: " + sym.owner, sym.owner.members());
- Scope.Entry outerEntry = sym.owner.members().lookup(outerName);
- ClassSymbol outer = (ClassSymbol) outerEntry.sym;
+ ClassSymbol outer = (ClassSymbol)sym.owner.members().findFirst(outerName);
// log("outer: " + outerName + " " + outer);
// remove from package
@@ -302,7 +283,7 @@
ClassSymbol createClass(Name name, Symbol owner) {
ClassSymbol sym = new ClassSymbol(0, name, owner);
- sym.members_field = new Scope(sym);
+ sym.members_field = WriteableScope.create(sym);
if (owner != symtab.unnamedPackage)
owner.members().enter(sym);
return sym;
@@ -318,7 +299,7 @@
List<Symbol> imports = new ArrayList<Symbol>();
int nextClassSerial;
- Scope starImportScope;
+ StarImportScope starImportScope;
Model starImportModel;
}
@@ -355,9 +336,8 @@
void check(Scope scope) {
// First, check all entries in scope are in map
int bogusCount = 0;
- for (Scope.Entry se = scope.elems; se != null; se = se.sibling) {
- Symbol sym = se.sym;
- if (sym.owner != se.scope.owner) {
+ for (Symbol sym : scope.getSymbols()) {
+ if (sym.owner != scope.getOrigin(sym).owner) {
if (bogus.contains(sym)) {
bogusCount++;
} else {
@@ -380,16 +360,14 @@
// Second, check all entries in map are in scope
for (Map.Entry<Name,Set<Symbol>> me: map.entrySet()) {
Name name = me.getKey();
- Scope.Entry se = scope.lookup(name);
- assert (se != null);
- if (se.sym == null) {
+ if (scope.findFirst(name) == null) {
error("check: no entries found for " + name + " in scope");
continue;
}
nextSym:
for (Symbol sym: me.getValue()) {
- for (Scope.Entry e = se; e.sym != null; e = e.next()) {
- if (sym == e.sym)
+ for (Symbol s : scope.getSymbolsByName(name)) {
+ if (sym == s)
continue nextSym;
}
error("check: symbol " + sym + " not found in scope");
--- a/langtools/test/tools/javac/staticImport/6537020/T6537020.out Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/staticImport/6537020/T6537020.out Thu Jul 10 12:39:26 2014 -0700
@@ -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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/MakeTypeTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8042239
+ * @summary Verify that TreeMaker.Type(Type) can handle all reasonable types
+ * @library /tools/javac/lib
+ * @build JavacTestingAbstractProcessor MakeTypeTest
+ * @compile/process/ref=MakeTypeTest.out -processor MakeTypeTest MakeTypeTest.java
+ */
+
+import java.lang.annotation.*;
+import java.util.*;
+
+import javax.annotation.processing.RoundEnvironment;
+import javax.lang.model.element.*;
+import javax.lang.model.type.*;
+
+import com.sun.source.tree.*;
+import com.sun.source.util.*;
+import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import com.sun.tools.javac.tree.JCTree.JCExpression;
+import com.sun.tools.javac.tree.TreeMaker;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.List;
+
+public class MakeTypeTest extends JavacTestingAbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (!roundEnv.processingOver())
+ return false;
+
+ JavacTask.instance(processingEnv).addTaskListener(new TaskListener() {
+ @Override
+ public void started(TaskEvent e) {
+ }
+ @Override
+ public void finished(TaskEvent e) {
+ if (e.getKind() == TaskEvent.Kind.ANALYZE &&
+ e.getTypeElement().getQualifiedName().contentEquals("MakeTypeTest")) {
+ doTest();
+ }
+ }
+ });
+
+ return false;
+ }
+
+ void doTest() {
+ //go through this file, look for @TestType and verify TreeMaker.Type behavior:
+ Context ctx = ((JavacProcessingEnvironment) processingEnv).getContext();
+ JavacTrees trees = JavacTrees.instance(ctx);
+ TypeElement testType = processingEnv.getElementUtils().getTypeElement("MakeTypeTest");
+ TreePath path = trees.getPath(testType);
+
+ Set<TypeKind> unseenTypeKinds = EnumSet.allOf(TypeKind.class);
+
+ new TreePathScanner<Void, Void>() {
+ @Override
+ public Void visitVariable(VariableTree node, Void p) {
+ handleDecl(new TreePath(getCurrentPath(), node.getType()));
+ return super.visitVariable(node, p);
+ }
+
+ @Override
+ public Void visitMethod(MethodTree node, Void p) {
+ if (node.getReturnType() != null)
+ handleDecl(new TreePath(getCurrentPath(), node.getReturnType()));
+ return super.visitMethod(node, p);
+ }
+
+ @Override
+ public Void visitTypeParameter(TypeParameterTree node, Void p) {
+ TypeVariable type = (TypeVariable) trees.getTypeMirror(getCurrentPath());
+ TreePath aBoundPath = new TreePath(getCurrentPath(), node.getBounds().get(0));
+ handleDecl(aBoundPath, (Type) type.getUpperBound());
+ return super.visitTypeParameter(node, p);
+ }
+
+ void handleDecl(TreePath typePath) {
+ handleDecl(typePath, (Type) trees.getTypeMirror(typePath));
+ }
+
+ void handleDecl(TreePath typePath, Type type) {
+ Element decl = trees.getElement(typePath.getParentPath());
+ TestType testType = decl.getAnnotation(TestType.class);
+
+ if (testType == null) return ;
+
+ if (testType.nested() >= 0) {
+ ClassType ct = (ClassType) type;
+ type = ct.getTypeArguments().get(testType.nested());
+ }
+
+ JCExpression typeExpr = TreeMaker.instance(ctx).Type(type);
+
+ if (!typeExpr.getKind().equals(testType.expectedKind())) {
+ throw new IllegalStateException("was=" + typeExpr + ", kind=" +
+ typeExpr.getKind() + "; expected kind: " +
+ testType.expectedKind() + "; type=" + type);
+ }
+ unseenTypeKinds.remove(type.getKind());
+ }
+
+ }.scan(path, null);
+
+ unseenTypeKinds.removeAll(Arrays.asList(TypeKind.NONE, TypeKind.NULL, TypeKind.ERROR,
+ TypeKind.PACKAGE, TypeKind.EXECUTABLE, TypeKind.OTHER));
+
+ if (!unseenTypeKinds.isEmpty())
+ throw new IllegalStateException("Unhandled types=" + unseenTypeKinds);
+
+ System.err.println("done.");
+ }
+
+ //the following defines the Types that should be passed into TreeMaker.Type and
+ //the expected resulting Tree kind:
+
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ boolean f1;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ byte f2;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ char f3;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ double f4;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ float f5;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ int f6;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ long f7;
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ short f8;
+ @TestType(expectedKind=Tree.Kind.PARAMETERIZED_TYPE)
+ List<? extends String> f9;
+ @TestType(expectedKind=Tree.Kind.ARRAY_TYPE)
+ int[] fa;
+ @TestType(expectedKind=Tree.Kind.EXTENDS_WILDCARD, nested = 0)
+ List<? extends String> fb;
+ @TestType(expectedKind=Tree.Kind.SUPER_WILDCARD, nested = 0)
+ List<? super String> fc;
+ @TestType(expectedKind=Tree.Kind.UNBOUNDED_WILDCARD, nested = 0)
+ List<?> fd;
+
+ @TestType(expectedKind=Tree.Kind.PRIMITIVE_TYPE)
+ void voidMethod() {
+ try {
+ voidMethod();
+ } catch (@TestType(expectedKind=Tree.Kind.UNION_TYPE) NullPointerException |
+ IllegalStateException ex) {
+ }
+ }
+
+ class WithTypeParam<@TestType(expectedKind=Tree.Kind.INTERSECTION_TYPE)
+ T extends CharSequence & Runnable> {
+ @TestType(expectedKind=Tree.Kind.IDENTIFIER)
+ T voidMethod() {
+ return null;
+ }
+ }
+
+}
+
+//TreeMaker.Type will be tested for the type the element annotated by this annotation
+@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD,
+ ElementType.PARAMETER, ElementType.TYPE_PARAMETER})
+@interface TestType {
+ //the expected Tree kind of the Tree that will be returned from TreeMaker.Type for the type
+ public Tree.Kind expectedKind();
+ //if >=0, the current type will be interpreted as a ClassType and the type to test will be
+ //the given type argument:
+ public int nested() default -1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/tree/MakeTypeTest.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,1 @@
+done.
--- a/langtools/test/tools/javac/unicode/NonasciiDigit.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/unicode/NonasciiDigit.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4707960 6183529
* @summary javac accepts unicode digits - sometimes crashing
* @author gafter
*
- * @compile/fail NonasciiDigit.java
+ * @compile/fail/ref=NonasciiDigit.out -XDrawDiagnostics NonasciiDigit.java
*/
public class NonasciiDigit {
public static void main(String[] args) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/NonasciiDigit.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NonasciiDigit.java:12:26: compiler.err.illegal.char: \uff11
+1 error
--- a/langtools/test/tools/javac/unicode/NonasciiDigit2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/unicode/NonasciiDigit2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,33 +1,10 @@
/*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4707960 6183529
* @summary javac accepts unicode digits - sometimes crashing
* @author gafter
*
- * @compile/fail NonasciiDigit2.java
+ * @compile/fail/ref=NonasciiDigit2.out -XDrawDiagnostics NonasciiDigit2.java
*/
public class NonasciiDigit2 {
public static void main(String[] args) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/NonasciiDigit2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+NonasciiDigit2.java:12:18: compiler.err.illegal.nonascii.digit
+1 error
--- a/langtools/test/tools/javac/unicode/SupplementaryJavaID2.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID2.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,34 +1,11 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4914724
* @summary Ensure that the invalid surrogate sequence, as the start of an identifier,
* causes a compilation failure
* @author Naoto Sato
*
- * @compile/fail SupplementaryJavaID2.java
+ * @compile/fail/ref=SupplementaryJavaID2.out -XDrawDiagnostics SupplementaryJavaID2.java
*/
public class SupplementaryJavaID2 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID2.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,3 @@
+SupplementaryJavaID2.java:12:14: compiler.err.illegal.char: \ud801
+SupplementaryJavaID2.java:12:24: compiler.err.expected: token.identifier
+2 errors
--- a/langtools/test/tools/javac/unicode/SupplementaryJavaID3.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID3.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,34 +1,11 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 4914724
* @summary Ensure that the invalid surrogate sequence, as the part of an identifier,
* causes a compilation failure
* @author Naoto Sato
*
- * @compile/fail SupplementaryJavaID3.java
+ * @compile/fail/ref=SupplementaryJavaID3.out -XDrawDiagnostics SupplementaryJavaID3.java
*/
public class SupplementaryJavaID3 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID3.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,2 @@
+SupplementaryJavaID3.java:12:23: compiler.err.illegal.char: \ud801
+1 error
--- a/langtools/test/tools/javac/unicode/TripleQuote.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/unicode/TripleQuote.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,36 +1,14 @@
/*
- * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * @test
+ * @test /nodynamiccopyright/
* @bug 1265387
* @summary ''' and '\u0027' are not legal char literals.
* @author turnidge
*
- * @compile/fail TripleQuote.java
+ * @compile/fail/ref=TripleQuote.out -XDrawDiagnostics TripleQuote.java
*/
public
class TripleQuote {
char c = '\u0027';
+ char d = ''';
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/TripleQuote.out Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,7 @@
+TripleQuote.java:12:14: compiler.err.empty.char.lit
+TripleQuote.java:12:20: compiler.err.empty.char.lit
+TripleQuote.java:12:21: compiler.err.unclosed.char.lit
+TripleQuote.java:13:14: compiler.err.empty.char.lit
+TripleQuote.java:13:15: compiler.err.empty.char.lit
+TripleQuote.java:13:16: compiler.err.unclosed.char.lit
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/varargs/T8049075/VarargsAndWildcardParameterizedTypeTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8049075
+ * @summary javac, wildcards and generic vararg method invocation not accepted
+ * @compile VarargsAndWildcardParameterizedTypeTest.java
+ */
+
+class VarargsAndWildcardParameterizedTypeTest {
+ interface I<T> {
+ String m(T... t);
+ }
+
+ void m() {
+ I<? super Integer> i = null;
+ i.m(Integer.valueOf(1), Integer.valueOf(1));
+ }
+}
--- a/langtools/test/tools/javac/varargs/warning/Warn4.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/varargs/warning/Warn4.java Thu Jul 10 12:39:26 2014 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6945418 6993978 8006694
+ * @bug 6945418 6993978 8006694 7196160
* @summary Project Coin: Simplified Varargs Method Invocation
* temporarily workaround combo tests are causing time out in several platforms
* @author mcimadamore
--- a/langtools/test/tools/javac/varargs/warning/Warn5.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/javac/varargs/warning/Warn5.java Thu Jul 10 12:39:26 2014 -0700
@@ -23,7 +23,7 @@
/**
* @test
- * @bug 6993978 7097436 8006694
+ * @bug 6993978 7097436 8006694 7196160
* @summary Project Coin: Annotation to reduce varargs warnings
* temporarily workaround combo tests are causing time out in several platforms
* @author mcimadamore
--- a/langtools/test/tools/jdeps/APIDeps.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/jdeps/APIDeps.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8015912 8029216
+ * @bug 8015912 8029216 8048063
* @summary Test -apionly and -jdkinternals options
* @build m.Bar m.Foo m.Gee b.B c.C c.I d.D e.E f.F g.G
* @run main APIDeps
@@ -81,27 +81,39 @@
new String[] {"compact1", "compact3", testDirBasename},
new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
test(new File(mDir, "Foo.class"),
+ new String[] {"c.I", "e.E", "f.F"},
+ new String[] {testDirBasename},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P"});
+ test(new File(mDir, "Foo.class"),
new String[] {"c.I", "e.E", "f.F", "m.Bar"},
new String[] {testDirBasename},
- new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
+ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-filter:none", "-P"});
test(new File(mDir, "Gee.class"),
- new String[] {"g.G", "sun.misc.Lock"},
- new String[] {testDirBasename, "JDK internal API"},
- new String[] {"-classpath", testDir.getPath(), "-verbose"});
+ new String[] {"g.G", "sun.misc.Lock", "com.sun.tools.classfile.ClassFile",
+ "com.sun.management.ThreadMXBean", "com.sun.source.tree.BinaryTree"},
+ new String[] {testDirBasename, "JDK internal API", "compact3", ""},
+ new String[] {"-classpath", testDir.getPath(), "-verbose", "-P"});
// -jdkinternals
test(new File(mDir, "Gee.class"),
- new String[] {"sun.misc.Lock"},
+ new String[] {"sun.misc.Lock", "com.sun.tools.classfile.ClassFile"},
new String[] {"JDK internal API"},
new String[] {"-jdkinternals"});
// -jdkinternals parses all classes on -classpath and the input arguments
test(new File(mDir, "Gee.class"),
- new String[] {"sun.misc.Lock", "sun.misc.Unsafe"},
+ new String[] {"com.sun.tools.jdeps.Main", "com.sun.tools.classfile.ClassFile",
+ "sun.misc.Lock", "sun.misc.Unsafe"},
new String[] {"JDK internal API"},
new String[] {"-classpath", testDir.getPath(), "-jdkinternals"});
// parse only APIs
- // parse only APIs
+ test(mDir,
+ new String[] {"java.lang.Object", "java.lang.String",
+ "java.util.Set",
+ "c.C", "d.D", "c.I", "e.E"},
+ new String[] {"compact1", testDirBasename},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:class", "-P", "-apionly"});
+
test(mDir,
new String[] {"java.lang.Object", "java.lang.String",
"java.util.Set",
--- a/langtools/test/tools/jdeps/Basic.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/jdeps/Basic.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8003562 8005428 8015912 8027481
+ * @bug 8003562 8005428 8015912 8027481 8048063
* @summary Basic tests for jdeps tool
* @build Test p.Foo p.Bar javax.activity.NotCompactProfile
* @run main Basic
@@ -86,6 +86,16 @@
new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
new String[] {"compact1", "compact1", "not found", "not found"},
new String[] {"-verbose:class"});
+ // test -filter:none option
+ test(new File(testDir, "p"),
+ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"});
+ // test -filter:archive option
+ test(new File(testDir, "p"),
+ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"});
// test -p option
test(new File(testDir, "Test.class"),
new String[] {"p.Foo", "p.Bar"},
@@ -100,11 +110,12 @@
new String[] {"java.lang"},
new String[] {"compact1"},
new String[] {"-verbose:package", "-e", "java\\.lang\\..*"});
+
// test -classpath and -include options
test(null,
- new String[] {"java.lang", "java.util",
- "java.lang.management", "javax.crypto"},
- new String[] {"compact1", "compact1", "compact3", "compact1"},
+ new String[] {"java.lang", "java.util", "java.lang.management",
+ "javax.activity", "javax.crypto"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
new String[] {"-classpath", testDir.getPath(), "-include", "p.+|Test.class"});
test(new File(testDir, "Test.class"),
new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeps/DotFileTest.java Thu Jul 10 12:39:26 2014 -0700
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8003562
+ * @summary Basic tests for jdeps -dotoutput option
+ * @build Test p.Foo p.Bar javax.activity.NotCompactProfile
+ * @run main DotFileTest
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
+import java.util.regex.*;
+
+public class DotFileTest {
+ private static boolean symbolFileExist = initProfiles();
+ private static boolean initProfiles() {
+ // check if ct.sym exists; if not use the profiles.properties file
+ Path home = Paths.get(System.getProperty("java.home"));
+ if (home.endsWith("jre")) {
+ home = home.getParent();
+ }
+ Path ctsym = home.resolve("lib").resolve("ct.sym");
+ boolean symbolExists = ctsym.toFile().exists();
+ if (!symbolExists) {
+ Path testSrcProfiles =
+ Paths.get(System.getProperty("test.src", "."), "profiles.properties");
+ if (!testSrcProfiles.toFile().exists())
+ throw new Error(testSrcProfiles + " does not exist");
+ System.out.format("%s doesn't exist.%nUse %s to initialize profiles info%n",
+ ctsym, testSrcProfiles);
+ System.setProperty("jdeps.profiles", testSrcProfiles.toString());
+ }
+ return symbolExists;
+ }
+
+ public static void main(String... args) throws Exception {
+ int errors = 0;
+ errors += new DotFileTest().run();
+ if (errors > 0)
+ throw new Exception(errors + " errors found");
+ }
+
+ final Path dir;
+ final Path dotoutput;
+ DotFileTest() {
+ this.dir = Paths.get(System.getProperty("test.classes", "."));
+ this.dotoutput = dir.resolve("dots");
+ }
+
+ int run() throws IOException {
+ File testDir = dir.toFile();
+ // test a .class file
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang", "p"},
+ new String[] {"compact1", "not found"});
+ // test a directory
+ // also test non-SE javax.activity class dependency
+ test(new File(testDir, "p"),
+ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
+ new String[] {"-classpath", testDir.getPath()});
+ // test class-level dependency output
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
+ new String[] {"compact1", "compact1", "not found", "not found"},
+ new String[] {"-verbose:class"});
+ // test -filter:none option
+ test(new File(testDir, "p"),
+ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto", "p"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1", "p"},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:none"});
+ // test -filter:archive option
+ test(new File(testDir, "p"),
+ new String[] {"java.lang", "java.util", "java.lang.management", "javax.activity", "javax.crypto"},
+ new String[] {"compact1", "compact1", "compact3", testDir.getName(), "compact1"},
+ new String[] {"-classpath", testDir.getPath(), "-verbose:package", "-filter:archive"});
+ // test -p option
+ test(new File(testDir, "Test.class"),
+ new String[] {"p.Foo", "p.Bar"},
+ new String[] {"not found", "not found"},
+ new String[] {"-verbose:class", "-p", "p"});
+ // test -e option
+ test(new File(testDir, "Test.class"),
+ new String[] {"p.Foo", "p.Bar"},
+ new String[] {"not found", "not found"},
+ new String[] {"-verbose:class", "-e", "p\\..*"});
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang"},
+ new String[] {"compact1"},
+ new String[] {"-verbose:package", "-e", "java\\.lang\\..*"});
+ // test -classpath options
+ test(new File(testDir, "Test.class"),
+ new String[] {"java.lang.Object", "java.lang.String", "p.Foo", "p.Bar"},
+ new String[] {"compact1", "compact1", testDir.getName(), testDir.getName()},
+ new String[] {"-v", "-classpath", testDir.getPath()});
+
+ testSummary(new File(testDir, "Test.class"),
+ new String[] {"rt.jar", testDir.getName()},
+ new String[] {"compact1", ""},
+ new String[] {"-classpath", testDir.getPath()});
+ testSummary(new File(testDir, "Test.class"),
+ new String[] {"java.lang", "p"},
+ new String[] {"compact1", testDir.getName()},
+ new String[] {"-v", "-classpath", testDir.getPath()});
+ return errors;
+ }
+
+ void test(File file, String[] expect, String[] profiles) throws IOException {
+ test(file, expect, profiles, new String[0]);
+ }
+
+ void test(File file, String[] expect, String[] profiles, String[] options)
+ throws IOException
+ {
+ Path dotfile = dotoutput.resolve(file.toPath().getFileName().toString() + ".dot");
+
+ List<String> args = new ArrayList<>(Arrays.asList(options));
+ args.add("-dotoutput");
+ args.add(dotoutput.toString());
+ if (file != null) {
+ args.add(file.getPath());
+ }
+
+ Map<String,String> result = jdeps(args, dotfile);
+ checkResult("dependencies", expect, result.keySet());
+
+ // with -P option
+ List<String> argsWithDashP = new ArrayList<>();
+ argsWithDashP.add("-dotoutput");
+ argsWithDashP.add(dotoutput.toString());
+ argsWithDashP.add("-P");
+ argsWithDashP.addAll(args);
+
+ result = jdeps(argsWithDashP, dotfile);
+ checkResult("profiles", expect, profiles, result);
+ }
+
+ void testSummary(File file, String[] expect, String[] profiles, String[] options)
+ throws IOException
+ {
+ Path dotfile = dotoutput.resolve("summary.dot");
+
+ List<String> args = new ArrayList<>(Arrays.asList(options));
+ args.add("-dotoutput");
+ args.add(dotoutput.toString());
+ if (file != null) {
+ args.add(file.getPath());
+ }
+
+ Map<String,String> result = jdeps(args, dotfile);
+ checkResult("dependencies", expect, result.keySet());
+
+ // with -P option
+ List<String> argsWithDashP = new ArrayList<>();
+ argsWithDashP.add("-dotoutput");
+ argsWithDashP.add(dotoutput.toString());
+ argsWithDashP.add("-P");
+ argsWithDashP.addAll(args);
+
+ result = jdeps(argsWithDashP, dotfile);
+ checkResult("profiles", expect, profiles, result);
+ }
+
+ Map<String,String> jdeps(List<String> args, Path dotfile) throws IOException {
+ if (Files.exists(dotoutput)) {
+ try (DirectoryStream<Path> stream = Files.newDirectoryStream(dotoutput)) {
+ for (Path p : stream) {
+ Files.delete(p);
+ }
+ }
+ Files.delete(dotoutput);
+ }
+ // invoke jdeps
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ System.err.println("jdeps " + args);
+ int rc = com.sun.tools.jdeps.Main.run(args.toArray(new String[0]), pw);
+ pw.close();
+ String out = sw.toString();
+ if (!out.isEmpty())
+ System.err.println(out);
+ if (rc != 0)
+ throw new Error("jdeps failed: rc=" + rc);
+
+ // check output files
+ if (Files.notExists(dotfile)) {
+ throw new RuntimeException(dotfile + " doesn't exist");
+ }
+ return parse(dotfile);
+ }
+ private static Pattern pattern = Pattern.compile("(.*) -> +([^ ]*) (.*)");
+ private Map<String,String> parse(Path outfile) throws IOException {
+ Map<String,String> result = new LinkedHashMap<>();
+ for (String line : Files.readAllLines(outfile)) {
+ line = line.replace('"', ' ').replace(';', ' ');
+ Matcher pm = pattern.matcher(line);
+ if (pm.find()) {
+ String origin = pm.group(1).trim();
+ String target = pm.group(2).trim();
+ String module = pm.group(3).replace('(', ' ').replace(')', ' ').trim();
+ result.put(target, module);
+ }
+ }
+ return result;
+ }
+
+ void checkResult(String label, String[] expect, Collection<String> found) {
+ List<String> list = Arrays.asList(expect);
+ if (!isEqual(list, found))
+ error("Unexpected " + label + " found: '" + found + "', expected: '" + list + "'");
+ }
+
+ void checkResult(String label, String[] expect, String[] profiles, Map<String,String> result) {
+ if (expect.length != profiles.length)
+ error("Invalid expected names and profiles");
+
+ // check the dependencies
+ checkResult(label, expect, result.keySet());
+ // check profile information
+ checkResult(label, profiles, result.values());
+ for (int i=0; i < expect.length; i++) {
+ String profile = result.get(expect[i]);
+ if (!profile.equals(profiles[i]))
+ error("Unexpected profile: '" + profile + "', expected: '" + profiles[i] + "'");
+ }
+ }
+
+ boolean isEqual(List<String> expected, Collection<String> found) {
+ if (expected.size() != found.size())
+ return false;
+
+ List<String> list = new ArrayList<>(found);
+ list.removeAll(expected);
+ return list.isEmpty();
+ }
+
+ void error(String msg) {
+ System.err.println("Error: " + msg);
+ errors++;
+ }
+
+ int errors;
+}
--- a/langtools/test/tools/jdeps/m/Gee.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/jdeps/m/Gee.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,5 +26,7 @@
class Gee extends g.G {
public sun.misc.Lock lock;
+ public com.sun.tools.classfile.ClassFile cf; // @jdk.Exported(false)
+ public com.sun.source.tree.BinaryTree tree; // @jdk.Exported
+ public com.sun.management.ThreadMXBean mxbean; // @jdk.Exported on package-info
}
-
--- a/langtools/test/tools/jdeps/p/Bar.java Thu Jul 10 12:13:35 2014 -0700
+++ b/langtools/test/tools/jdeps/p/Bar.java Thu Jul 10 12:39:26 2014 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,4 +30,8 @@
public javax.crypto.Cipher getCiper() {
return null;
}
+
+ public Foo foo() {
+ return new Foo();
+ }
}