mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-17 11:23:19 +00:00
Merge
This commit is contained in:
commit
47c06db65a
@ -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 @@ import com.sun.tools.javac.comp.Env;
|
||||
* @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 @@ public class JavacScope implements com.sun.source.tree.Scope {
|
||||
return null;
|
||||
}
|
||||
public Iterable<? extends Element> getLocalElements() {
|
||||
return env.toplevel.starImportScope.getElements();
|
||||
return env.toplevel.starImportScope.getSymbols();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -456,10 +456,9 @@ public class JavacTrees extends DocTrees {
|
||||
}
|
||||
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 @@ public class JavacTrees extends DocTrees {
|
||||
|
||||
/** @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 @@ public class JavacTrees extends DocTrees {
|
||||
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 @@ public class JavacTrees extends DocTrees {
|
||||
// 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 @@ public class JavacTrees extends DocTrees {
|
||||
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 class JavacTrees extends DocTrees {
|
||||
}
|
||||
|
||||
public JavacScope getScope(TreePath path) {
|
||||
return new JavacScope(getAttrContext(path));
|
||||
return JavacScope.create(getAttrContext(path));
|
||||
}
|
||||
|
||||
public String getDocComment(TreePath path) {
|
||||
|
||||
@ -37,6 +37,7 @@ import javax.tools.StandardJavaFileManager;
|
||||
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 @@ public class ClassFinder {
|
||||
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 @@ public class ClassFinder {
|
||||
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 @@ public class ClassFinder {
|
||||
*/
|
||||
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) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -33,19 +33,21 @@ import java.util.concurrent.Callable;
|
||||
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 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
|
||||
/** If this is a class or package, its members, otherwise null.
|
||||
*/
|
||||
public Scope members() {
|
||||
public WriteableScope members() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -475,15 +477,13 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
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 abstract class Symbol extends AnnoConstruct implements Element {
|
||||
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 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
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 abstract class Symbol extends AnnoConstruct implements Element {
|
||||
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 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
return name.isEmpty() && owner != null;
|
||||
}
|
||||
|
||||
public Scope members() {
|
||||
public WriteableScope members() {
|
||||
if (completer != null) complete();
|
||||
return members_field;
|
||||
}
|
||||
@ -910,7 +910,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
/** a scope for all class members; variables, methods and inner classes
|
||||
* 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 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
return flags_field;
|
||||
}
|
||||
|
||||
public Scope members() {
|
||||
public WriteableScope members() {
|
||||
if (completer != null) complete();
|
||||
return members_field;
|
||||
}
|
||||
@ -1397,15 +1397,13 @@ public abstract class Symbol extends AnnoConstruct implements Element {
|
||||
|
||||
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 abstract class Symbol extends AnnoConstruct implements Element {
|
||||
*/
|
||||
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;
|
||||
|
||||
@ -34,6 +34,7 @@ import javax.lang.model.element.ElementVisitor;
|
||||
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 @@ public class Symtab {
|
||||
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 @@ public class Symtab {
|
||||
|
||||
// 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 @@ public class Symtab {
|
||||
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,
|
||||
|
||||
@ -1050,6 +1050,10 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
|
||||
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.
|
||||
|
||||
@ -403,7 +403,7 @@ public class Types {
|
||||
}
|
||||
|
||||
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 @@ public class Types {
|
||||
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 @@ public class Types {
|
||||
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 @@ public class Types {
|
||||
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 @@ public class Types {
|
||||
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 class Types {
|
||||
}
|
||||
|
||||
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 @@ public class Types {
|
||||
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 @@ public class Types {
|
||||
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 class Types {
|
||||
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)) {
|
||||
|
||||
@ -690,7 +690,7 @@ public class Annotate {
|
||||
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 &&
|
||||
|
||||
@ -37,6 +37,7 @@ import com.sun.source.tree.TreeVisitor;
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
// 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 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
// 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 @@ public class Attr extends JCTree.Visitor {
|
||||
}
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
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 @@ public class Attr extends JCTree.Visitor {
|
||||
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,
|
||||
|
||||
@ -27,6 +27,7 @@ package com.sun.tools.javac.comp;
|
||||
|
||||
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 @@ public class AttrContext {
|
||||
|
||||
/** The scope of local symbols.
|
||||
*/
|
||||
Scope scope = null;
|
||||
WriteableScope scope = null;
|
||||
|
||||
/** The number of enclosing `static' modifiers.
|
||||
*/
|
||||
@ -87,7 +88,7 @@ public class AttrContext {
|
||||
|
||||
/** 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 class AttrContext {
|
||||
public Iterable<Symbol> getLocalElements() {
|
||||
if (scope == null)
|
||||
return List.nil();
|
||||
return scope.getElements();
|
||||
return scope.getSymbols();
|
||||
}
|
||||
|
||||
boolean lastResolveVarargs() {
|
||||
|
||||
@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
|
||||
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.util.List;
|
||||
|
||||
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.*;
|
||||
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 @@ public class Check {
|
||||
* @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 @@ public class Check {
|
||||
* @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 @@ public class Check {
|
||||
* @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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
|
||||
/** 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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
// 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 @@ public class Check {
|
||||
}
|
||||
if (implmeth == null || implmeth == absmeth) {
|
||||
undef = absmeth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2336,10 +2322,10 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
}
|
||||
|
||||
//...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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
}
|
||||
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
}
|
||||
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 @@ public class Check {
|
||||
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 @@ public class Check {
|
||||
/** 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 class Check {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkImportsResolvable(final JCCompilationUnit toplevel) {
|
||||
for (final JCImport imp : toplevel.getImports()) {
|
||||
if (!imp.staticImport || !imp.qualid.hasTag(SELECT))
|
||||
continue;
|
||||
final JCFieldAccess select = (JCFieldAccess) imp.qualid;
|
||||
final Symbol origin;
|
||||
if (select.name == names.asterisk || (origin = TreeInfo.symbol(select.selected)) == null || origin.kind != TYP)
|
||||
continue;
|
||||
|
||||
JavaFileObject prev = log.useSource(toplevel.sourcefile);
|
||||
try {
|
||||
TypeSymbol site = (TypeSymbol) TreeInfo.symbol(select.selected);
|
||||
if (!checkTypeContainsImportableElement(site, site, toplevel.packge, select.name, new HashSet<Symbol>())) {
|
||||
log.error(imp.pos(), "cant.resolve.location",
|
||||
KindName.STATIC,
|
||||
select.name, List.<Type>nil(), List.<Type>nil(),
|
||||
Kinds.typeKindName(TreeInfo.symbol(select.selected).type),
|
||||
TreeInfo.symbol(select.selected).type);
|
||||
}
|
||||
} finally {
|
||||
log.useSource(prev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkTypeContainsImportableElement(TypeSymbol tsym, TypeSymbol origin, PackageSymbol packge, Name name, Set<Symbol> processed) {
|
||||
if (tsym == null || !processed.add(tsym))
|
||||
return false;
|
||||
|
||||
// also search through inherited names
|
||||
if (checkTypeContainsImportableElement(types.supertype(tsym.type).tsym, origin, packge, name, processed))
|
||||
return true;
|
||||
|
||||
for (Type t : types.interfaces(tsym.type))
|
||||
if (checkTypeContainsImportableElement(t.tsym, origin, packge, name, processed))
|
||||
return true;
|
||||
|
||||
for (Symbol sym : tsym.members().getSymbolsByName(name)) {
|
||||
if (sym.isStatic() &&
|
||||
staticImportAccessible(sym, packge) &&
|
||||
sym.isMemberOf(origin, types)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// is the sym accessible everywhere in packge?
|
||||
public boolean staticImportAccessible(Symbol sym, PackageSymbol packge) {
|
||||
int flags = (int)(sym.flags() & AccessFlags);
|
||||
switch (flags) {
|
||||
default:
|
||||
case PUBLIC:
|
||||
return true;
|
||||
case PRIVATE:
|
||||
return false;
|
||||
case 0:
|
||||
case PROTECTED:
|
||||
return sym.packge() == packge;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -376,9 +376,8 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
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 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
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 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class DeferredAttr extends JCTree.Visitor {
|
||||
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);
|
||||
|
||||
@ -191,7 +191,7 @@ public class Enter extends JCTree.Visitor {
|
||||
*/
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
* 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 @@ public class Enter extends JCTree.Visitor {
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
@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 @@ public class Enter extends JCTree.Visitor {
|
||||
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 @@ public class Enter extends JCTree.Visitor {
|
||||
// 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);
|
||||
|
||||
@ -30,6 +30,7 @@ package com.sun.tools.javac.comp;
|
||||
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 @@ public class Flow {
|
||||
|
||||
/** 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 @@ public class Flow {
|
||||
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
|
||||
|
||||
@ -31,7 +31,7 @@ import com.sun.tools.javac.tree.TreeMaker;
|
||||
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 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
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 @@ public class LambdaToMethod extends TreeTranslator {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
|
||||
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 com.sun.tools.javac.tree.EndPosTable;
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
}
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
* @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 @@ public class Lower extends TreeTranslator {
|
||||
* @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 @@ public class Lower extends TreeTranslator {
|
||||
/** 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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
* 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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
* 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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
|
||||
// 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 @@ public class Lower extends TreeTranslator {
|
||||
} 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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
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 @@ public class Lower extends TreeTranslator {
|
||||
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<>();
|
||||
|
||||
@ -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 com.sun.tools.javac.tree.JCTree.*;
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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,44 +206,47 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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() {
|
||||
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);
|
||||
|
||||
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);
|
||||
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 {
|
||||
|
||||
// enter non-types before annotations that might use them
|
||||
annotate.earlier(new Annotate.Worker() {
|
||||
Set<Symbol> processed = new HashSet<>();
|
||||
boolean found = false;
|
||||
private final ImportFilter delegate;
|
||||
private final Set<Symbol> maskedOut;
|
||||
|
||||
public String toString() {
|
||||
return "import static " + tsym + "." + name;
|
||||
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))
|
||||
return;
|
||||
@ -312,47 +256,21 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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() &&
|
||||
staticImportAccessible(sym, packge) &&
|
||||
sym.isMemberOf(origin, types)) {
|
||||
found = true;
|
||||
if (sym.kind != TYP) {
|
||||
toScope.enter(sym, sym.owner.members(), origin.members(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
doImport(tsym);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
abstract void doImport(TypeSymbol tsym);
|
||||
}
|
||||
|
||||
/** 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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
* 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 class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
}
|
||||
|
||||
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 class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
}
|
||||
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
*/
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
|
||||
// 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
|
||||
|
||||
@ -28,6 +28,7 @@ package com.sun.tools.javac.comp;
|
||||
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 class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
*/
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
*/
|
||||
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 @@ public class Resolve {
|
||||
}
|
||||
|
||||
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;
|
||||
@ -2319,42 +2310,6 @@ public class Resolve {
|
||||
kindName(sym), sym, sym.location());
|
||||
}
|
||||
|
||||
/* ***************************************************************************
|
||||
* Debugging
|
||||
****************************************************************************/
|
||||
|
||||
/** print all scopes starting with scope s and proceeding outwards.
|
||||
* used for debugging.
|
||||
*/
|
||||
public void printscopes(Scope s) {
|
||||
while (s != null) {
|
||||
if (s.owner != null)
|
||||
System.err.print(s.owner + ": ");
|
||||
for (Scope.Entry e = s.elems; e != null; e = e.sibling) {
|
||||
if ((e.sym.flags() & ABSTRACT) != 0)
|
||||
System.err.print("abstract ");
|
||||
System.err.print(e.sym + " ");
|
||||
}
|
||||
System.err.println();
|
||||
s = s.next;
|
||||
}
|
||||
}
|
||||
|
||||
void printscopes(Env<AttrContext> env) {
|
||||
while (env.outer != null) {
|
||||
System.err.println("------------------------------");
|
||||
printscopes(env.info.scope);
|
||||
env = env.outer;
|
||||
}
|
||||
}
|
||||
|
||||
public void printscopes(Type t) {
|
||||
while (t.hasTag(CLASS)) {
|
||||
printscopes(t.tsym.members());
|
||||
t = types.supertype(t);
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************************************************************
|
||||
* Name resolution
|
||||
* Naming conventions are as for symbol lookup
|
||||
@ -2453,7 +2408,7 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
|
||||
@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 @@ public class Resolve {
|
||||
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 @@ public class Resolve {
|
||||
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;
|
||||
|
||||
@ -37,6 +37,7 @@ import com.sun.tools.javac.util.List;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.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 @@ public class TransTypes extends TreeTranslator {
|
||||
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 @@ public class TransTypes extends TreeTranslator {
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ import com.sun.tools.javac.comp.Annotate;
|
||||
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 @@ public class ClassReader {
|
||||
|
||||
/** 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 @@ public class ClassReader {
|
||||
|
||||
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 @@ public class ClassReader {
|
||||
/** 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 @@ public class ClassReader {
|
||||
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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 @@ public class ClassReader {
|
||||
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);
|
||||
|
||||
@ -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 com.sun.tools.javac.util.*;
|
||||
|
||||
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 @@ public class ClassWriter extends ClassFile {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class ClassWriter extends ClassFile {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class ClassWriter extends ClassFile {
|
||||
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 @@ public class ClassWriter extends ClassFile {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -45,6 +45,7 @@ import com.sun.tools.javac.tree.JCTree.*;
|
||||
|
||||
import static com.sun.tools.javac.code.Flags.*;
|
||||
import static com.sun.tools.javac.code.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 @@ public class Gen extends JCTree.Visitor {
|
||||
|
||||
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 @@ public class Gen extends JCTree.Visitor {
|
||||
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);
|
||||
|
||||
@ -37,7 +37,6 @@ import javax.tools.StandardLocation;
|
||||
|
||||
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 com.sun.tools.javac.util.Pair;
|
||||
|
||||
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 @@ public class JNIWriter {
|
||||
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 @@ public class JNIWriter {
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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.Symbol.*;
|
||||
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 @@ public class AnnotationProxyMaker {
|
||||
|
||||
// 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);
|
||||
|
||||
@ -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 @@ package com.sun.tools.javac.model;
|
||||
|
||||
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 class FilteredMemberList extends AbstractList<Symbol> {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -35,6 +35,7 @@ import javax.tools.JavaFileObject;
|
||||
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.TreeInfo;
|
||||
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 class JavacElements implements Elements {
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -310,9 +310,9 @@ public class JavacTypes implements javax.lang.model.util.Types {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ package com.sun.tools.javac.sym;
|
||||
|
||||
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 @@ public class CreateSymbols extends AbstractProcessor {
|
||||
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 @@ public class CreateSymbols extends AbstractProcessor {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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 abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
|
||||
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. */
|
||||
|
||||
@ -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 @@ public class TreeMaker implements JCTree.Factory {
|
||||
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 @@ public class TreeMaker implements JCTree.Factory {
|
||||
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;
|
||||
|
||||
@ -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.javadoc.*;
|
||||
|
||||
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 class AnnotationTypeDocImpl
|
||||
*/
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,6 +59,7 @@ import com.sun.tools.javac.util.Name;
|
||||
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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
*/
|
||||
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 class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
*/
|
||||
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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
*---------------------------------*/
|
||||
|
||||
// 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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
// 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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
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 @@ public class ClassDocImpl extends ProgramElementDocImpl implements ClassDoc {
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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 @@ public class MethodDocImpl
|
||||
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 @@ public class MethodDocImpl
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 javax.tools.FileObject;
|
||||
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.ListBuffer;
|
||||
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 @@ public class PackageDocImpl extends DocImpl implements PackageDoc {
|
||||
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);
|
||||
|
||||
@ -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 @@ class SerializedForm {
|
||||
/* 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 @@ class SerializedForm {
|
||||
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 @@ class SerializedForm {
|
||||
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 @@ class SerializedForm {
|
||||
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;
|
||||
|
||||
@ -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 @@ package com.sun.tools.jdeps;
|
||||
|
||||
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 @@ public class Analyzer {
|
||||
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,15 +68,29 @@ public class Analyzer {
|
||||
* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs the dependency analysis on the given archives.
|
||||
*/
|
||||
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()) {
|
||||
@ -81,190 +101,202 @@ public class Analyzer {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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<>();
|
||||
this.deps = new HashSet<>();
|
||||
this.requires = new HashSet<>();
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
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));
|
||||
Set<Dep> dependencies() {
|
||||
return deps;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
List<Dep> list = new ArrayList<>();
|
||||
for (Map.Entry<Archive,Profile> e: map.entrySet()) {
|
||||
list.add(new Dep("", e.getKey(), e.getValue()));
|
||||
}
|
||||
return list;
|
||||
Set<Archive> requires() {
|
||||
return requires;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
Profile getTargetProfile(Archive target) {
|
||||
return JDKArchive.isProfileArchive(target) ? profile : null;
|
||||
}
|
||||
|
||||
@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;
|
||||
Archive findArchive(Location t) {
|
||||
Archive target = archive.getClasses().contains(t) ? archive : map.get(t);
|
||||
if (target == null) {
|
||||
map.put(t, target = NOT_FOUND);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
@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());
|
||||
}
|
||||
}
|
||||
return this.target.compareTo(o.target);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
String origin = o.getClassName();
|
||||
String target = t.getClassName();
|
||||
add(origin, target, targetArchive, t.getPackageName());
|
||||
Dep e = new Dep(origin, archive, target, targetArchive);
|
||||
if (deps.contains(e)) {
|
||||
for (Dep e1 : deps) {
|
||||
if (e.equals(e1)) {
|
||||
curDep = e1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
deps.add(e);
|
||||
curDep = e;
|
||||
}
|
||||
return curDep;
|
||||
}
|
||||
}
|
||||
|
||||
private class PackageVisitor extends ArchiveDeps {
|
||||
PackageVisitor(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);
|
||||
}
|
||||
/*
|
||||
* Class-level or package-level dependency
|
||||
*/
|
||||
class Dep {
|
||||
final String origin;
|
||||
final Archive originArchive;
|
||||
final String target;
|
||||
final Archive targetArchive;
|
||||
|
||||
String origin = packageOf(o);
|
||||
String target = packageOf(t);
|
||||
add(origin, target, targetArchive, t.getPackageName());
|
||||
Dep(String origin, Archive originArchive, String target, Archive targetArchive) {
|
||||
this.origin = origin;
|
||||
this.originArchive = originArchive;
|
||||
this.target = target;
|
||||
this.targetArchive = targetArchive;
|
||||
}
|
||||
public String packageOf(Location o) {
|
||||
String pkg = o.getPackageName();
|
||||
return pkg.isEmpty() ? "<unnamed>" : pkg;
|
||||
|
||||
String origin() {
|
||||
return origin;
|
||||
}
|
||||
|
||||
Archive originArchive() {
|
||||
return originArchive;
|
||||
}
|
||||
|
||||
String target() {
|
||||
return target;
|
||||
}
|
||||
|
||||
Archive targetArchive() {
|
||||
return targetArchive;
|
||||
}
|
||||
|
||||
@Override
|
||||
@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;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ public class Archive {
|
||||
return reader;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
public String getName() {
|
||||
return filename;
|
||||
}
|
||||
|
||||
@ -89,6 +95,10 @@ public class Archive {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return getClasses().isEmpty();
|
||||
}
|
||||
|
||||
public String getPathName() {
|
||||
return path != null ? path.toString() : filename;
|
||||
}
|
||||
|
||||
@ -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 @@ public class ClassFileReader {
|
||||
|
||||
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 @@ public class ClassFileReader {
|
||||
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 @@ public class ClassFileReader {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public class ClassFileReader {
|
||||
+ 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 class ClassFileReader {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public boolean hasNext() {
|
||||
return nextEntry != null;
|
||||
}
|
||||
|
||||
public ClassFile next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
ClassFile cf;
|
||||
while (nextEntry != null) {
|
||||
try {
|
||||
cf = readClassFile(nextEntry);
|
||||
} catch (IOException ex) {
|
||||
throw new ClassFileError(ex);
|
||||
cf = reader.readClassFile(jf, nextEntry);
|
||||
return true;
|
||||
} catch (ClassFileError | IOException ex) {
|
||||
skippedEntries.add(nextEntry.getName());
|
||||
}
|
||||
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;
|
||||
nextEntry = nextEntry();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
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;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Not supported yet.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.ConstantPoolException;
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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,20 +518,27 @@ class JdepsTask {
|
||||
throw new ClassFileError(e);
|
||||
}
|
||||
|
||||
if (matches(classFileName, cf.access_flags)) {
|
||||
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());
|
||||
// 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 (String name : a.reader().skippedEntries()) {
|
||||
warning("warn.skipped.entry", name, a.getPathName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -462,6 +566,10 @@ class JdepsTask {
|
||||
// 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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ class JdepsTask {
|
||||
}
|
||||
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 @@ class JdepsTask {
|
||||
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 @@ class JdepsTask {
|
||||
}
|
||||
|
||||
@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();
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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>";
|
||||
}
|
||||
@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) {
|
||||
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");
|
||||
for (Edge e: edges) {
|
||||
writeEdge(writer, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
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;
|
||||
StringBuilder label = edges.get(origin).get(target);
|
||||
return label == null ? "" : String.format(" [label=\"%s\",fontsize=9]", label.toString());
|
||||
}
|
||||
|
||||
Edge findEdge(T origin, T target) {
|
||||
for (Edge e : edges) {
|
||||
if (e.from.equals(origin) && e.to.equals(target)) {
|
||||
return e;
|
||||
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);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getLabel(Edge e) {
|
||||
String label = e.label.toString();
|
||||
return label.isEmpty() ? "" : String.format("[label=\"%s\",fontsize=9]", label);
|
||||
}
|
||||
|
||||
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 + ")");
|
||||
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");
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ public class Main {
|
||||
return t.run(args);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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.SimpleFileVisitor;
|
||||
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 @@ class PlatformClassPath {
|
||||
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 @@ class PlatformClassPath {
|
||||
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 @@ class PlatformClassPath {
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ import java.util.jar.JarFile;
|
||||
* Build the profile information from ct.sym if exists.
|
||||
*/
|
||||
enum Profile {
|
||||
|
||||
COMPACT1("compact1", 1),
|
||||
COMPACT2("compact2", 2),
|
||||
COMPACT3("compact3", 3),
|
||||
@ -61,8 +60,7 @@ enum Profile {
|
||||
this.proprietaryPkgs = new HashSet<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
public String profileName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -77,7 +75,7 @@ enum Profile {
|
||||
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 {
|
||||
|
||||
@ -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.version=\
|
||||
|
||||
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 @@ main.opt.cp=\
|
||||
\ -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 @@ main.opt.depth=\
|
||||
|
||||
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}
|
||||
|
||||
|
||||
@ -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 @@ public class CheckLocalElements extends Checker {
|
||||
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);
|
||||
|
||||
@ -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 @@ abstract class Checker {
|
||||
for (CompilationUnitTree unit: units) {
|
||||
TreePath p = new TreePath(unit);
|
||||
s.scan(p, getTrees());
|
||||
additionalChecks(getTrees(), unit);
|
||||
}
|
||||
task = null;
|
||||
|
||||
@ -111,6 +112,9 @@ abstract class Checker {
|
||||
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())));
|
||||
|
||||
@ -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.*";
|
||||
|
||||
@ -32,7 +32,7 @@ import java.util.*;
|
||||
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.jvm.ClassReader;
|
||||
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 @@ public class T6889255 {
|
||||
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 @@ public class T6889255 {
|
||||
break;
|
||||
}
|
||||
case Kinds.MTH:
|
||||
verify((MethodSymbol) e.sym, expectNames);
|
||||
verify((MethodSymbol) s, expectNames);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ public class SourceFileTestBase extends TestBase {
|
||||
*/
|
||||
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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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");
|
||||
}
|
||||
}
|
||||
@ -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 @@ public class TestBase {
|
||||
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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/AbstractEmptyEnum.out
Normal file
2
langtools/test/tools/javac/enum/AbstractEmptyEnum.out
Normal file
@ -0,0 +1,2 @@
|
||||
AbstractEmptyEnum.java:10:8: compiler.err.does.not.override.abstract: AbstractEmptyEnum, m(), AbstractEmptyEnum
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
3
langtools/test/tools/javac/enum/Enum2.out
Normal file
3
langtools/test/tools/javac/enum/Enum2.out
Normal file
@ -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
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/FauxEnum1.out
Normal file
2
langtools/test/tools/javac/enum/FauxEnum1.out
Normal file
@ -0,0 +1,2 @@
|
||||
FauxEnum1.java:10:8: compiler.err.enum.no.subclassing
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/FauxEnum3.out
Normal file
2
langtools/test/tools/javac/enum/FauxEnum3.out
Normal file
@ -0,0 +1,2 @@
|
||||
FauxEnum3.java:10:8: compiler.err.enum.types.not.extensible
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/FauxSpecialEnum1.out
Normal file
2
langtools/test/tools/javac/enum/FauxSpecialEnum1.out
Normal file
@ -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
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/FauxSpecialEnum2.out
Normal file
2
langtools/test/tools/javac/enum/FauxSpecialEnum2.out
Normal file
@ -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
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/LocalEnum.out
Normal file
2
langtools/test/tools/javac/enum/LocalEnum.out
Normal file
@ -0,0 +1,2 @@
|
||||
LocalEnum.java:11:9: compiler.err.local.enum
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NestedEnum.out
Normal file
2
langtools/test/tools/javac/enum/NestedEnum.out
Normal file
@ -0,0 +1,2 @@
|
||||
NestedEnum.java:12:9: compiler.err.enums.must.be.static
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NoFinal.out
Normal file
2
langtools/test/tools/javac/enum/NoFinal.out
Normal file
@ -0,0 +1,2 @@
|
||||
NoFinal.java:11:24: compiler.err.enum.no.finalize
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NoFinal2.out
Normal file
2
langtools/test/tools/javac/enum/NoFinal2.out
Normal file
@ -0,0 +1,2 @@
|
||||
NoFinal2.java:11:20: compiler.err.enum.no.finalize
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NoFinal3.out
Normal file
2
langtools/test/tools/javac/enum/NoFinal3.out
Normal file
@ -0,0 +1,2 @@
|
||||
NoFinal3.java:11:17: compiler.err.enum.no.finalize
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NoFinal4.out
Normal file
2
langtools/test/tools/javac/enum/NoFinal4.out
Normal file
@ -0,0 +1,2 @@
|
||||
NoFinal4.java:11:18: compiler.err.enum.no.finalize
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/NoFinal5.out
Normal file
2
langtools/test/tools/javac/enum/NoFinal5.out
Normal file
@ -0,0 +1,2 @@
|
||||
NoFinal5.java:11:10: compiler.err.enum.no.finalize
|
||||
1 error
|
||||
@ -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
|
||||
* @test /nodynamiccopyright/
|
||||
* @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
|
||||
* @compile/fail/ref=T5081785.out -XDrawDiagnostics T5081785.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 }
|
||||
}
|
||||
}
|
||||
|
||||
5
langtools/test/tools/javac/enum/T5081785.out
Normal file
5
langtools/test/tools/javac/enum/T5081785.out
Normal file
@ -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
|
||||
@ -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{}; };
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
3
langtools/test/tools/javac/enum/forwardRef/TestEnum1.out
Normal file
3
langtools/test/tools/javac/enum/forwardRef/TestEnum1.out
Normal file
@ -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
|
||||
@ -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 {
|
||||
|
||||
3
langtools/test/tools/javac/enum/forwardRef/TestEnum2.out
Normal file
3
langtools/test/tools/javac/enum/forwardRef/TestEnum2.out
Normal file
@ -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
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/forwardRef/TestEnum3.out
Normal file
2
langtools/test/tools/javac/enum/forwardRef/TestEnum3.out
Normal file
@ -0,0 +1,2 @@
|
||||
TestEnum3.java:13:34: compiler.err.illegal.enum.static.ref
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/forwardRef/TestEnum4.out
Normal file
2
langtools/test/tools/javac/enum/forwardRef/TestEnum4.out
Normal file
@ -0,0 +1,2 @@
|
||||
TestEnum4.java:14:24: compiler.err.illegal.enum.static.ref
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/forwardRef/TestEnum5.out
Normal file
2
langtools/test/tools/javac/enum/forwardRef/TestEnum5.out
Normal file
@ -0,0 +1,2 @@
|
||||
TestEnum5.java:15:20: compiler.err.illegal.enum.static.ref
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
2
langtools/test/tools/javac/enum/forwardRef/TestEnum6.out
Normal file
2
langtools/test/tools/javac/enum/forwardRef/TestEnum6.out
Normal file
@ -0,0 +1,2 @@
|
||||
TestEnum6.java:10:18: compiler.err.illegal.self.ref
|
||||
1 error
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
|
||||
* 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
|
||||
@ -21,8 +21,23 @@
|
||||
* questions.
|
||||
*/
|
||||
|
||||
class A {
|
||||
class B {
|
||||
enum C { X, Y, Z }
|
||||
/**
|
||||
* @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);
|
||||
}
|
||||
}
|
||||
@ -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.*;
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
NewBeforeOuterConstructed.java:27:21: compiler.err.cant.ref.before.ctor.called: this
|
||||
1 error
|
||||
@ -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 {
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
NewBeforeOuterConstructed2.java:20:35: compiler.err.cant.ref.before.ctor.called: this
|
||||
1 error
|
||||
@ -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;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user