This commit is contained in:
Lana Steuck 2011-02-21 14:35:12 -08:00
commit f042640a89
40 changed files with 1322 additions and 281 deletions

View File

@ -868,8 +868,10 @@
executable="${boot.java.home}/bin/javac"
srcdir="${make.tools.dir}/GenStubs"
destdir="${build.toolclasses.dir}/"
classpath="${build.bootstrap.dir}/classes:${ant.core.lib}"
includeantruntime="false"/>
classpath="${ant.core.lib}"
includeantruntime="false">
<compilerarg value="-Xbootclasspath/p:${build.bootstrap.dir}/classes"/>
</javac>
<taskdef name="genstubs"
classname="GenStubs$$Ant"
classpath="${build.toolclasses.dir}/"/>

View File

@ -31,8 +31,7 @@ case `uname -s` in
mydir=`cygpath -m $mydir`
;;
esac
mylib="`dirname $mydir`"/lib
mylib="$mydir/../lib"
# By default, put the jar file and its dependencies on the bootclasspath.
# This is always required on a Mac, because the system langtools classes
@ -73,4 +72,4 @@ done
unset DUALCASE
IFS=$nl
"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/#PROGRAM#.jar ${toolOpts}
"#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mylib}/#PROGRAM#.jar" ${toolOpts}

View File

@ -74,7 +74,7 @@ public class Scope {
/** A list of scopes to be notified if items are to be removed from this scope.
*/
List<Scope> listeners = List.nil();
List<ScopeListener> listeners = List.nil();
/** Use as a "not-found" result for lookup.
* Also used to mark deleted entries in the table.
@ -219,12 +219,27 @@ public class Scope {
Entry e = makeEntry(sym, old, elems, s, origin);
table[hash] = e;
elems = e;
//notify listeners
for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
l.head.symbolAdded(sym, this);
}
}
Entry makeEntry(Symbol sym, Entry shadowed, Entry sibling, Scope scope, Scope origin) {
return new Entry(sym, shadowed, sibling, scope);
}
public interface ScopeListener {
public void symbolAdded(Symbol sym, Scope s);
public void symbolRemoved(Symbol sym, Scope s);
}
public void addScopeListener(ScopeListener sl) {
listeners = listeners.prepend(sl);
}
/** Remove symbol from this scope. Used when an inner class
* attribute tells us that the class isn't a package member.
*/
@ -258,9 +273,9 @@ public class Scope {
te = te.sibling;
}
// remove items from scopes that have done importAll
for (List<Scope> l = listeners; l.nonEmpty(); l = l.tail) {
l.head.remove(sym);
//notify listeners
for (List<ScopeListener> l = listeners; l.nonEmpty(); l = l.tail) {
l.head.symbolRemoved(sym, this);
}
}
@ -393,7 +408,32 @@ public class Scope {
};
}
};
}
public Iterable<Symbol> getElementsByName(Name name) {
return getElementsByName(name, noFilter);
}
public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
return new Iterable<Symbol>() {
public Iterator<Symbol> iterator() {
return new Iterator<Symbol>() {
Scope.Entry currentEntry = lookup(name, sf);
public boolean hasNext() {
return currentEntry.scope != null;
}
public Symbol next() {
Scope.Entry prevEntry = currentEntry;
currentEntry = currentEntry.next(sf);
return prevEntry.sym;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
};
}
public String toString() {
@ -488,7 +528,7 @@ public class Scope {
}
}
public static class StarImportScope extends ImportScope {
public static class StarImportScope extends ImportScope implements ScopeListener {
public StarImportScope(Symbol owner) {
super(owner);
@ -500,8 +540,13 @@ public class Scope {
enter(e.sym, fromScope);
}
// Register to be notified when imported items are removed
fromScope.listeners = fromScope.listeners.prepend(this);
fromScope.addScopeListener(this);
}
public void symbolRemoved(Symbol sym, Scope s) {
remove(sym);
}
public void symbolAdded(Symbol sym, Scope s) { }
}
/** An empty scope, into which you can't place anything. Used for
@ -538,6 +583,151 @@ public class Scope {
}
}
/** A class scope adds capabilities to keep track of changes in related
* class scopes - this allows client to realize whether a class scope
* has changed, either directly (because a new member has been added/removed
* to this scope) or indirectly (i.e. because a new member has been
* added/removed into a supertype scope)
*/
public static class CompoundScope extends Scope implements ScopeListener {
public static final Entry[] emptyTable = new Entry[0];
private List<Scope> subScopes = List.nil();
private int mark = 0;
public CompoundScope(Symbol owner) {
super(null, owner, emptyTable);
}
public void addSubScope(Scope that) {
if (that != null) {
subScopes = subScopes.prepend(that);
that.addScopeListener(this);
mark++;
for (ScopeListener sl : listeners) {
sl.symbolAdded(null, this); //propagate upwards in case of nested CompoundScopes
}
}
}
public void symbolAdded(Symbol sym, Scope s) {
mark++;
for (ScopeListener sl : listeners) {
sl.symbolAdded(sym, s);
}
}
public void symbolRemoved(Symbol sym, Scope s) {
mark++;
for (ScopeListener sl : listeners) {
sl.symbolRemoved(sym, s);
}
}
public int getMark() {
return mark;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append("CompoundScope{");
String sep = "";
for (Scope s : subScopes) {
buf.append(sep);
buf.append(s);
sep = ",";
}
buf.append("}");
return buf.toString();
}
@Override
public Iterable<Symbol> getElements(final Filter<Symbol> sf) {
return new Iterable<Symbol>() {
public Iterator<Symbol> iterator() {
return new CompoundScopeIterator(subScopes) {
Iterator<Symbol> nextIterator(Scope s) {
return s.getElements().iterator();
}
};
}
};
}
@Override
public Iterable<Symbol> getElementsByName(final Name name, final Filter<Symbol> sf) {
return new Iterable<Symbol>() {
public Iterator<Symbol> iterator() {
return new CompoundScopeIterator(subScopes) {
Iterator<Symbol> nextIterator(Scope s) {
return s.getElementsByName(name, sf).iterator();
}
};
}
};
}
abstract class CompoundScopeIterator implements Iterator<Symbol> {
private Iterator<Symbol> currentIterator;
private List<Scope> scopesToScan;
public CompoundScopeIterator(List<Scope> scopesToScan) {
this.scopesToScan = scopesToScan;
update();
}
abstract Iterator<Symbol> nextIterator(Scope s);
public boolean hasNext() {
return currentIterator != null;
}
public Symbol next() {
Symbol sym = currentIterator.next();
if (!currentIterator.hasNext()) {
update();
}
return sym;
}
public void remove() {
throw new UnsupportedOperationException();
}
private void update() {
while (scopesToScan.nonEmpty()) {
currentIterator = nextIterator(scopesToScan.head);
scopesToScan = scopesToScan.tail;
if (currentIterator.hasNext()) return;
}
currentIterator = null;
}
}
@Override
public Entry lookup(Name name, Filter<Symbol> sf) {
throw new UnsupportedOperationException();
}
@Override
public Scope dup(Symbol newOwner) {
throw new UnsupportedOperationException();
}
@Override
public void enter(Symbol sym, Scope s, Scope origin) {
throw new UnsupportedOperationException();
}
@Override
public void remove(Symbol sym) {
throw new UnsupportedOperationException();
}
}
/** An error scope, for which the owner should be an error symbol. */
public static class ErrorScope extends Scope {
ErrorScope(Scope next, Symbol errSymbol, Entry[] table) {

View File

@ -731,7 +731,7 @@ public abstract class Symbol implements Element {
/** members closure cache (set by Types.membersClosure)
*/
Scope membersClosure;
Scope.CompoundScope membersClosure;
public ClassSymbol(long flags, Name name, Type type, Symbol owner) {
super(flags, name, type, owner);

View File

@ -270,10 +270,6 @@ public class Type implements PrimitiveType {
public Type getUpperBound() { return null; }
public Type getLowerBound() { return null; }
public void setThrown(List<Type> ts) {
throw new AssertionError();
}
/** Navigation methods, these will work for classes, type variables,
* foralls, but will return null for arrays and methods.
*/
@ -388,14 +384,6 @@ public class Type implements PrimitiveType {
*/
public void complete() {}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}
public TypeSymbol asElement() {
return tsym;
}
@ -817,8 +805,7 @@ public class Type implements PrimitiveType {
}
}
public static class MethodType extends Type
implements Cloneable, ExecutableType {
public static class MethodType extends Type implements ExecutableType {
public List<Type> argtypes;
public Type restype;
@ -880,10 +867,6 @@ public class Type implements PrimitiveType {
public Type getReturnType() { return restype; }
public List<Type> getThrownTypes() { return thrown; }
public void setThrown(List<Type> t) {
thrown = t;
}
public boolean isErroneous() {
return
isErroneous(argtypes) ||
@ -1068,12 +1051,10 @@ public class Type implements PrimitiveType {
public List<Type> getThrownTypes() { return qtype.getThrownTypes(); }
public List<Type> allparams() { return qtype.allparams(); }
public Type getUpperBound() { return qtype.getUpperBound(); }
public Object clone() { DelegatedType t = (DelegatedType)super.clone(); t.qtype = (Type)qtype.clone(); return t; }
public boolean isErroneous() { return qtype.isErroneous(); }
}
public static class ForAll extends DelegatedType
implements Cloneable, ExecutableType {
public static class ForAll extends DelegatedType implements ExecutableType {
public List<Type> tvars;
public ForAll(List<Type> tvars, Type qtype) {
@ -1092,16 +1073,6 @@ public class Type implements PrimitiveType {
public List<Type> getTypeArguments() { return tvars; }
public void setThrown(List<Type> t) {
qtype.setThrown(t);
}
public Object clone() {
ForAll result = (ForAll)super.clone();
result.qtype = (Type)result.qtype.clone();
return result;
}
public boolean isErroneous() {
return qtype.isErroneous();
}

View File

@ -2023,18 +2023,22 @@ public class Types {
final MethodSymbol cachedImpl;
final Filter<Symbol> implFilter;
final boolean checkResult;
final int prevMark;
public Entry(MethodSymbol cachedImpl,
Filter<Symbol> scopeFilter,
boolean checkResult) {
boolean checkResult,
int prevMark) {
this.cachedImpl = cachedImpl;
this.implFilter = scopeFilter;
this.checkResult = checkResult;
this.prevMark = prevMark;
}
boolean matches(Filter<Symbol> scopeFilter, boolean checkResult) {
boolean matches(Filter<Symbol> scopeFilter, boolean checkResult, int mark) {
return this.implFilter == scopeFilter &&
this.checkResult == checkResult;
this.checkResult == checkResult &&
this.prevMark == mark;
}
}
@ -2046,10 +2050,11 @@ public class Types {
_map.put(ms, new SoftReference<Map<TypeSymbol, Entry>>(cache));
}
Entry e = cache.get(origin);
CompoundScope members = membersClosure(origin.type);
if (e == null ||
!e.matches(implFilter, checkResult)) {
MethodSymbol impl = implementationInternal(ms, origin, Types.this, checkResult, implFilter);
cache.put(origin, new Entry(impl, implFilter, checkResult));
!e.matches(implFilter, checkResult, members.getMark())) {
MethodSymbol impl = implementationInternal(ms, origin, checkResult, implFilter);
cache.put(origin, new Entry(impl, implFilter, checkResult, members.getMark()));
return impl;
}
else {
@ -2057,8 +2062,8 @@ public class Types {
}
}
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, Types types, boolean checkResult, Filter<Symbol> implFilter) {
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = types.supertype(t)) {
private MethodSymbol implementationInternal(MethodSymbol ms, TypeSymbol origin, boolean checkResult, Filter<Symbol> implFilter) {
for (Type t = origin.type; t.tag == CLASS || t.tag == TYPEVAR; t = supertype(t)) {
while (t.tag == TYPEVAR)
t = t.getUpperBound();
TypeSymbol c = t.tsym;
@ -2066,7 +2071,7 @@ public class Types {
e.scope != null;
e = e.next(implFilter)) {
if (e.sym != null &&
e.sym.overrides(ms, origin, types, checkResult))
e.sym.overrides(ms, origin, Types.this, checkResult))
return (MethodSymbol)e.sym;
}
}
@ -2082,46 +2087,35 @@ public class Types {
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="compute transitive closure of all members in given site">
public Scope membersClosure(Type site) {
public CompoundScope membersClosure(Type site) {
return membersClosure.visit(site);
}
UnaryVisitor<Scope> membersClosure = new UnaryVisitor<Scope>() {
UnaryVisitor<CompoundScope> membersClosure = new UnaryVisitor<CompoundScope>() {
public Scope visitType(Type t, Void s) {
public CompoundScope visitType(Type t, Void s) {
return null;
}
@Override
public Scope visitClassType(ClassType t, Void s) {
public CompoundScope visitClassType(ClassType t, Void s) {
ClassSymbol csym = (ClassSymbol)t.tsym;
if (csym.membersClosure == null) {
Scope membersClosure = new Scope(csym);
CompoundScope membersClosure = new CompoundScope(csym);
for (Type i : interfaces(t)) {
enterAll(visit(i), membersClosure);
membersClosure.addSubScope(visit(i));
}
enterAll(visit(supertype(t)), membersClosure);
enterAll(csym.members(), membersClosure);
membersClosure.addSubScope(visit(supertype(t)));
membersClosure.addSubScope(csym.members());
csym.membersClosure = membersClosure;
}
return csym.membersClosure;
}
@Override
public Scope visitTypeVar(TypeVar t, Void s) {
public CompoundScope visitTypeVar(TypeVar t, Void s) {
return visit(t.getUpperBound());
}
public void enterAll(Scope s, Scope to) {
if (s == null) return;
List<Symbol> syms = List.nil();
for (Scope.Entry e = s.elems ; e != null ; e = e.sibling) {
syms = syms.prepend(e.sym);
}
for (Symbol sym : syms) {
to.enter(sym);
}
}
};
// </editor-fold>
@ -2413,6 +2407,38 @@ public class Types {
};
// </editor-fold>
public Type createMethodTypeWithParameters(Type original, List<Type> newParams) {
return original.accept(methodWithParameters, newParams);
}
// where
private final MapVisitor<List<Type>> methodWithParameters = new MapVisitor<List<Type>>() {
public Type visitType(Type t, List<Type> newParams) {
throw new IllegalArgumentException("Not a method type: " + t);
}
public Type visitMethodType(MethodType t, List<Type> newParams) {
return new MethodType(newParams, t.restype, t.thrown, t.tsym);
}
public Type visitForAll(ForAll t, List<Type> newParams) {
return new ForAll(t.tvars, t.qtype.accept(this, newParams));
}
};
public Type createMethodTypeWithThrown(Type original, List<Type> newThrown) {
return original.accept(methodWithThrown, newThrown);
}
// where
private final MapVisitor<List<Type>> methodWithThrown = new MapVisitor<List<Type>>() {
public Type visitType(Type t, List<Type> newThrown) {
throw new IllegalArgumentException("Not a method type: " + t);
}
public Type visitMethodType(MethodType t, List<Type> newThrown) {
return new MethodType(t.argtypes, t.restype, newThrown, t.tsym);
}
public Type visitForAll(ForAll t, List<Type> newThrown) {
return new ForAll(t.tvars, t.qtype.accept(this, newThrown));
}
};
// <editor-fold defaultstate="collapsed" desc="createErrorType">
public Type createErrorType(Type originalType) {
return new ErrorType(originalType, syms.errSymbol);

View File

@ -1584,6 +1584,11 @@ public class Attr extends JCTree.Visitor {
if (!TreeInfo.isDiamond(tree)) {
clazztype = chk.checkClassType(
tree.clazz.pos(), clazztype, true);
} else if (!clazztype.isErroneous() &&
!clazztype.tsym.type.isParameterized()) {
log.error(tree.clazz.pos(),
"cant.apply.diamond.1",
clazztype, diags.fragment("diamond.non.generic", clazztype));
}
chk.validate(clazz, localEnv);
if (tree.encl != null) {
@ -1609,7 +1614,7 @@ public class Attr extends JCTree.Visitor {
List<Type> argtypes = attribArgs(tree.args, localEnv);
List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
if (TreeInfo.isDiamond(tree)) {
if (TreeInfo.isDiamond(tree) && clazztype.tsym.type.isParameterized()) {
clazztype = attribDiamond(localEnv, tree, clazztype, mapping, argtypes, typeargtypes);
clazz.type = clazztype;
} else if (allowDiamondFinder &&

View File

@ -2106,32 +2106,32 @@ public class Check {
void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
ClashFilter cf = new ClashFilter(site);
//for each method m1 that is a member of 'site'...
for (Scope.Entry e1 = types.membersClosure(site).lookup(sym.name, cf) ;
e1.scope != null ; e1 = e1.next(cf)) {
for (Symbol s1 : types.membersClosure(site).getElementsByName(sym.name, cf)) {
//...find another method m2 that is overridden (directly or indirectly)
//by method 'sym' in 'site'
for (Scope.Entry e2 = types.membersClosure(site).lookup(sym.name, cf) ;
e2.scope != null ; e2 = e2.next(cf)) {
if (e1.sym == e2.sym || !sym.overrides(e2.sym, site.tsym, types, false)) continue;
for (Symbol s2 : types.membersClosure(site).getElementsByName(sym.name, cf)) {
if (s1 == s2 || !sym.overrides(s2, site.tsym, types, false)) 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
if (!types.isSubSignature(sym.type, types.memberType(site, e1.sym)) &&
types.hasSameArgs(e1.sym.erasure(types), e2.sym.erasure(types))) {
if (!types.isSubSignature(sym.type, types.memberType(site, s1)) &&
types.hasSameArgs(s1.erasure(types), s2.erasure(types))) {
sym.flags_field |= CLASH;
String key = e2.sym == sym ?
String key = s2 == sym ?
"name.clash.same.erasure.no.override" :
"name.clash.same.erasure.no.override.1";
log.error(pos,
key,
sym, sym.location(),
e1.sym, e1.sym.location(),
e2.sym, e2.sym.location());
s1, s1.location(),
s2, s2.location());
return;
}
}
}
}
/** Check that all static methods accessible from 'site' are
* mutually compatible (JLS 8.4.8).
*
@ -2142,16 +2142,15 @@ 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 (Scope.Entry e = types.membersClosure(site).lookup(sym.name, cf) ;
e.scope != null ; e = e.next(cf)) {
for (Symbol s : types.membersClosure(site).getElementsByName(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, e.sym)) &&
types.hasSameArgs(e.sym.erasure(types), sym.erasure(types))) {
if (!types.isSubSignature(sym.type, types.memberType(site, s)) &&
types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
log.error(pos,
"name.clash.same.erasure.no.hide",
sym, sym.location(),
e.sym, e.sym.location());
s, s.location());
return;
}
}

View File

@ -314,13 +314,22 @@ public class Flow extends TreeScanner {
for (PendingExit exit = pendingExits.next();
exit != null;
exit = pendingExits.next()) {
boolean synthetic = classDef != null &&
classDef.pos == exit.tree.pos;
log.error(exit.tree.pos(),
synthetic
? "unreported.exception.default.constructor"
: "unreported.exception.need.to.catch.or.throw",
exit.thrown);
if (classDef != null &&
classDef.pos == exit.tree.pos) {
log.error(exit.tree.pos(),
"unreported.exception.default.constructor",
exit.thrown);
} else if (exit.tree.getTag() == JCTree.VARDEF &&
((JCVariableDecl)exit.tree).sym.isResourceVariable()) {
log.error(exit.tree.pos(),
"unreported.exception.implicit.close",
exit.thrown,
((JCVariableDecl)exit.tree).sym.name);
} else {
log.error(exit.tree.pos(),
"unreported.exception.need.to.catch.or.throw",
exit.thrown);
}
}
}
@ -664,12 +673,15 @@ public class Flow extends TreeScanner {
// in an anonymous class, add the set of thrown exceptions to
// the throws clause of the synthetic constructor and propagate
// outwards.
// Changing the throws clause on the fly is okay here because
// the anonymous constructor can't be invoked anywhere else,
// and its type hasn't been cached.
if (tree.name == names.empty) {
for (List<JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
if (TreeInfo.isInitialConstructor(l.head)) {
JCMethodDecl mdef = (JCMethodDecl)l.head;
mdef.thrown = make.Types(thrown);
mdef.sym.type.setThrown(thrown);
mdef.sym.type = types.createMethodTypeWithThrown(mdef.sym.type, thrown);
}
}
thrownPrev = chk.union(thrown, thrownPrev);
@ -1021,7 +1033,7 @@ public class Flow extends TreeScanner {
List.<Type>nil());
if (closeMethod.kind == MTH) {
for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
markThrown(tree.body, t);
markThrown(resource, t);
}
}
}

View File

@ -1425,25 +1425,55 @@ public class Lower extends TreeTranslator {
}
}
/** Optionally replace a try statement with an automatic resource
* management (ARM) block.
/**
* Optionally replace a try statement with the desugaring of a
* try-with-resources statement. The canonical desugaring of
*
* try ResourceSpecification
* Block
*
* is
*
* {
* final VariableModifiers_minus_final R #resource = Expression;
* Throwable #primaryException = null;
*
* try ResourceSpecificationtail
* Block
* catch (Throwable #t) {
* #primaryException = t;
* throw #t;
* } finally {
* if (#resource != null) {
* if (#primaryException != null) {
* try {
* #resource.close();
* } catch(Throwable #suppressedException) {
* #primaryException.addSuppressed(#suppressedException);
* }
* } else {
* #resource.close();
* }
* }
* }
*
* @param tree The try statement to inspect.
* @return An ARM block, or the original try block if there are no
* resources to manage.
* @return A a desugared try-with-resources tree, or the original
* try block if there are no resources to manage.
*/
JCTree makeArmTry(JCTry tree) {
JCTree makeTwrTry(JCTry tree) {
make_at(tree.pos());
twrVars = twrVars.dup();
JCBlock armBlock = makeArmBlock(tree.resources, tree.body, 0);
JCBlock twrBlock = makeTwrBlock(tree.resources, tree.body, 0);
if (tree.catchers.isEmpty() && tree.finalizer == null)
result = translate(armBlock);
result = translate(twrBlock);
else
result = translate(make.Try(armBlock, tree.catchers, tree.finalizer));
result = translate(make.Try(twrBlock, tree.catchers, tree.finalizer));
twrVars = twrVars.leave();
return result;
}
private JCBlock makeArmBlock(List<JCTree> resources, JCBlock block, int depth) {
private JCBlock makeTwrBlock(List<JCTree> resources, JCBlock block, int depth) {
if (resources.isEmpty())
return block;
@ -1497,16 +1527,16 @@ public class Lower extends TreeTranslator {
int oldPos = make.pos;
make.at(TreeInfo.endPos(block));
JCBlock finallyClause = makeArmFinallyClause(primaryException, expr);
JCBlock finallyClause = makeTwrFinallyClause(primaryException, expr);
make.at(oldPos);
JCTry outerTry = make.Try(makeArmBlock(resources.tail, block, depth + 1),
JCTry outerTry = make.Try(makeTwrBlock(resources.tail, block, depth + 1),
List.<JCCatch>of(catchClause),
finallyClause);
stats.add(outerTry);
return make.Block(0L, stats.toList());
}
private JCBlock makeArmFinallyClause(Symbol primaryException, JCExpression resource) {
private JCBlock makeTwrFinallyClause(Symbol primaryException, JCExpression resource) {
// primaryException.addSuppressed(catchException);
VarSymbol catchException =
new VarSymbol(0, make.paramName(2),
@ -1525,22 +1555,30 @@ public class Lower extends TreeTranslator {
List<JCCatch> catchClauses = List.<JCCatch>of(make.Catch(catchExceptionDecl, catchBlock));
JCTry tryTree = make.Try(tryBlock, catchClauses, null);
// if (resource != null) resourceClose;
JCExpression nullCheck = makeBinary(JCTree.NE,
make.Ident(primaryException),
makeNull());
JCIf closeIfStatement = make.If(nullCheck,
// if (primaryException != null) {try...} else resourceClose;
JCIf closeIfStatement = make.If(makeNonNullCheck(make.Ident(primaryException)),
tryTree,
makeResourceCloseInvocation(resource));
return make.Block(0L, List.<JCStatement>of(closeIfStatement));
// if (#resource != null) { if (primaryException ... }
return make.Block(0L,
List.<JCStatement>of(make.If(makeNonNullCheck(resource),
closeIfStatement,
null)));
}
private JCStatement makeResourceCloseInvocation(JCExpression resource) {
// create resource.close() method invocation
JCExpression resourceClose = makeCall(resource, names.close, List.<JCExpression>nil());
JCExpression resourceClose = makeCall(resource,
names.close,
List.<JCExpression>nil());
return make.Exec(resourceClose);
}
private JCExpression makeNonNullCheck(JCExpression expression) {
return makeBinary(JCTree.NE, expression, makeNull());
}
/** Construct a tree that represents the outer instance
* <C.this>. Never pick the current `this'.
* @param pos The source code position to be used for the tree.
@ -3573,7 +3611,7 @@ public class Lower extends TreeTranslator {
if (tree.resources.isEmpty()) {
super.visitTry(tree);
} else {
result = makeArmTry(tree);
result = makeTwrTry(tree);
}
}

View File

@ -776,10 +776,12 @@ public class Resolve {
// due to error recovery or mixing incompatible class files
return ambiguityError(m1, m2);
}
List<Type> allThrown = chk.intersect(mt1.getThrownTypes(), mt2.getThrownTypes());
Type newSig = types.createMethodTypeWithThrown(mostSpecific.type, allThrown);
MethodSymbol result = new MethodSymbol(
mostSpecific.flags(),
mostSpecific.name,
null,
newSig,
mostSpecific.owner) {
@Override
public MethodSymbol implementation(TypeSymbol origin, Types types, boolean checkResult) {
@ -789,9 +791,6 @@ public class Resolve {
return super.implementation(origin, types, checkResult);
}
};
result.type = (Type)mostSpecific.type.clone();
result.type.setThrown(chk.intersect(mt1.getThrownTypes(),
mt2.getThrownTypes()));
return result;
}
if (m1SignatureMoreSpecific) return m1;
@ -852,13 +851,8 @@ public class Resolve {
}
//append varargs element type as last synthetic formal
args.append(types.elemtype(varargsTypeTo));
MethodSymbol msym = new MethodSymbol(to.flags_field,
to.name,
(Type)to.type.clone(), //see: 6990136
to.owner);
MethodType mtype = msym.type.asMethodType();
mtype.argtypes = args.toList();
return msym;
Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
return new MethodSymbol(to.flags_field, to.name, mtype, to.owner);
} else {
return to;
}

View File

@ -49,16 +49,13 @@ public class CacheFSInfo extends FSInfo {
public static void preRegister(final Context context) {
context.put(FSInfo.class, new Context.Factory<FSInfo>() {
public FSInfo make() {
if (singleton == null)
singleton = new CacheFSInfo();
context.put(FSInfo.class, singleton);
return singleton;
FSInfo instance = new CacheFSInfo();
context.put(FSInfo.class, instance);
return instance;
}
});
}
static CacheFSInfo singleton;
public void clearCache() {
cache.clear();
}

View File

@ -164,9 +164,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
fsInfo = FSInfo.instance(context);
// retain check for system property for compatibility
useZipFileIndex = options.isUnset("useJavaUtilZip")
&& System.getProperty("useJavaUtilZip") == null;
useZipFileIndex = options.isSet("useOptimizedZip");
if (useZipFileIndex)
zipFileIndexCache = ZipFileIndexCache.getSharedInstance();
@ -499,8 +497,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil
if (!useZipFileIndex) {
zdir = new ZipFile(zipFileName);
}
else {
} else {
usePreindexedCache = options.isSet("usezipindex");
preindexCacheLocation = options.get("java.io.tmpdir");
String optCacheLoc = options.get("cachezipindexdir");

View File

@ -247,10 +247,16 @@ public class Paths {
public Path() { super(); }
public Path addDirectories(String dirs, boolean warn) {
if (dirs != null)
for (File dir : getPathEntries(dirs))
addDirectory(dir, warn);
return this;
boolean prev = expandJarClassPaths;
expandJarClassPaths = true;
try {
if (dirs != null)
for (File dir : getPathEntries(dirs))
addDirectory(dir, warn);
return this;
} finally {
expandJarClassPaths = prev;
}
}
public Path addDirectories(String dirs) {

View File

@ -282,12 +282,6 @@ public class Scanner implements Lexer {
sbuf[sp++] = ch;
}
/** For debugging purposes: print character.
*/
private void dch() {
System.err.print(ch); System.out.flush();
}
/** Read next character in character or string literal and copy into sbuf.
*/
private void scanLitChar() {

View File

@ -55,6 +55,7 @@ import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.api.JavacTrees;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.FSInfo;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.main.JavaCompiler;
@ -1069,6 +1070,10 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
if (tl != null)
next.put(TaskListener.class, tl);
FSInfo fsInfo = context.get(FSInfo.class);
if (fsInfo != null)
next.put(FSInfo.class, fsInfo);
JavaFileManager jfm = context.get(JavaFileManager.class);
Assert.checkNonNull(jfm);
next.put(JavaFileManager.class, jfm);

View File

@ -800,6 +800,11 @@ compiler.err.unreported.exception.need.to.catch.or.throw=\
compiler.err.unreported.exception.default.constructor=\
unreported exception {0} in default constructor
# 0: type, 1: name
compiler.err.unreported.exception.implicit.close=\
unreported exception {0}; must be caught or declared to be thrown\n\
exception thrown from implicit call to close() on resource variable ''{1}''
compiler.err.unsupported.cross.fp.lit=\
hexadecimal floating-point literals are not supported on this VM
@ -1579,6 +1584,10 @@ compiler.misc.inferred.do.not.conform.to.bounds=\
compiler.misc.diamond=\
{0}<>
# 0: type
compiler.misc.diamond.non.generic=\
cannot use ''<>'' with non-generic class {0}
# 0: list of type, 1: message segment
compiler.misc.diamond.invalid.arg=\
type argument {0} inferred for {1} is not allowed in this context

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011 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
@ -123,7 +123,7 @@ public class T4241573 {
if (!dir.mkdirs())
throw new Exception("cannot create directories " + dir);
for (String e: entries) {
writeFile(new File(dir, getPathForEntry(e)), getBodyForEntry(e));
writeFile(new File(dir, getPathForDirEntry(e)), getBodyForEntry(e));
}
return dir;
}
@ -134,7 +134,7 @@ public class T4241573 {
try {
JarOutputStream jos = new JarOutputStream(out);
for (String e: entries) {
jos.putNextEntry(new JarEntry(getPathForEntry(e)));
jos.putNextEntry(new JarEntry(getPathForZipEntry(e)));
jos.write(getBodyForEntry(e).getBytes());
}
jos.close();
@ -144,11 +144,16 @@ public class T4241573 {
return jar;
}
/** Return the path for an entry given to createDir or createJar. */
String getPathForEntry(String e) {
/** Return the path for an entry given to createDir */
String getPathForDirEntry(String e) {
return e.replace(".", File.separator) + ".java";
}
/** Return the path for an entry given to createJar. */
String getPathForZipEntry(String e) {
return e.replace(".", "/") + ".java";
}
/** Return the body text for an entry given to createDir or createJar. */
String getBodyForEntry(String e) {
int sep = e.lastIndexOf(".");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2010, 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
@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*/
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2010, 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
@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*/
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright 2010 Sun Microsystems, Inc. All Rights Reserved.
* Copyright (c) 2010, 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
@ -16,9 +16,9 @@
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
* 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.
*/
/*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2011 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
@ -138,12 +138,11 @@ public class TestInferBinaryName {
boolean zipFileIndexKind)
throws IOException {
Context ctx = new Context();
Options options = Options.instance(ctx);
// uugh, ugly back door, should be cleaned up, someday
if (zipFileIndexKind == USE_ZIP_FILE_INDEX)
System.clearProperty("useJavaUtilZip");
else
System.setProperty("useJavaUtilZip", "true");
Options options = Options.instance(ctx);
options.put("useOptimizedZip", "true");
if (symFileKind == IGNORE_SYMBOL_FILE)
options.put("ignore.symbol.file", "true");
JavacFileManager fm = new JavacFileManager(ctx, false, null);

View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2011, 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,7 +24,7 @@
#
# @test @(#)Class-Path.sh 1.3 03/10/31
# @test
# @bug 4212732
# @summary Test handling of the Class-Path attribute in jar file manifests
# @author Martin Buchholz
@ -184,8 +184,8 @@ Success "$jar" umf MANIFEST.MF "Hello.jar"
#
Success "$jar" cfe "Hello.jar" "Hello" Bye.class
# Jar creation and update when there is no manifest and inputfiles
specified
# Jar creation and update when there is no manifest and inputfiles
# specified
Failure "$jar" cvf "A.jar"
Failure "$jar" uvf "A.jar"

View File

@ -0,0 +1,111 @@
#!/bin/sh
#
# Copyright (c) 2011, 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 4212732 6485027
# @summary Test handling of the Class-Path attribute in jar file manifests
# @author Martin Buchholz
#
# @run shell Class-Path2.sh
# To run this test manually, simply do ./Class-Path2.sh
. ${TESTSRC-.}/Util.sh
set -u
Cleanup() {
Sys rm -rf pkg Main.java Main.class Main.jar jars
Sys rm -rf MANIFEST.MF A.jar B.zip
}
Cleanup
Sys mkdir pkg
#----------------------------------------------------------------
# Create mutually referential jar files
#----------------------------------------------------------------
cat >pkg/A.java <<EOF
package pkg;
import pkg.B;
public class A {
public static int f() { return B.g(); }
public static int g() { return 0; }
}
EOF
cat >pkg/B.java <<EOF
package pkg;
import pkg.A;
public class B {
public static int f() { return A.g(); }
public static int g() { return 0; }
}
EOF
Sys "$javac" pkg/A.java pkg/B.java
MkManifestWithClassPath "./sub/B.zip"
Sys "$jar" cmf MANIFEST.MF A.jar pkg/A.class
MkManifestWithClassPath "../A.jar"
Sys "$jar" cmf MANIFEST.MF B.zip pkg/B.class
cat >Main.java <<EOF
import pkg.*;
public class Main {
public static void main(String []a) { System.exit(A.f() + B.f()); }
}
EOF
Sys rm -rf pkg
Sys mkdir jars
Sys mkdir jars/sub/
Sys mv A.jar jars/.
Sys mv B.zip jars/sub/.
#
# Test 1: Compiling
#
Success "$javac" ${TESTTOOLVMOPTS} -cp "jars/A.jar" Main.java
Success "$java" ${TESTVMOPTS} -cp "jars/A.jar${PS}." Main
Success "$javac" ${TESTTOOLVMOPTS} -cp "jars/sub/B.zip" Main.java
Success "$java" ${TESTVMOPTS} -cp "jars/sub/B.zip${PS}." Main
#
# Test 2: Use of extension directories is incorrect
#
Success "$javac" ${TESTTOOLVMOPTS} -extdirs jars -cp None Main.java
Success "$java" ${TESTVMOPTS} -Djava.ext.dirs="jars" -cp . Main
Success "$javac" ${TESTTOOLVMOPTS} -extdirs jars/sub -cp None Main.java
Success "$java" ${TESTVMOPTS} -Djava.ext.dirs="jars/sub" -cp . Main
Cleanup
Bottom Line

View File

@ -1,7 +1,7 @@
#!/bin/sh
#
# Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2003, 2011, 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
@ -182,12 +182,12 @@ No Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -classpath classesRefRef.jar
No Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -Xbootclasspath/p:classesRefRef.jar Main.java
#----------------------------------------------------------------
# Class-Path attribute ignored in extdirs or endorseddirs
# Class-Path attribute followed in extdirs or endorseddirs
#----------------------------------------------------------------
Sys mkdir jars
Sys cp -p classesRefRef.jar jars/.
No Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -extdirs jars Main.java
No Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -endorseddirs jars Main.java
Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -extdirs jars Main.java
Warning "$javac" ${TESTTOOLVMOPTS} -Xlint -endorseddirs jars Main.java
#----------------------------------------------------------------
# Bad Jar file in extdirs and endorseddirs should not be ignored

View File

@ -1,2 +1,2 @@
ResourceInterface.java:38:34: compiler.err.unreported.exception.need.to.catch.or.throw: ResourceInterface.E1
ResourceInterface.java:38:13: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2
1 error

View File

@ -1,3 +1,3 @@
TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException
TwrFlow.java:12:46: compiler.err.unreported.exception.need.to.catch.or.throw: CustomCloseException
TwrFlow.java:12:13: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow
2 errors

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2011, 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 7020047
* @summary Test null handling of try-with-resources statement
*/
public class TwrNullTests {
/*
* Each try-with-resources statement generates two calls to the
* close method for each resource: one for when there is a primary
* exception present and the second for when a primary exception
* is absent. The null handling of both cases needs to be
* checked.
*/
public static void main(String... args) {
testNormalCompletion();
testNoSuppression();
}
/*
* Verify empty try-with-resources on a null resource completes
* normally; no NPE from the generated close call.
*/
private static void testNormalCompletion() {
try(AutoCloseable resource = null) {
return; // Nothing to see here, move along.
} catch (Exception e) {
throw new AssertionError("Should not be reached", e);
}
}
/*
* Verify that a NPE on a null resource is <em>not</em> added as a
* suppressed exception to an exception from try block.
*/
private static void testNoSuppression() {
try(AutoCloseable resource = null) {
throw new java.io.IOException();
} catch(java.io.IOException ioe) {
Throwable[] suppressed = ioe.getSuppressed();
if (suppressed.length != 0) {
throw new AssertionError("Non-empty suppressed exceptions",
ioe);
}
} catch (Exception e) {
throw new AssertionError("Should not be reached", e);
}
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011 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
@ -59,12 +59,12 @@ public class Test {
test(createFileManager(), createDir("dir", entries), "p", entries);
test(createFileManager(), createDir("a b/dir", entries), "p", entries);
for (boolean useJavaUtilZip: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip), createJar("jar", entries), "p", entries);
test(createFileManager(useJavaUtilZip), createJar("jar jar", entries), "p", entries);
for (boolean useOptimizedZip: new boolean[] { false, true }) {
test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries);
test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries);
for (boolean useSymbolFile: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip, useSymbolFile), rt_jar, "java.lang.ref", null);
test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", null);
}
}
@ -145,42 +145,22 @@ public class Test {
return createFileManager(false, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip) {
return createFileManager(useJavaUtilZip, false);
JavacFileManager createFileManager(boolean useOptimizedZip) {
return createFileManager(useOptimizedZip, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip, boolean useSymbolFile) {
// javac should really not be using system properties like this
// -- it should really be using (hidden) options -- but until then
// take care to leave system properties as we find them, so as not
// to adversely affect other tests that might follow.
String prev = System.getProperty("useJavaUtilZip");
boolean resetProperties = false;
try {
if (useJavaUtilZip) {
System.setProperty("useJavaUtilZip", "true");
resetProperties = true;
} else if (System.getProperty("useJavaUtilZip") != null) {
System.getProperties().remove("useJavaUtilZip");
resetProperties = true;
JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) {
Context c = new Context();
Options options = Options.instance(c);
if (useOptimizedZip) {
options.put("useOptimizedZip", "true");
}
Context c = new Context();
if (!useSymbolFile) {
Options options = Options.instance(c);
options.put("ignore.symbol.file", "true");
}
return new JavacFileManager(c, false, null);
} finally {
if (resetProperties) {
if (prev == null) {
System.getProperties().remove("useJavaUtilZip");
} else {
System.setProperty("useJavaUtilZip", prev);
}
}
}
}
File createDir(String name, String... entries) throws Exception {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011 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
@ -32,7 +32,9 @@ import java.util.*;
import java.util.zip.*;
import javax.tools.*;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.main.OptionName;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Options;
public class T6838467 {
boolean fileSystemIsCaseSignificant = !new File("a").equals(new File("A"));
@ -176,33 +178,13 @@ public class T6838467 {
return fm;
}
JavacFileManager createFileManager(boolean useJavaUtilZip) {
// javac should really not be using system properties like this
// -- it should really be using (hidden) options -- but until then
// take care to leave system properties as we find them, so as not
// to adversely affect other tests that might follow.
String prev = System.getProperty("useJavaUtilZip");
boolean resetProperties = false;
try {
if (useJavaUtilZip) {
System.setProperty("useJavaUtilZip", "true");
resetProperties = true;
} else if (System.getProperty("useJavaUtilZip") != null) {
System.getProperties().remove("useJavaUtilZip");
resetProperties = true;
}
Context c = new Context();
return new JavacFileManager(c, false, null);
} finally {
if (resetProperties) {
if (prev == null) {
System.getProperties().remove("useJavaUtilZip");
} else {
System.setProperty("useJavaUtilZip", prev);
}
}
JavacFileManager createFileManager(boolean useOptimedZipIndex) {
Context ctx = new Context();
if (useOptimedZipIndex) {
Options options = Options.instance(ctx);
options.put("useOptimizedZip", "true");
}
return new JavacFileManager(ctx, false, null);
}
// create a directory containing a given set of paths

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011 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,12 +63,12 @@ public class T6877206 {
test(createFileManager(), createDir("dir", entries), "p", entries.length);
test(createFileManager(), createDir("a b/dir", entries), "p", entries.length);
for (boolean useJavaUtilZip: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip), createJar("jar", entries), "p", entries.length);
test(createFileManager(useJavaUtilZip), createJar("jar jar", entries), "p", entries.length);
for (boolean useOptimizedZip: new boolean[] { false, true }) {
test(createFileManager(useOptimizedZip), createJar("jar", entries), "p", entries.length);
test(createFileManager(useOptimizedZip), createJar("jar jar", entries), "p", entries.length);
for (boolean useSymbolFile: new boolean[] { false, true }) {
test(createFileManager(useJavaUtilZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
test(createFileManager(useOptimizedZip, useSymbolFile), rt_jar, "java.lang.ref", -1);
}
}
@ -161,42 +161,20 @@ public class T6877206 {
return createFileManager(false, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip) {
return createFileManager(useJavaUtilZip, false);
JavacFileManager createFileManager(boolean useOptimizedZip) {
return createFileManager(useOptimizedZip, false);
}
JavacFileManager createFileManager(boolean useJavaUtilZip, boolean useSymbolFile) {
// javac should really not be using system properties like this
// -- it should really be using (hidden) options -- but until then
// take care to leave system properties as we find them, so as not
// to adversely affect other tests that might follow.
String prev = System.getProperty("useJavaUtilZip");
boolean resetProperties = false;
try {
if (useJavaUtilZip) {
System.setProperty("useJavaUtilZip", "true");
resetProperties = true;
} else if (System.getProperty("useJavaUtilZip") != null) {
System.getProperties().remove("useJavaUtilZip");
resetProperties = true;
}
Context c = new Context();
if (!useSymbolFile) {
Options options = Options.instance(c);
options.put("ignore.symbol.file", "true");
}
return new JavacFileManager(c, false, null);
} finally {
if (resetProperties) {
if (prev == null) {
System.getProperties().remove("useJavaUtilZip");
} else {
System.setProperty("useJavaUtilZip", prev);
}
}
JavacFileManager createFileManager(boolean useOptimizedZip, boolean useSymbolFile) {
Context ctx = new Context();
Options options = Options.instance(ctx);
if (useOptimizedZip) {
options.put("useOptimizedZip", "true");
}
if (!useSymbolFile) {
options.put("ignore.symbol.file", "true");
}
return new JavacFileManager(ctx, false, null);
}
File createDir(String name, String... entries) throws Exception {

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2011, 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.
*/
// key: compiler.misc.diamond.non.generic
// key: compiler.err.cant.apply.diamond.1
class DiamondNonGeneric {
String s = new String<>("foo");
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2011, 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.
*/
// key: compiler.err.unreported.exception.implicit.close
class UnreportedExceptionImplicitClose {
static class MyCloseable implements AutoCloseable {
public void close() throws Exception { }
}
void test() {
try (MyCloseable x = new MyCloseable()) { }
}
}

View File

@ -0,0 +1,121 @@
/*
* Copyright (c) 2011, 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 7018098
* @summary CacheFSInfo persists too long
* @library ../lib
* @build JavacTestingAbstractProcessor T7018098
* @run main T7018098
*/
import java.io.*;
import java.util.*;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedOptions;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import com.sun.tools.javac.file.FSInfo;
import com.sun.tools.javac.processing.JavacProcessingEnvironment;
import com.sun.tools.javac.util.Context;
@SupportedOptions("expect")
public class T7018098 extends JavacTestingAbstractProcessor {
public static void main(String... args) throws Exception {
new T7018098().run();
}
static File testDir = new File("T7018098.dir");
void run() throws Exception {
String myName = T7018098.class.getSimpleName();
File testSrc = new File(System.getProperty("test.src"));
File file = new File(testSrc, myName + ".java");
_assert(!testDir.exists());
compile(
"-proc:only",
"-processor", myName,
"-Aexpect=false",
file.getPath());
testDir.mkdirs();
_assert(testDir.exists());
compile(
"-proc:only",
"-processor", myName,
"-Aexpect=true",
file.getPath());
}
void _assert(boolean cond) {
if (!cond)
throw new AssertionError();
}
void compile(String... args) throws Exception {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
int rc = com.sun.tools.javac.Main.compile(args, pw);
pw.close();
String out = sw.toString();
if (!out.isEmpty())
System.err.println(out);
if (rc != 0)
throw new Exception("compilation failed unexpectedly: rc=" + rc);
}
//---------------
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Context context = ((JavacProcessingEnvironment) processingEnv).getContext();
FSInfo fsInfo = context.get(FSInfo.class);
round++;
if (round == 1) {
boolean expect = Boolean.valueOf(options.get("expect"));
checkEqual("cache result", fsInfo.isDirectory(testDir), expect);
initialFSInfo = fsInfo;
} else {
checkEqual("fsInfo", fsInfo, initialFSInfo);
}
return true;
}
<T> void checkEqual(String label, T actual, T expected) {
if (actual != expected)
messager.printMessage(Diagnostic.Kind.ERROR,
"Unexpected value for " + label
+ "; expected: " + expected
+ "; found: " + actual);
}
int round = 0;
FSInfo initialFSInfo;
}

View File

@ -0,0 +1,15 @@
/*
* @test /nodynamiccopyright/
* @bug 7020043
*
* @summary Project Coin: diamond allowed on non-generic type
* @author R&eacute;mi Forax
* @compile/fail/ref=Neg12.out Neg12.java -XDrawDiagnostics
*
*/
class DiamondRaw {
public static void main(String[] args) {
String s = new String<>("foo");
}
}

View File

@ -0,0 +1,2 @@
Neg12.java:13:27: compiler.err.cant.apply.diamond.1: java.lang.String, (compiler.misc.diamond.non.generic: java.lang.String)
1 error

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2011, 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,7 +25,7 @@
* @test
* @bug 6906175 6915476 6915497 7006564
* @summary Path-based JavaFileManager
* @compile -g HelloPathWorld.java
* @compile -g CompileTest.java HelloPathWorld.java
* @run main CompileTest
*/

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2011, 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 6505047
* @summary javax.lang.model.element.Element.getEnclosingElement() doesn't return null for type parameter
* @library ../../../lib
* @build JavacTestingAbstractProcessor TestTypeParameter
* @compile -processor TestTypeParameter -proc:only TestTypeParameter.java
*/
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.element.*;
import javax.lang.model.util.*;
import javax.tools.*;
public class TestTypeParameter<T> extends JavacTestingAbstractProcessor {
int round = 0;
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (++round == 1) {
int found = (new Scanner()).scan(roundEnv.getRootElements(), null);
if (found == expect) {
note("generic elements found and verified: " + found);
} else {
error("unexpected number of results: expected " + expect
+ ", found " + found);
}
}
return true;
}
class Scanner extends ElementScanner7<Integer,Void> {
@Override
public Integer visitExecutable(ExecutableElement e, Void p) {
super.visitExecutable(e, p);
found += check(e, e.getTypeParameters());
return found;
}
@Override
public Integer visitType(TypeElement e, Void p) {
super.visitType(e, p);
found += check(e, e.getTypeParameters());
return found;
}
int found;
}
/**
* Check if type parameters, if any, have expected owner.
* Return 1 if typarams not empty and all have expected owner, else return 0.
*/
int check(Element e, List<? extends TypeParameterElement> typarams) {
note("checking " + e, e);
if (typarams.isEmpty()) {
note("no type parameters found", e);
return 0;
}
for (TypeParameterElement tpe: typarams) {
note("checking type parameter " + tpe, tpe);
if (tpe.getEnclosingElement() != e) {
error("unexpected owner; expected: " + e
+ ", found " + tpe.getEnclosingElement(),
tpe);
return 0;
}
if (tpe.getEnclosingElement() != tpe.getGenericElement()) {
error("unexpected generic element; expected: " + tpe.getGenericElement()
+ ", found " + tpe.getEnclosingElement(),
tpe);
return 0;
}
}
note("verified " + e, e);
return 1;
}
void note(String msg) {
messager.printMessage(Diagnostic.Kind.NOTE, msg);
}
void note(String msg, Element e) {
messager.printMessage(Diagnostic.Kind.NOTE, msg, e);
}
void error(String msg, Element e) {
messager.printMessage(Diagnostic.Kind.ERROR, msg, e);
}
void error(String msg) {
messager.printMessage(Diagnostic.Kind.ERROR, msg);
}
// additional generic elements to test
<X> X m(X x) { return x; }
interface Intf<X> { X m() ; }
class Class<X> {
<Y> Class() { }
}
final int expect = 5; // top level class, plus preceding examples
}

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2011, 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 7017664
* @summary Basher for CompoundScopes
*/
import java.util.Random;
import java.util.Map;
import java.util.HashMap;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.code.*;
import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.file.JavacFileManager;
public class CompoundScopeTest {
public static void main(String... args) throws Exception {
new CompoundScopeTest().run(args);
}
static final int MAX_SYMBOLS_COUNT = 20;
static final int PASSES = 10;
void run(String... args) throws Exception {
int count = PASSES;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("-seed") && (i + 1 < args.length))
seed = Long.parseLong(args[++i]);
else if(arg.equals("-tests") && (i + 1 < args.length))
count = Integer.parseInt(args[++i]);
else
throw new Exception("unknown arg: " + arg);
}
rgen = new Random(seed);
for (int i = 0; i < count; i++) {
Test t = new Test();
t.run();
}
if (errors > 0)
throw new Exception(errors + " errors found");
}
/**
* Write a message to stderr.
*/
void log(String msg) {
System.err.println(msg);
}
/**
* Write an error message to stderr.
*/
void error(String msg) {
System.err.println("Error: " + msg);
errors++;
}
Random rgen;
long seed = 0;
int errors;
/** Class to encapsulate a test run. */
class Test {
List<Symbol> elems = List.nil();
Map<Name, List<Symbol>> shadowedMap = new HashMap<Name, List<Symbol>>();
/** Run the test. */
void run() throws Exception {
log ("starting test");
setup();
Scope[] scopes = { createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)),
createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)),
createScope(rgen.nextInt(MAX_SYMBOLS_COUNT)) };
boolean[][] scopeNesting = { {false, true, false, true},
{false, true, true, true},
{false, false, true, true} };
/**
* We want to generate (and check) the following compound scopes:
* C1 = C(S1, S2, S3)
* C2 = C((S1, S2), S3)
* C3 = C(S1, (S2, S3))
* C3 = C(C(S1, S2, S3))
*/
for (int i = 0 ; i < 4 ; i ++) {
CompoundScope root = new CompoundScope(symtab.noSymbol);
CompoundScope sub = new CompoundScope(symtab.noSymbol);
boolean subAdded = false;
for (int sc = 0 ; sc < 3 ; sc ++) {
if (scopeNesting[sc][i]) {
sub.addSubScope(scopes[sc]);
if (!subAdded) {
root.addSubScope(sub);
subAdded = true;
}
} else {
root.addSubScope(scopes[sc]);
}
}
log("testing scope: " + root);
checkElems(root);
checkShadowed(root);
}
}
/**
* Create a scope containing a given number of synthetic symbols
*/
Scope createScope(int nelems) {
Scope s = new Scope(symtab.noSymbol);
for (int i = 0 ; i < nelems ; i++) {
Symbol sym = new TypeSymbol(0, names.fromString("s" + i), null, null);
s.enter(sym);
elems = elems.prepend(sym);
List<Symbol> shadowed = shadowedMap.get(sym.name);
if (shadowed == null) {
shadowed = List.nil();
}
shadowedMap.put(sym.name, shadowed.prepend(sym));
}
return s;
}
/**
* Setup compiler context
*/
void setup() {
log ("setup");
context = new Context();
JavacFileManager.preRegister(context); // required by ClassReader which is required by Symtab
names = Names.instance(context); // Name.Table impls tied to an instance of Names
symtab = Symtab.instance(context);
}
/**
* Check that CompoundScope.getElements() correctly visits all symbols
* in all subscopes (in the correct order)
*/
void checkElems(CompoundScope cs) {
List<Symbol> allSymbols = elems;
int count = 0;
for (Symbol s : cs.getElements()) {
checkSameSymbols(s, allSymbols.head);
allSymbols = allSymbols.tail;
count++;
}
if (count != elems.size()) {
error("CompoundScope.getElements() did not returned enough symbols");
}
}
/**
* Check that CompoundScope.getElements() correctly visits all symbols
* with a given name in all subscopes (in the correct order)
*/
void checkShadowed(CompoundScope cs) {
for (Map.Entry<Name, List<Symbol>> shadowedEntry : shadowedMap.entrySet()) {
int count = 0;
List<Symbol> shadowed = shadowedEntry.getValue();
Name name = shadowedEntry.getKey();
for (Symbol s : cs.getElementsByName(name)) {
checkSameSymbols(s, shadowed.head);
shadowed = shadowed.tail;
count++;
}
if (count != shadowedEntry.getValue().size()) {
error("CompoundScope.lookup() did not returned enough symbols for name " + name);
}
}
}
void checkSameSymbols(Symbol found, Symbol req) {
if (found != req) {
error("Symbol mismatch - found : " + found + ":" + found.hashCode() + "\n" +
" required : " + req + ":" + req.hashCode());
}
}
Context context;
Symtab symtab;
Names names;
}
}

View File

@ -0,0 +1,129 @@
/*
* Copyright (c) 2011, 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 7017664
* @summary Basher for CompoundScopes
*/
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.code.Symbol.*;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import javax.lang.model.element.Element;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import static javax.tools.JavaFileObject.Kind;
public class ImplementationCacheTest {
static class SourceFile extends SimpleJavaFileObject {
final String source = "interface I { void m(); }\n" +
"class A implements I { public void m() {} }\n" +
"class B extends A { }\n";
public SourceFile() {
super(URI.create("test.java"), Kind.SOURCE);
}
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return source;
}
}
public static void main(String[] args) throws IOException {
List<? extends JavaFileObject> files = Arrays.asList(new SourceFile());
JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
JavacTask ct = (JavacTask)tool.getTask(null, null, null, null, null, files);
Context ctx = new Context();
JavacFileManager.preRegister(ctx);
checkImplementationCache(ct.analyze(), Types.instance(ctx));
}
static void checkImplementationCache(Iterable<? extends Element> elements, Types types) {
if (types == null) {
throw new AssertionError("problems initializing Types");
}
Symbol a = null;
Symbol b = null;
Symbol i = null;
for (Element e : elements) {
if (e.getSimpleName().contentEquals("A")) {
a = (Symbol)e;
} else if (e.getSimpleName().contentEquals("B")) {
b = (Symbol)e;
} else if (e.getSimpleName().contentEquals("I")) {
i = (Symbol)e;
}
}
if (a == null || b == null || i == null) {
throw new AssertionError("missing class");
}
MethodSymbol I_m = null;
for (Symbol sym : i.members().getElements()) {
if (sym.name.contentEquals("m")) {
I_m = (MethodSymbol)sym;
}
}
if (I_m == null) {
throw new AssertionError("missing method m() in scope of interface I");
}
Symbol impl = I_m.implementation((TypeSymbol)b, types, true);
if (impl == null || impl.owner != a) {
throw new AssertionError("wrong implementation for m() in B");
}
b.members().enter(I_m.clone(b));
Symbol newImpl = I_m.implementation((TypeSymbol)b, types, true);
if (newImpl == impl) {
throw new AssertionError("stale implementation for m() in B");
}
if (newImpl == null || newImpl.owner != b) {
throw new AssertionError("wrong implementation for m() in B");
}
}
}