--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Dec 04 15:22:53 2014 -0800
@@ -58,6 +58,7 @@
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.main.Option.*;
+import com.sun.tools.javac.util.Dependencies.CompletionCause;
/**
* This class provides operations to locate class definitions
@@ -270,7 +271,7 @@
if (sym.kind == TYP) {
try {
ClassSymbol c = (ClassSymbol) sym;
- dependencies.push(c);
+ dependencies.push(c, CompletionCause.CLASS_READER);
c.members_field = new Scope.ErrorScope(c); // make sure it's always defined
annotate.enterStart();
try {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java Thu Dec 04 15:22:53 2014 -0800
@@ -168,6 +168,7 @@
public static final KindSelector MTH = new KindSelector(0x10);
public static final KindSelector ERR = new KindSelector(0x3f);
public static final KindSelector POLY = new KindSelector(0x20);
+ public static final KindSelector ASG = new KindSelector(0x44);
//common derived selectors
public static final KindSelector TYP_PCK = of(TYP, PCK);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java Thu Dec 04 15:22:53 2014 -0800
@@ -80,6 +80,16 @@
return l;
}
+ /**
+ * Returns a new Lint that has the given LintCategory suppressed.
+ */
+ public Lint suppress(LintCategory lc) {
+ Lint l = new Lint(this);
+ l.values.remove(lc);
+ l.suppressedValues.add(lc);
+ return l;
+ }
+
private final AugmentVisitor augmentor;
private final EnumSet<LintCategory> values;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Scope.java Thu Dec 04 15:22:53 2014 -0800
@@ -25,13 +25,18 @@
package com.sun.tools.javac.code;
+import com.sun.tools.javac.code.Kinds.Kind;
import java.util.*;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.Scope.LookupKind.RECURSIVE;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
/** A scope represents an area of visibility in a Java program. The
* Scope class is a container for symbols which provides
@@ -672,28 +677,67 @@
}
- public static class NamedImportScope extends CompoundScope {
+ public static class ImportScope extends CompoundScope {
+
+ public ImportScope(Symbol owner) {
+ super(owner);
+ }
+
+ /**Finalize the content of the ImportScope to speed-up future lookups.
+ * No further changes to class hierarchy or class content will be reflected.
+ */
+ public void finalizeScope() {
+ for (List<Scope> scopes = this.subScopes; scopes.nonEmpty(); scopes = scopes.tail) {
+ Scope impScope = scopes.head;
+
+ if (impScope instanceof FilterImportScope && impScope.owner.kind == Kind.TYP) {
+ WriteableScope finalized = WriteableScope.create(impScope.owner);
+
+ for (Symbol sym : impScope.getSymbols()) {
+ finalized.enter(sym);
+ }
+
+ finalized.addScopeListener(new ScopeListener() {
+ @Override
+ public void symbolAdded(Symbol sym, Scope s) {
+ Assert.error("The scope is sealed.");
+ }
+ @Override
+ public void symbolRemoved(Symbol sym, Scope s) {
+ Assert.error("The scope is sealed.");
+ }
+ });
+
+ scopes.head = finalized;
+ }
+ }
+ }
+
+ }
+
+ public static class NamedImportScope extends ImportScope {
public NamedImportScope(Symbol owner, Scope currentFileScope) {
super(owner);
prependSubScope(currentFileScope);
}
- public void importByName(Scope delegate, Scope origin, Name name, ImportFilter filter) {
- appendScope(new FilterImportScope(delegate, origin, name, filter, true));
+ public Scope importByName(Types types, Scope origin, Name name, ImportFilter filter) {
+ return appendScope(new FilterImportScope(types, origin, name, filter, true));
}
- public void importType(Scope delegate, Scope origin, Symbol sym) {
- appendScope(new SingleEntryScope(delegate.owner, sym, origin));
+ public Scope importType(Scope delegate, Scope origin, Symbol sym) {
+ return appendScope(new SingleEntryScope(delegate.owner, sym, origin));
}
- private void appendScope(Scope newScope) {
+ private Scope appendScope(Scope newScope) {
List<Scope> existingScopes = this.subScopes.reverse();
subScopes = List.of(existingScopes.head);
subScopes = subScopes.prepend(newScope);
for (Scope s : existingScopes.tail) {
subScopes = subScopes.prepend(s);
}
+ return newScope;
}
private static class SingleEntryScope extends Scope {
@@ -735,24 +779,23 @@
}
}
- public static class StarImportScope extends CompoundScope {
+ public static class StarImportScope extends ImportScope {
public StarImportScope(Symbol owner) {
super(owner);
}
- public void importAll(Scope delegate,
- Scope origin,
+ public void importAll(Types types, Scope origin,
ImportFilter filter,
boolean staticImport) {
for (Scope existing : subScopes) {
Assert.check(existing instanceof FilterImportScope);
FilterImportScope fis = (FilterImportScope) existing;
- if (fis.delegate == delegate && fis.origin == origin &&
- fis.filter == filter && fis.staticImport == staticImport)
+ if (fis.origin == origin && fis.filter == filter &&
+ fis.staticImport == staticImport)
return ; //avoid entering the same scope twice
}
- prependSubScope(new FilterImportScope(delegate, origin, null, filter, staticImport));
+ prependSubScope(new FilterImportScope(types, origin, null, filter, staticImport));
}
}
@@ -763,19 +806,19 @@
private static class FilterImportScope extends Scope {
- private final Scope delegate;
+ private final Types types;
private final Scope origin;
private final Name filterName;
private final ImportFilter filter;
private final boolean staticImport;
- public FilterImportScope(Scope delegate,
+ public FilterImportScope(Types types,
Scope origin,
Name filterName,
ImportFilter filter,
boolean staticImport) {
- super(delegate.owner);
- this.delegate = delegate;
+ super(origin.owner);
+ this.types = types;
this.origin = origin;
this.filterName = filterName;
this.filter = filter;
@@ -783,19 +826,31 @@
}
@Override
- public Iterable<Symbol> getSymbols(Filter<Symbol> sf, LookupKind lookupKind) {
+ public Iterable<Symbol> getSymbols(final Filter<Symbol> sf, final LookupKind lookupKind) {
if (filterName != null)
return getSymbolsByName(filterName, sf, lookupKind);
- return new FilteredIterable(delegate.getSymbols(sf, lookupKind));
+ SymbolImporter si = new SymbolImporter(staticImport) {
+ @Override
+ Iterable<Symbol> doLookup(TypeSymbol tsym) {
+ return tsym.members().getSymbols(sf, lookupKind);
+ }
+ };
+ return si.importFrom((TypeSymbol) origin.owner) :: iterator;
}
@Override
- public Iterable<Symbol> getSymbolsByName(Name name,
- Filter<Symbol> sf,
- LookupKind lookupKind) {
+ public Iterable<Symbol> getSymbolsByName(final Name name,
+ final Filter<Symbol> sf,
+ final LookupKind lookupKind) {
if (filterName != null && filterName != name)
return Collections.emptyList();
- return new FilteredIterable(delegate.getSymbolsByName(name, sf, lookupKind));
+ SymbolImporter si = new SymbolImporter(staticImport) {
+ @Override
+ Iterable<Symbol> doLookup(TypeSymbol tsym) {
+ return tsym.members().getSymbolsByName(name, sf, lookupKind);
+ }
+ };
+ return si.importFrom((TypeSymbol) origin.owner) :: iterator;
}
@Override
@@ -808,57 +863,31 @@
return staticImport;
}
- private class FilteredIterator implements Iterator<Symbol> {
- private final Iterator<Symbol> delegate;
- private Symbol next;
+ abstract class SymbolImporter {
+ Set<Symbol> processed = new HashSet<>();
+ List<Iterable<Symbol>> delegates = List.nil();
+ final boolean inspectSuperTypes;
+ public SymbolImporter(boolean inspectSuperTypes) {
+ this.inspectSuperTypes = inspectSuperTypes;
+ }
+ Stream<Symbol> importFrom(TypeSymbol tsym) {
+ if (tsym == null || !processed.add(tsym))
+ return Stream.empty();
- public FilteredIterator(Iterator<Symbol> delegate) {
- this.delegate = delegate;
- update();
- }
+ Stream<Symbol> result = Stream.empty();
- void update() {
- while (delegate.hasNext()) {
- if (filter.accepts(origin, next = delegate.next()))
- return;
+ if (inspectSuperTypes) {
+ // also import inherited names
+ result = importFrom(types.supertype(tsym.type).tsym);
+ for (Type t : types.interfaces(tsym.type))
+ result = Stream.concat(importFrom(t.tsym), result);
}
- next = null;
- }
-
- @Override
- public boolean hasNext() {
- return next != null;
- }
-
- @Override
- public Symbol next() {
- Symbol result = next;
-
- update();
-
- return result;
+ return Stream.concat(StreamSupport.stream(doLookup(tsym).spliterator(), false)
+ .filter(s -> filter.accepts(origin, s)),
+ result);
}
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException("Not supported.");
- }
-
- }
-
- private class FilteredIterable implements Iterable<Symbol> {
-
- private final Iterable<Symbol> unfiltered;
-
- public FilteredIterable(Iterable<Symbol> unfiltered) {
- this.unfiltered = unfiltered;
- }
-
- @Override
- public Iterator<Symbol> iterator() {
- return new FilteredIterator(unfiltered.iterator());
- }
+ abstract Iterable<Symbol> doLookup(TypeSymbol tsym);
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java Thu Dec 04 15:22:53 2014 -0800
@@ -140,6 +140,9 @@
public boolean allowTryWithResources() {
return compareTo(JDK1_7) >= 0;
}
+ public boolean allowEffectivelyFinalVariablesInTryWithResources() {
+ return compareTo(JDK1_9) >= 0;
+ }
public boolean allowBinaryLiterals() {
return compareTo(JDK1_7) >= 0;
}
@@ -149,6 +152,9 @@
public boolean allowStringsInSwitch() {
return compareTo(JDK1_7) >= 0;
}
+ public boolean allowDeprecationOnImport() {
+ return compareTo(JDK1_9) < 0;
+ }
public boolean allowSimplifiedVarargs() {
return compareTo(JDK1_7) >= 0;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Dec 04 15:22:53 2014 -0800
@@ -87,6 +87,7 @@
final Check chk;
final Flow flow;
final MemberEnter memberEnter;
+ final TypeEnter typeEnter;
final TreeMaker make;
final ConstFold cfolder;
final Enter enter;
@@ -116,6 +117,7 @@
chk = Check.instance(context);
flow = Flow.instance(context);
memberEnter = MemberEnter.instance(context);
+ typeEnter = TypeEnter.instance(context);
make = TreeMaker.instance(context);
enter = Enter.instance(context);
infer = Infer.instance(context);
@@ -148,7 +150,7 @@
identifyLambdaCandidate = options.getBoolean("identifyLambdaCandidate", false);
statInfo = new ResultInfo(KindSelector.NIL, Type.noType);
- varInfo = new ResultInfo(KindSelector.VAR, Type.noType);
+ varAssignmentInfo = new ResultInfo(KindSelector.ASG, Type.noType);
unknownExprInfo = new ResultInfo(KindSelector.VAL, Type.noType);
unknownAnyPolyInfo = new ResultInfo(KindSelector.VAL, Infer.anyPoly);
unknownTypeInfo = new ResultInfo(KindSelector.TYP, Type.noType);
@@ -498,7 +500,7 @@
}
final ResultInfo statInfo;
- final ResultInfo varInfo;
+ final ResultInfo varAssignmentInfo;
final ResultInfo unknownAnyPolyInfo;
final ResultInfo unknownExprInfo;
final ResultInfo unknownTypeInfo;
@@ -629,19 +631,19 @@
/** Attribute the arguments in a method call, returning the method kind.
*/
- KindSelector attribArgs(List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
- boolean polykind = false;
+ KindSelector attribArgs(KindSelector initialKind, List<JCExpression> trees, Env<AttrContext> env, ListBuffer<Type> argtypes) {
+ KindSelector kind = initialKind;
for (JCExpression arg : trees) {
Type argtype;
if (allowPoly && deferredAttr.isDeferred(env, arg)) {
argtype = deferredAttr.new DeferredType(arg, env);
- polykind = true;
+ kind = KindSelector.of(KindSelector.POLY, kind);
} else {
argtype = chk.checkNonVoid(arg, attribTree(arg, env, unknownAnyPolyInfo));
}
argtypes.append(argtype);
}
- return polykind ? KindSelector.VAL_POLY : KindSelector.VAL;
+ return kind;
}
/** Attribute a type argument list, returning a list of types.
@@ -949,7 +951,7 @@
if (body.stats.isEmpty() ||
!TreeInfo.isSelfCall(body.stats.head)) {
body.stats = body.stats.
- prepend(memberEnter.SuperCall(make.at(body.pos),
+ prepend(typeEnter.SuperCall(make.at(body.pos),
List.<Type>nil(),
List.<JCVariableDecl>nil(),
false));
@@ -1293,7 +1295,7 @@
}
};
ResultInfo twrResult =
- new ResultInfo(KindSelector.VAL,
+ new ResultInfo(KindSelector.VAR,
syms.autoCloseableType,
twrContext);
if (resource.hasTag(VARDEF)) {
@@ -1704,7 +1706,7 @@
localEnv.info.isSelfCall = true;
// Attribute arguments, yielding list of argument types.
- attribArgs(tree.args, localEnv, argtypesBuf);
+ KindSelector kind = attribArgs(KindSelector.MTH, tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
typeargtypes = attribTypes(tree.typeargs, localEnv);
@@ -1770,7 +1772,7 @@
// (this will also set the tree's type)
Type mpt = newMethodTemplate(resultInfo.pt, argtypes, typeargtypes);
checkId(tree.meth, site, sym, localEnv,
- new ResultInfo(KindSelector.MTH, mpt));
+ new ResultInfo(kind, mpt));
}
// Otherwise, `site' is an error type and we do nothing
}
@@ -1778,7 +1780,7 @@
} else {
// Otherwise, we are seeing a regular method call.
// Attribute the arguments, yielding list of argument types, ...
- KindSelector kind = attribArgs(tree.args, localEnv, argtypesBuf);
+ KindSelector kind = attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
argtypes = argtypesBuf.toList();
typeargtypes = attribAnyTypes(tree.typeargs, localEnv);
@@ -1958,7 +1960,7 @@
// Attribute constructor arguments.
ListBuffer<Type> argtypesBuf = new ListBuffer<>();
final KindSelector pkind =
- attribArgs(tree.args, localEnv, argtypesBuf);
+ attribArgs(KindSelector.VAL, tree.args, localEnv, argtypesBuf);
List<Type> argtypes = argtypesBuf.toList();
List<Type> typeargtypes = attribTypes(tree.typeargs, localEnv);
@@ -2942,7 +2944,7 @@
}
public void visitAssign(JCAssign tree) {
- Type owntype = attribTree(tree.lhs, env.dup(tree), varInfo);
+ Type owntype = attribTree(tree.lhs, env.dup(tree), varAssignmentInfo);
Type capturedType = capture(owntype);
attribExpr(tree.rhs, env, owntype);
result = check(tree, capturedType, KindSelector.VAL, resultInfo);
@@ -2950,7 +2952,7 @@
public void visitAssignop(JCAssignOp tree) {
// Attribute arguments.
- Type owntype = attribTree(tree.lhs, env, varInfo);
+ Type owntype = attribTree(tree.lhs, env, varAssignmentInfo);
Type operand = attribExpr(tree.rhs, env);
// Find operator.
Symbol operator = tree.operator = rs.resolveBinaryOperator(
@@ -2976,7 +2978,7 @@
public void visitUnary(JCUnary tree) {
// Attribute arguments.
Type argtype = (tree.getTag().isIncOrDecUnaryOp())
- ? attribTree(tree.arg, env, varInfo)
+ ? attribTree(tree.arg, env, varAssignmentInfo)
: chk.checkNonVoid(tree.arg.pos(), attribExpr(tree.arg, env));
// Find operator.
@@ -3156,7 +3158,7 @@
// If we are expecting a variable (as opposed to a value), check
// that the variable is assignable in the current environment.
- if (pkind() == KindSelector.VAR)
+ if (KindSelector.ASG.subset(pkind()))
checkAssignable(tree.pos(), v, null, env);
}
@@ -3233,6 +3235,10 @@
// Determine the symbol represented by the selection.
env.info.pendingResolutionPhase = null;
Symbol sym = selectSym(tree, sitesym, site, env, resultInfo);
+ if (sym.kind == VAR && sym.name != names._super && env.info.defaultSuperCallSite != null) {
+ log.error(tree.selected.pos(), "not.encl.class", site.tsym);
+ sym = syms.errSymbol;
+ }
if (sym.exists() && !isType(sym) && pkind().contains(KindSelector.TYP_PCK)) {
site = capture(site);
sym = selectSym(tree, sitesym, site, env, resultInfo);
@@ -3255,7 +3261,7 @@
// If we are expecting a variable (as opposed to a value), check
// that the variable is assignable in the current environment.
- if (pkind() == KindSelector.VAR)
+ if (KindSelector.ASG.subset(pkind()))
checkAssignable(tree.pos(), v, tree.selected, env);
}
@@ -3538,7 +3544,7 @@
// Test (4): if symbol is an instance field of a raw type,
// which is being assigned to, issue an unchecked warning if
// its type changes under erasure.
- if (resultInfo.pkind == KindSelector.VAR &&
+ if (KindSelector.ASG.subset(pkind()) &&
v.owner.kind == TYP &&
(v.flags() & STATIC) == 0 &&
(site.hasTag(CLASS) || site.hasTag(TYPEVAR))) {
@@ -4486,14 +4492,15 @@
super.visitTypeTest(tree);
}
public void visitNewClass(JCNewClass tree) {
- if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
- checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
- tree.clazz.type.tsym);
- }
- if (tree.def != null) {
- checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
- }
- if (tree.clazz.type != null) {
+ if (tree.clazz != null && tree.clazz.type != null) {
+ if (tree.clazz.hasTag(ANNOTATED_TYPE)) {
+ checkForDeclarationAnnotations(((JCAnnotatedType) tree.clazz).annotations,
+ tree.clazz.type.tsym);
+ }
+ if (tree.def != null) {
+ checkForDeclarationAnnotations(tree.def.mods.annotations, tree.clazz.type.tsym);
+ }
+
validateAnnotatedType(tree.clazz, tree.clazz.type);
}
super.visitNewClass(tree);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java Thu Dec 04 15:22:53 2014 -0800
@@ -28,7 +28,6 @@
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;
@@ -40,6 +39,7 @@
import com.sun.tools.javac.code.Lint;
import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Scope.CompoundScope;
import com.sun.tools.javac.code.Scope.NamedImportScope;
import com.sun.tools.javac.code.Scope.WriteableScope;
import com.sun.tools.javac.code.Type.*;
@@ -3415,56 +3415,69 @@
}
}
- /** 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.
+ /**Check that types imported through the ordinary imports don't clash with types imported
+ * by other (static or ordinary) imports. Note that two static imports may import two clashing
+ * types without an error on the imports.
+ * @param toplevel The toplevel tree for which the test should be performed.
*/
- 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.
- */
- boolean checkUniqueStaticImport(DiagnosticPosition pos, JCCompilationUnit toplevel, Symbol sym) {
- return checkUniqueImport(pos, toplevel, sym, true);
+ void checkImportsUnique(JCCompilationUnit toplevel) {
+ WriteableScope ordinallyImportedSoFar = WriteableScope.create(toplevel.packge);
+ WriteableScope staticallyImportedSoFar = WriteableScope.create(toplevel.packge);
+ WriteableScope topLevelScope = toplevel.toplevelScope;
+
+ for (JCTree def : toplevel.defs) {
+ if (!def.hasTag(IMPORT))
+ continue;
+
+ JCImport imp = (JCImport) def;
+
+ if (imp.importScope == null)
+ continue;
+
+ for (Symbol sym : imp.importScope.getSymbols(sym -> sym.kind == TYP)) {
+ if (imp.isStatic()) {
+ checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, true);
+ staticallyImportedSoFar.enter(sym);
+ } else {
+ checkUniqueImport(imp.pos(), ordinallyImportedSoFar, staticallyImportedSoFar, topLevelScope, sym, false);
+ ordinallyImportedSoFar.enter(sym);
+ }
+ }
+
+ imp.importScope = null;
+ }
}
/** 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 staticImport Whether or not this was a static import
+ * @param pos Position for error reporting.
+ * @param ordinallyImportedSoFar A Scope containing types imported so far through
+ * ordinary imports.
+ * @param staticallyImportedSoFar A Scope containing types imported so far through
+ * static imports.
+ * @param topLevelScope The current file's top-level Scope
+ * @param sym The symbol.
+ * @param staticImport Whether or not this was a static import
*/
- 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 = namedImportScope.getOrigin(byName) == topLevelScope;
- if ((isClassDecl || sym != byName) &&
- sym.kind == byName.kind &&
- sym.name != names.error &&
- (!staticImport || !namedImportScope.isStaticallyImported(byName))) {
- if (!byName.type.isErroneous()) {
- if (!isClassDecl) {
- if (staticImport)
- log.error(pos, "already.defined.static.single.import", byName);
- else
- log.error(pos, "already.defined.single.import", byName);
- }
- else if (sym != byName)
- log.error(pos, "already.defined.this.unit", byName);
- }
- return false;
- }
+ private boolean checkUniqueImport(DiagnosticPosition pos, Scope ordinallyImportedSoFar,
+ Scope staticallyImportedSoFar, Scope topLevelScope,
+ Symbol sym, boolean staticImport) {
+ Filter<Symbol> duplicates = candidate -> candidate != sym && !candidate.type.isErroneous();
+ Symbol clashing = ordinallyImportedSoFar.findFirst(sym.name, duplicates);
+ if (clashing == null && !staticImport) {
+ clashing = staticallyImportedSoFar.findFirst(sym.name, duplicates);
+ }
+ if (clashing != null) {
+ if (staticImport)
+ log.error(pos, "already.defined.static.single.import", clashing);
+ else
+ log.error(pos, "already.defined.single.import", clashing);
+ return false;
+ }
+ clashing = topLevelScope.findFirst(sym.name, duplicates);
+ if (clashing != null) {
+ log.error(pos, "already.defined.this.unit", clashing);
+ return false;
}
return true;
}
@@ -3570,18 +3583,13 @@
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);
+ 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);
}
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Thu Dec 04 15:22:53 2014 -0800
@@ -47,40 +47,34 @@
import static com.sun.tools.javac.code.Kinds.Kind.*;
/** This class enters symbols for all encountered definitions into
- * the symbol table. The pass consists of two phases, organized as
- * follows:
+ * the symbol table. The pass consists of high-level two phases,
+ * organized as follows:
*
* <p>In the first phase, all class symbols are entered into their
* enclosing scope, descending recursively down the tree for classes
* which are members of other classes. The class symbols are given a
- * MemberEnter object as completer.
+ * TypeEnter object as completer.
*
* <p>In the second phase classes are completed using
- * MemberEnter.complete(). Completion might occur on demand, but
+ * TypeEnter.complete(). Completion might occur on demand, but
* any classes that are not completed that way will be eventually
- * completed by processing the `uncompleted' queue. Completion
- * entails (1) determination of a class's parameters, supertype and
- * interfaces, as well as (2) entering all symbols defined in the
+ * completed by processing the `uncompleted' queue. Completion
+ * entails determination of a class's parameters, supertype and
+ * interfaces, as well as entering all symbols defined in the
* class into its scope, with the exception of class symbols which
- * have been entered in phase 1. (2) depends on (1) having been
- * completed for a class and all its superclasses and enclosing
- * classes. That's why, after doing (1), we put classes in a
- * `halfcompleted' queue. Only when we have performed (1) for a class
- * and all it's superclasses and enclosing classes, we proceed to
- * (2).
+ * have been entered in phase 1.
*
* <p>Whereas the first phase is organized as a sweep through all
- * compiled syntax trees, the second phase is demand. Members of a
+ * compiled syntax trees, the second phase is on-demand. Members of a
* class are entered when the contents of a class are first
* accessed. This is accomplished by installing completer objects in
- * class symbols for compiled classes which invoke the member-enter
+ * class symbols for compiled classes which invoke the type-enter
* phase for the corresponding class tree.
*
* <p>Classes migrate from one phase to the next via queues:
*
* <pre>{@literal
- * class enter -> (Enter.uncompleted) --> member enter (1)
- * -> (MemberEnter.halfcompleted) --> member enter (2)
+ * class enter -> (Enter.uncompleted) --> type enter
* -> (Todo) --> attribute
* (only for toplevel classes)
* }</pre>
@@ -98,7 +92,7 @@
Check chk;
TreeMaker make;
Annotate annotate;
- MemberEnter memberEnter;
+ TypeEnter typeEnter;
Types types;
Lint lint;
Names names;
@@ -122,7 +116,7 @@
make = TreeMaker.instance(context);
syms = Symtab.instance(context);
chk = Check.instance(context);
- memberEnter = MemberEnter.instance(context);
+ typeEnter = TypeEnter.instance(context);
types = Types.instance(context);
annotate = Annotate.instance(context);
lint = Lint.instance(context);
@@ -391,7 +385,7 @@
typeEnvs.put(c, localEnv);
// Fill out class fields.
- c.completer = memberEnter;
+ c.completer = typeEnter;
c.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, c, tree);
c.sourcefile = env.toplevel.sourcefile;
c.members_field = WriteableScope.create(c);
@@ -469,22 +463,23 @@
complete(trees, null);
}
- /** Main method: enter one class from a list of toplevel trees and
- * place the rest on uncompleted for later processing.
+ /** Main method: enter classes from the list of toplevel trees, possibly
+ * skipping TypeEnter for all but 'c' by placing them on the uncompleted
+ * list.
* @param trees The list of trees to be processed.
- * @param c The class symbol to be processed.
+ * @param c The class symbol to be processed or null to process all.
*/
public void complete(List<JCCompilationUnit> trees, ClassSymbol c) {
annotate.enterStart();
ListBuffer<ClassSymbol> prevUncompleted = uncompleted;
- if (memberEnter.completionEnabled) uncompleted = new ListBuffer<>();
+ if (typeEnter.completionEnabled) uncompleted = new ListBuffer<>();
try {
// enter all classes, and construct uncompleted list
classEnter(trees, null);
// complete all uncompleted classes in memberEnter
- if (memberEnter.completionEnabled) {
+ if (typeEnter.completionEnabled) {
while (uncompleted.nonEmpty()) {
ClassSymbol clazz = uncompleted.next();
if (c == null || c == clazz || prevUncompleted == null)
@@ -494,16 +489,7 @@
prevUncompleted.append(clazz);
}
- // 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.isEmpty()) {
- JavaFileObject prev = log.useSource(tree.sourcefile);
- Env<AttrContext> topEnv = topLevelEnv(tree);
- memberEnter.memberEnter(tree, topEnv);
- log.useSource(prev);
- }
- }
+ typeEnter.ensureImportsChecked(trees);
}
} finally {
uncompleted = prevUncompleted;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java Thu Dec 04 15:22:53 2014 -0800
@@ -242,9 +242,15 @@
Log.DiagnosticHandler diagHandler = new Log.DiscardDiagnosticHandler(log);
try {
new AssignAnalyzer() {
+ WriteableScope enclosedSymbols = WriteableScope.create(env.enclClass.sym);
+ @Override
+ public void visitVarDef(JCVariableDecl tree) {
+ enclosedSymbols.enter(tree.sym);
+ super.visitVarDef(tree);
+ }
@Override
protected boolean trackable(VarSymbol sym) {
- return !env.info.scope.includes(sym) &&
+ return enclosedSymbols.includes(sym) &&
sym.owner.kind == MTH;
}
}.analyzeTree(env, that);
@@ -2556,6 +2562,8 @@
* This pass implements the last step of the dataflow analysis, namely
* the effectively-final analysis check. This checks that every local variable
* reference from a lambda body/local inner class is either final or effectively final.
+ * Additional this also checks that every variable that is used as an operand to
+ * try-with-resources is final or effectively final.
* As effectively final variables are marked as such during DA/DU, this pass must run after
* AssignAnalyzer.
*/
@@ -2684,6 +2692,18 @@
}
}
+ public void visitTry(JCTry tree) {
+ for (JCTree resource : tree.resources) {
+ if (!resource.hasTag(VARDEF)) {
+ Symbol var = TreeInfo.symbol(resource);
+ if (var != null && (var.flags() & (FINAL | EFFECTIVELY_FINAL)) == 0) {
+ log.error(resource.pos(), "try.with.resources.expr.effectively.final.var", var);
+ }
+ }
+ }
+ super.visitTry(tree);
+ }
+
/**************************************************************************
* main method
*************************************************************************/
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java Thu Dec 04 15:22:53 2014 -0800
@@ -40,6 +40,7 @@
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.Type.MethodType;
+import com.sun.tools.javac.code.Type.TypeVar;
import com.sun.tools.javac.code.Types;
import com.sun.tools.javac.comp.LambdaToMethod.LambdaAnalyzerPreprocessor.*;
import com.sun.tools.javac.comp.Lower.BasicFreeVarCollector;
@@ -60,6 +61,7 @@
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
+import javax.lang.model.type.TypeKind;
/**
* This pass desugars lambda expressions into static methods
@@ -759,49 +761,10 @@
int prevPos = make.pos;
try {
make.at(tree);
- Type samDesc = localContext.bridgedRefSig();
- List<Type> samPTypes = samDesc.getParameterTypes();
-
- // an extra argument is prepended in the case where the member
- // reference is an unbound instance method reference (in which
- // case the receiver expression in passed.
- VarSymbol rcvr;
- switch (tree.kind) {
- case BOUND:
- rcvr = addParameter("rec$", tree.getQualifierExpression().type, false);
- receiverExpression = attr.makeNullCheck(tree.getQualifierExpression());
- break;
- case UNBOUND:
- rcvr = addParameter("rec$", samPTypes.head, false);
- samPTypes = samPTypes.tail;
- break;
- default:
- rcvr = null;
- break;
- }
-
- // generate the parameter list for the coverted member reference.
- // the signature will match the signature of the target sam descriptor
-
- List<Type> refPTypes = tree.sym.type.getParameterTypes();
- int refSize = refPTypes.size();
- int samSize = samPTypes.size();
- // Last parameter to copy from referenced method
- int last = localContext.needsVarArgsConversion() ? refSize - 1 : refSize;
-
- List<Type> l = refPTypes;
- // Use parameter types of the referenced method, excluding final var args
- for (int i = 0; l.nonEmpty() && i < last; ++i) {
- addParameter("x$" + i, l.head, true);
- l = l.tail;
- }
- // Flatten out the var args
- for (int i = last; i < samSize; ++i) {
- addParameter("xva$" + i, tree.varargsElement, true);
- }
//body generation - this can be either a method call or a
//new instance creation expression, depending on the member reference kind
+ VarSymbol rcvr = addParametersReturnReceiver();
JCExpression expr = (tree.getMode() == ReferenceMode.INVOKE)
? expressionInvoke(rcvr)
: expressionNew();
@@ -816,6 +779,78 @@
}
}
+ /**
+ * Generate the parameter list for the converted member reference.
+ *
+ * @return The receiver variable symbol, if any
+ */
+ VarSymbol addParametersReturnReceiver() {
+ Type samDesc = localContext.bridgedRefSig();
+ List<Type> samPTypes = samDesc.getParameterTypes();
+ List<Type> descPTypes = tree.getDescriptorType(types).getParameterTypes();
+
+ // Determine the receiver, if any
+ VarSymbol rcvr;
+ switch (tree.kind) {
+ case BOUND:
+ // The receiver is explicit in the method reference
+ rcvr = addParameter("rec$", tree.getQualifierExpression().type, false);
+ receiverExpression = attr.makeNullCheck(tree.getQualifierExpression());
+ break;
+ case UNBOUND:
+ // The receiver is the first parameter, extract it and
+ // adjust the SAM and unerased type lists accordingly
+ rcvr = addParameter("rec$", samDesc.getParameterTypes().head, false);
+ samPTypes = samPTypes.tail;
+ descPTypes = descPTypes.tail;
+ break;
+ default:
+ rcvr = null;
+ break;
+ }
+ List<Type> implPTypes = tree.sym.type.getParameterTypes();
+ int implSize = implPTypes.size();
+ int samSize = samPTypes.size();
+ // Last parameter to copy from referenced method, exclude final var args
+ int last = localContext.needsVarArgsConversion() ? implSize - 1 : implSize;
+
+ // Failsafe -- assure match-up
+ boolean checkForIntersection = tree.varargsElement != null || implSize == descPTypes.size();
+
+ // Use parameter types of the implementation method unless the unerased
+ // SAM parameter type is an intersection type, in that case use the
+ // erased SAM parameter type so that the supertype relationship
+ // the implementation method parameters is not obscured.
+ // Note: in this loop, the lists implPTypes, samPTypes, and descPTypes
+ // are used as pointers to the current parameter type information
+ // and are thus not usable afterwards.
+ for (int i = 0; implPTypes.nonEmpty() && i < last; ++i) {
+ // By default use the implementation method parmeter type
+ Type parmType = implPTypes.head;
+ // If the unerased parameter type is a type variable whose
+ // bound is an intersection (eg. <T extends A & B>) then
+ // use the SAM parameter type
+ if (checkForIntersection && descPTypes.head.getKind() == TypeKind.TYPEVAR) {
+ TypeVar tv = (TypeVar) descPTypes.head;
+ if (tv.bound.getKind() == TypeKind.INTERSECTION) {
+ parmType = samPTypes.head;
+ }
+ }
+ addParameter("x$" + i, parmType, true);
+
+ // Advance to the next parameter
+ implPTypes = implPTypes.tail;
+ samPTypes = samPTypes.tail;
+ descPTypes = descPTypes.tail;
+ }
+ // Flatten out the var args
+ for (int i = last; i < samSize; ++i) {
+ addParameter("xva$" + i, tree.varargsElement, true);
+ }
+
+ return rcvr;
+ }
+
JCExpression getReceiverExpression() {
return receiverExpression;
}
@@ -2064,11 +2099,35 @@
}
/**
+ * Erasure destroys the implementation parameter subtype
+ * relationship for intersection types
+ */
+ boolean interfaceParameterIsIntersectionType() {
+ List<Type> tl = tree.getDescriptorType(types).getParameterTypes();
+ if (tree.kind == ReferenceKind.UNBOUND) {
+ tl = tl.tail;
+ }
+ for (; tl.nonEmpty(); tl = tl.tail) {
+ Type pt = tl.head;
+ if (pt.getKind() == TypeKind.TYPEVAR) {
+ TypeVar tv = (TypeVar) pt;
+ if (tv.bound.getKind() == TypeKind.INTERSECTION) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Does this reference need to be converted to a lambda
* (i.e. var args need to be expanded or "super" is used)
*/
final boolean needsConversionToLambda() {
- return isSuper || needsVarArgsConversion() || isArrayOp() ||
+ return interfaceParameterIsIntersectionType() ||
+ isSuper ||
+ needsVarArgsConversion() ||
+ isArrayOp() ||
isPrivateInOtherClass() ||
!receiverAccessible() ||
(tree.getMode() == ReferenceMode.NEW &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Dec 04 15:22:53 2014 -0800
@@ -25,75 +25,45 @@
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.*;
-import com.sun.tools.javac.util.DefinedBy.Api;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.code.Symbol.*;
import com.sun.tools.javac.code.Type.*;
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.Scope.LookupKind.NON_RECURSIVE;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
-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;
-import static com.sun.tools.javac.tree.JCTree.Tag.*;
-import com.sun.tools.javac.util.Dependencies.AttributionKind;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
-import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
-
-/** This is the second phase of Enter, in which classes are completed
- * by entering their members into the class scope using
- * MemberEnter.complete(). See Enter for an overview.
+/** Resolves field, method and constructor header, and constructs corresponding Symbols.
*
* <p><b>This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
* deletion without notice.</b>
*/
-public class MemberEnter extends JCTree.Visitor implements Completer {
+public class MemberEnter extends JCTree.Visitor {
protected static final Context.Key<MemberEnter> memberEnterKey = new Context.Key<>();
/** A switch to determine whether we check for package/class conflicts
*/
final static boolean checkClash = true;
- private final Names names;
private final Enter enter;
private final Log log;
private final Check chk;
private final Attr attr;
private final Symtab syms;
- private final TreeMaker make;
- private final Todo todo;
private final Annotate annotate;
- private final TypeAnnotations typeAnnotations;
private final Types types;
- private final JCDiagnostic.Factory diags;
- private final Source source;
- private final Target target;
private final DeferredLintHandler deferredLintHandler;
- private final Lint lint;
- private final TypeEnvs typeEnvs;
- private final Dependencies dependencies;
public static MemberEnter instance(Context context) {
MemberEnter instance = context.get(memberEnterKey);
@@ -104,172 +74,14 @@
protected MemberEnter(Context context) {
context.put(memberEnterKey, this);
- names = Names.instance(context);
enter = Enter.instance(context);
log = Log.instance(context);
chk = Check.instance(context);
attr = Attr.instance(context);
syms = Symtab.instance(context);
- make = TreeMaker.instance(context);
- todo = Todo.instance(context);
annotate = Annotate.instance(context);
- typeAnnotations = TypeAnnotations.instance(context);
types = Types.instance(context);
- diags = JCDiagnostic.Factory.instance(context);
- source = Source.instance(context);
- target = Target.instance(context);
deferredLintHandler = DeferredLintHandler.instance(context);
- lint = Lint.instance(context);
- typeEnvs = TypeEnvs.instance(context);
- dependencies = Dependencies.instance(context);
- allowTypeAnnos = source.allowTypeAnnotations();
- }
-
- /** Switch: support type annotations.
- */
- boolean allowTypeAnnos;
-
- /** A queue for classes whose members still need to be entered into the
- * symbol table.
- */
- ListBuffer<Env<AttrContext>> halfcompleted = new ListBuffer<>();
-
- /** Set to true only when the first of a set of classes is
- * processed from the half completed queue.
- */
- boolean isFirst = true;
-
- /** A flag to disable completion from time to time during member
- * enter, as we only need to look up types. This avoids
- * unnecessarily deep recursion.
- */
- boolean completionEnabled = true;
-
- /* ---------- Processing import clauses ----------------
- */
-
- /** Import all classes of a class or package on demand.
- * @param pos Position to be used for error reporting.
- * @param tsym The class or package the members of which are imported.
- * @param env The env in which the imported classes will be entered.
- */
- private void importAll(int pos,
- final TypeSymbol tsym,
- Env<AttrContext> env) {
- // Check that packages imported from exist (JLS ???).
- 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");
- throw new FatalError(msg);
- } else {
- log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym);
- }
- }
- env.toplevel.starImportScope.importAll(tsym.members(), tsym.members(), typeImportFilter, false);
- }
-
- /** Import all static members of a class or package on demand.
- * @param pos Position to be used for error reporting.
- * @param tsym The class or package the members of which are imported.
- * @param env The env in which the imported classes will be entered.
- */
- private void importStaticAll(int pos,
- final TypeSymbol tsym,
- Env<AttrContext> env) {
- final StarImportScope toScope = env.toplevel.starImportScope;
- final PackageSymbol packge = env.toplevel.packge;
- final TypeSymbol origin = tsym;
-
- // enter imported types immediately
- new SymbolImporter() {
- void doImport(TypeSymbol tsym) {
- toScope.importAll(tsym.members(), origin.members(), staticImportFilter, true);
- }
- }.importFrom(tsym);
- }
-
- /** Import statics types of a given name. Non-types are handled in Attr.
- * @param pos Position to be used for error reporting.
- * @param tsym The class from which the name is imported.
- * @param name The (simple) name being imported.
- * @param env The environment containing the named import
- * scope to add to.
- */
- private void importNamedStatic(final DiagnosticPosition pos,
- final TypeSymbol tsym,
- final Name name,
- final Env<AttrContext> env) {
- if (tsym.kind != TYP) {
- log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
- return;
- }
-
- final NamedImportScope toScope = env.toplevel.namedImportScope;
- final Scope originMembers = tsym.members();
-
- // enter imported types immediately
- new SymbolImporter() {
- void doImport(TypeSymbol tsym) {
- Set<Symbol> maskedOut = null;
- for (Symbol sym : tsym.members().getSymbolsByName(name)) {
- if (sym.kind == TYP &&
- staticImportFilter.accepts(originMembers, sym) &&
- !chk.checkUniqueStaticImport(pos, env.toplevel, sym)) {
- if (maskedOut == null)
- maskedOut = Collections.newSetFromMap(new IdentityHashMap<Symbol, Boolean>());
- maskedOut.add(sym);
- }
- }
- ImportFilter importFilter = maskedOut != null ?
- new MaskedImportFilter(staticImportFilter, maskedOut) :
- staticImportFilter;
- toScope.importByName(tsym.members(), originMembers, name, importFilter);
- }
- }.importFrom(tsym);
- }
- //where:
- class MaskedImportFilter implements ImportFilter {
-
- private final ImportFilter delegate;
- private final Set<Symbol> maskedOut;
-
- public MaskedImportFilter(ImportFilter delegate, Set<Symbol> maskedOut) {
- this.delegate = delegate;
- this.maskedOut = maskedOut;
- }
-
- @Override
- public boolean accepts(Scope origin, Symbol sym) {
- return !maskedOut.contains(sym) && delegate.accepts(origin, sym);
- }
- }
- abstract class SymbolImporter {
- Set<Symbol> processed = new HashSet<>();
- void importFrom(TypeSymbol tsym) {
- if (tsym == null || !processed.add(tsym))
- return;
-
- // also import inherited names
- importFrom(types.supertype(tsym.type).tsym);
- for (Type t : types.interfaces(tsym.type))
- importFrom(t.tsym);
-
- doImport(tsym);
- }
- 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, final Symbol tsym, Env<AttrContext> env) {
- if (tsym.kind == TYP &&
- chk.checkUniqueImport(pos, env.toplevel, tsym))
- env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
}
/** Construct method type from method signature.
@@ -338,32 +150,6 @@
* Visitor methods for member enter
*********************************************************************/
- ImportFilter staticImportFilter;
- ImportFilter typeImportFilter = new ImportFilter() {
- @Override
- public boolean accepts(Scope origin, Symbol t) {
- return t.kind == 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;
@@ -390,122 +176,6 @@
memberEnter(l.head, env);
}
- /** Enter members for a class.
- */
- void finishClass(JCClassDecl tree, Env<AttrContext> env) {
- if ((tree.mods.flags & Flags.ENUM) != 0 &&
- (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
- addEnumMembers(tree, env);
- }
- memberEnter(tree.defs, env);
- }
-
- /** Add the implicit members for an enum type
- * to the symbol table.
- */
- private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
- JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
-
- // public static T[] values() { return ???; }
- JCMethodDecl values = make.
- MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
- names.values,
- valuesType,
- List.<JCTypeParameter>nil(),
- List.<JCVariableDecl>nil(),
- List.<JCExpression>nil(), // thrown
- null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
- null);
- memberEnter(values, env);
-
- // public static T valueOf(String name) { return ???; }
- JCMethodDecl valueOf = make.
- MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
- names.valueOf,
- make.Type(tree.sym.type),
- List.<JCTypeParameter>nil(),
- List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
- Flags.MANDATED),
- names.fromString("name"),
- make.Type(syms.stringType), null)),
- List.<JCExpression>nil(), // thrown
- null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
- null);
- memberEnter(valueOf, env);
- }
-
- public void visitTopLevel(JCCompilationUnit tree) {
- if (!tree.starImportScope.isEmpty()) {
- // we must have already processed this toplevel
- return;
- }
-
- DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
- Lint prevLint = chk.setLint(lint);
-
- try {
- // Import-on-demand java.lang.
- importAll(tree.pos, syms.enterPackage(names.java_lang), env);
-
- // Process the package def and all import clauses.
- memberEnter(tree.defs, env);
- } finally {
- chk.setLint(prevLint);
- deferredLintHandler.setPos(prevLintPos);
- }
- }
-
- public void visitPackageDef(JCPackageDecl tree) {
- // check that no class exists with same fully qualified name as
- // toplevel package
- if (checkClash && tree.pid != null) {
- Symbol p = env.toplevel.packge;
- while (p.owner != syms.rootPackage) {
- p.owner.complete(); // enter all class members of p
- if (syms.classes.get(p.getQualifiedName()) != null) {
- log.error(tree.pos,
- "pkg.clashes.with.class.of.same.name",
- p);
- }
- p = p.owner;
- }
- }
- // process package annotations
- annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null);
- }
-
- // process the non-static imports and the static imports of types.
- public void visitImport(JCImport tree) {
- dependencies.push(AttributionKind.IMPORT, tree);
- JCFieldAccess imp = (JCFieldAccess)tree.qualid;
- Name name = TreeInfo.name(imp);
-
- // Create a local environment pointing to this tree to disable
- // effects of other imports in Resolve.findGlobalType
- Env<AttrContext> localEnv = env.dup(tree);
-
- TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym;
- if (name == names.asterisk) {
- // Import on demand.
- chk.checkCanonical(imp.selected);
- if (tree.staticImport)
- importStaticAll(tree.pos, p, env);
- else
- importAll(tree.pos, p, env);
- } else {
- // Named type import.
- if (tree.staticImport) {
- importNamedStatic(tree.pos(), p, name, localEnv);
- chk.checkCanonical(imp.selected);
- } else {
- TypeSymbol c = attribImportType(imp, localEnv).tsym;
- chk.checkCanonical(imp);
- importNamed(tree.pos(), c, env);
- }
- }
- dependencies.pop();
- }
-
public void visitMethodDef(JCMethodDecl tree) {
WriteableScope enclScope = enter.enterScope(env);
MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
@@ -765,35 +435,6 @@
return iEnv;
}
-/* ********************************************************************
- * Type completion
- *********************************************************************/
-
- Type attribImportType(JCTree tree, Env<AttrContext> env) {
- Assert.check(completionEnabled);
- try {
- // To prevent deep recursion, suppress completion of some
- // types.
- completionEnabled = false;
- return attr.attribType(tree, env);
- } finally {
- completionEnabled = true;
- }
- }
-
- /**
- * Check if a list of annotations contains a reference to
- * java.lang.Deprecated.
- **/
- private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
- for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
- JCAnnotation a = al.head;
- if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
- return true;
- }
- return false;
- }
-
/** Queue processing of an attribute default value. */
void annotateDefaultValueLater(final JCExpression defaultValue,
final Env<AttrContext> localEnv,
@@ -839,534 +480,4 @@
localEnv);
}
-/* ********************************************************************
- * Source completer
- *********************************************************************/
-
- /** Complete entering a class.
- * @param sym The symbol of the class to be completed.
- */
- public void complete(Symbol sym) throws CompletionFailure {
- // Suppress some (recursive) MemberEnter invocations
- if (!completionEnabled) {
- // Re-install same completer for next time around and return.
- Assert.check((sym.flags() & Flags.COMPOUND) == 0);
- sym.completer = this;
- return;
- }
-
- try {
- annotate.enterStart();
-
- ClassSymbol c = (ClassSymbol)sym;
- ClassType ct = (ClassType)c.type;
- Env<AttrContext> env = typeEnvs.get(c);
- JCClassDecl tree = (JCClassDecl)env.tree;
- boolean wasFirst = isFirst;
- isFirst = false;
-
- JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
- DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
- try {
- dependencies.push(c);
-
- // Save class environment for later member enter (2) processing.
- halfcompleted.append(env);
-
- // Mark class as not yet attributed.
- c.flags_field |= UNATTRIBUTED;
-
- // If this is a toplevel-class, make sure any preceding import
- // clauses have been seen.
- if (c.owner.kind == PCK) {
- memberEnter(env.toplevel, env.enclosing(TOPLEVEL));
- todo.append(env);
- }
-
- if (c.owner.kind == TYP)
- c.owner.complete();
-
- // create an environment for evaluating the base clauses
- Env<AttrContext> baseEnv = baseEnv(tree, env);
-
- if (tree.extending != null)
- annotate.annotateTypeLater(tree.extending, baseEnv, sym, tree.pos());
- for (JCExpression impl : tree.implementing)
- annotate.annotateTypeLater(impl, baseEnv, sym, tree.pos());
- annotate.flush();
-
- // Determine supertype.
- Type supertype;
- if (tree.extending != null) {
- dependencies.push(AttributionKind.EXTENDS, tree.extending);
- try {
- supertype = attr.attribBase(tree.extending, baseEnv,
- true, false, true);
- } finally {
- dependencies.pop();
- }
- } else {
- supertype = ((tree.mods.flags & Flags.ENUM) != 0)
- ? attr.attribBase(enumBase(tree.pos, c), baseEnv,
- true, false, false)
- : (c.fullname == names.java_lang_Object)
- ? Type.noType
- : syms.objectType;
- }
- ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
-
- // Determine interfaces.
- ListBuffer<Type> interfaces = new ListBuffer<>();
- ListBuffer<Type> all_interfaces = null; // lazy init
- Set<Type> interfaceSet = new HashSet<>();
- List<JCExpression> interfaceTrees = tree.implementing;
- for (JCExpression iface : interfaceTrees) {
- dependencies.push(AttributionKind.IMPLEMENTS, iface);
- try {
- Type it = attr.attribBase(iface, baseEnv, false, true, true);
- if (it.hasTag(CLASS)) {
- interfaces.append(it);
- if (all_interfaces != null) all_interfaces.append(it);
- chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
- } else {
- if (all_interfaces == null)
- all_interfaces = new ListBuffer<Type>().appendList(interfaces);
- all_interfaces.append(modelMissingTypes(it, iface, true));
- }
- } finally {
- dependencies.pop();
- }
- }
-
- if ((c.flags_field & ANNOTATION) != 0) {
- ct.interfaces_field = List.of(syms.annotationType);
- ct.all_interfaces_field = ct.interfaces_field;
- } else {
- ct.interfaces_field = interfaces.toList();
- ct.all_interfaces_field = (all_interfaces == null)
- ? ct.interfaces_field : all_interfaces.toList();
- }
-
- if (c.fullname == names.java_lang_Object) {
- if (tree.extending != null) {
- chk.checkNonCyclic(tree.extending.pos(),
- supertype);
- ct.supertype_field = Type.noType;
- }
- else if (tree.implementing.nonEmpty()) {
- chk.checkNonCyclic(tree.implementing.head.pos(),
- ct.interfaces_field.head);
- ct.interfaces_field = List.nil();
- }
- }
-
- // Annotations.
- // In general, we cannot fully process annotations yet, but we
- // can attribute the annotation types and then check to see if the
- // @Deprecated annotation is present.
- attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
- if (hasDeprecatedAnnotation(tree.mods.annotations))
- c.flags_field |= DEPRECATED;
- annotate.annotateLater(tree.mods.annotations, baseEnv,
- c, tree.pos());
-
- chk.checkNonCyclicDecl(tree);
-
- // class type parameters use baseEnv but everything uses env
- attr.attribTypeVariables(tree.typarams, baseEnv);
- for (JCTypeParameter tp : tree.typarams)
- annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos());
-
- // Add default constructor if needed.
- if ((c.flags() & INTERFACE) == 0 &&
- !TreeInfo.hasConstructors(tree.defs)) {
- List<Type> argtypes = List.nil();
- List<Type> typarams = List.nil();
- List<Type> thrown = List.nil();
- long ctorFlags = 0;
- boolean based = false;
- boolean addConstructor = true;
- JCNewClass nc = null;
- if (c.name.isEmpty()) {
- nc = (JCNewClass)env.next.tree;
- if (nc.constructor != null) {
- addConstructor = nc.constructor.kind != ERR;
- Type superConstrType = types.memberType(c.type,
- nc.constructor);
- argtypes = superConstrType.getParameterTypes();
- typarams = superConstrType.getTypeArguments();
- ctorFlags = nc.constructor.flags() & VARARGS;
- if (nc.encl != null) {
- argtypes = argtypes.prepend(nc.encl.type);
- based = true;
- }
- thrown = superConstrType.getThrownTypes();
- }
- }
- if (addConstructor) {
- MethodSymbol basedConstructor = nc != null ?
- (MethodSymbol)nc.constructor : null;
- JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
- basedConstructor,
- typarams, argtypes, thrown,
- ctorFlags, based);
- tree.defs = tree.defs.prepend(constrDef);
- }
- }
-
- // enter symbols for 'this' into current scope.
- VarSymbol thisSym =
- new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
- thisSym.pos = Position.FIRSTPOS;
- env.info.scope.enter(thisSym);
- // if this is a class, enter symbol for 'super' into current scope.
- if ((c.flags_field & INTERFACE) == 0 &&
- ct.supertype_field.hasTag(CLASS)) {
- VarSymbol superSym =
- new VarSymbol(FINAL | HASINIT, names._super,
- ct.supertype_field, c);
- superSym.pos = Position.FIRSTPOS;
- env.info.scope.enter(superSym);
- }
-
- // check that no package exists with same fully qualified name,
- // but admit classes in the unnamed package which have the same
- // name as a top-level package.
- if (checkClash &&
- c.owner.kind == PCK && c.owner != syms.unnamedPackage &&
- syms.packageExists(c.fullname)) {
- log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), c);
- }
- if (c.owner.kind == PCK && (c.flags_field & PUBLIC) == 0 &&
- !env.toplevel.sourcefile.isNameCompatible(c.name.toString(),JavaFileObject.Kind.SOURCE)) {
- c.flags_field |= AUXILIARY;
- }
- } catch (CompletionFailure ex) {
- chk.completionError(tree.pos(), ex);
- } finally {
- deferredLintHandler.setPos(prevLintPos);
- log.useSource(prev);
- dependencies.pop();
- }
-
- // 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);
- if (allowTypeAnnos) {
- typeAnnotations.organizeTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
- typeAnnotations.validateTypeAnnotationsSignatures(toFinish, (JCClassDecl)toFinish.tree);
- }
- }
- } finally {
- isFirst = true;
- }
-
- for (JCCompilationUnit toplevel : topLevels) {
- chk.checkImportsResolvable(toplevel);
- }
-
- }
- } finally {
- annotate.enterDone();
- }
- }
-
- private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
- WriteableScope baseScope = WriteableScope.create(tree.sym);
- //import already entered local classes into base scope
- for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
- if (sym.isLocal()) {
- baseScope.enter(sym);
- }
- }
- //import current type-parameters into base scope
- if (tree.typarams != null)
- for (List<JCTypeParameter> typarams = tree.typarams;
- typarams.nonEmpty();
- typarams = typarams.tail)
- baseScope.enter(typarams.head.type.tsym);
- Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
- Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
- localEnv.baseClause = true;
- localEnv.outer = outer;
- localEnv.info.isSelfCall = false;
- return localEnv;
- }
-
- /** Enter member fields and methods of a class
- * @param env the environment current for the class block.
- */
- private void finish(Env<AttrContext> env) {
- JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
- try {
- JCClassDecl tree = (JCClassDecl)env.tree;
- finishClass(tree, env);
- } finally {
- log.useSource(prev);
- }
- }
-
- /** Generate a base clause for an enum type.
- * @param pos The position for trees and diagnostics, if any
- * @param c The class symbol of the enum
- */
- private JCExpression enumBase(int pos, ClassSymbol c) {
- JCExpression result = make.at(pos).
- TypeApply(make.QualIdent(syms.enumSym),
- List.<JCExpression>of(make.Type(c.type)));
- return result;
- }
-
- Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
- if (!t.hasTag(ERROR))
- return t;
-
- return new ErrorType(t.getOriginalType(), t.tsym) {
- private Type modelType;
-
- @Override
- public Type getModelType() {
- if (modelType == null)
- modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
- return modelType;
- }
- };
- }
- // where
- private class Synthesizer extends JCTree.Visitor {
- Type originalType;
- boolean interfaceExpected;
- List<ClassSymbol> synthesizedSymbols = List.nil();
- Type result;
-
- Synthesizer(Type originalType, boolean interfaceExpected) {
- this.originalType = originalType;
- this.interfaceExpected = interfaceExpected;
- }
-
- Type visit(JCTree tree) {
- tree.accept(this);
- return result;
- }
-
- List<Type> visit(List<? extends JCTree> trees) {
- ListBuffer<Type> lb = new ListBuffer<>();
- for (JCTree t: trees)
- lb.append(visit(t));
- return lb.toList();
- }
-
- @Override
- public void visitTree(JCTree tree) {
- result = syms.errType;
- }
-
- @Override
- public void visitIdent(JCIdent tree) {
- if (!tree.type.hasTag(ERROR)) {
- result = tree.type;
- } else {
- result = synthesizeClass(tree.name, syms.unnamedPackage).type;
- }
- }
-
- @Override
- public void visitSelect(JCFieldAccess tree) {
- if (!tree.type.hasTag(ERROR)) {
- result = tree.type;
- } else {
- Type selectedType;
- boolean prev = interfaceExpected;
- try {
- interfaceExpected = false;
- selectedType = visit(tree.selected);
- } finally {
- interfaceExpected = prev;
- }
- ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym);
- result = c.type;
- }
- }
-
- @Override
- public void visitTypeApply(JCTypeApply tree) {
- if (!tree.type.hasTag(ERROR)) {
- result = tree.type;
- } else {
- ClassType clazzType = (ClassType) visit(tree.clazz);
- if (synthesizedSymbols.contains(clazzType.tsym))
- synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size());
- final List<Type> actuals = visit(tree.arguments);
- result = new ErrorType(tree.type, clazzType.tsym) {
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public List<Type> getTypeArguments() {
- return actuals;
- }
- };
- }
- }
-
- ClassSymbol synthesizeClass(Name name, Symbol owner) {
- int flags = interfaceExpected ? INTERFACE : 0;
- ClassSymbol c = new ClassSymbol(flags, name, owner);
- c.members_field = new Scope.ErrorScope(c);
- c.type = new ErrorType(originalType, c) {
- @Override @DefinedBy(Api.LANGUAGE_MODEL)
- public List<Type> getTypeArguments() {
- return typarams_field;
- }
- };
- synthesizedSymbols = synthesizedSymbols.prepend(c);
- return c;
- }
-
- void synthesizeTyparams(ClassSymbol sym, int n) {
- ClassType ct = (ClassType) sym.type;
- Assert.check(ct.typarams_field.isEmpty());
- if (n == 1) {
- TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
- ct.typarams_field = ct.typarams_field.prepend(v);
- } else {
- for (int i = n; i > 0; i--) {
- TypeVar v = new TypeVar(names.fromString("T" + i), sym,
- syms.botType);
- ct.typarams_field = ct.typarams_field.prepend(v);
- }
- }
- }
- }
-
-
-/* ***************************************************************************
- * tree building
- ****************************************************************************/
-
- /** Generate default constructor for given class. For classes different
- * from java.lang.Object, this is:
- *
- * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
- * super(x_0, ..., x_n)
- * }
- *
- * or, if based == true:
- *
- * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
- * x_0.super(x_1, ..., x_n)
- * }
- *
- * @param make The tree factory.
- * @param c The class owning the default constructor.
- * @param argtypes The parameter types of the constructor.
- * @param thrown The thrown exceptions of the constructor.
- * @param based Is first parameter a this$n?
- */
- JCTree DefaultConstructor(TreeMaker make,
- ClassSymbol c,
- MethodSymbol baseInit,
- List<Type> typarams,
- List<Type> argtypes,
- List<Type> thrown,
- long flags,
- boolean based) {
- JCTree result;
- if ((c.flags() & ENUM) != 0 &&
- (types.supertype(c.type).tsym == syms.enumSym)) {
- // constructors of true enums are private
- flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
- } else
- flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
- if (c.name.isEmpty()) {
- flags |= ANONCONSTR;
- }
- Type mType = new MethodType(argtypes, null, thrown, c);
- Type initType = typarams.nonEmpty() ?
- new ForAll(typarams, mType) :
- mType;
- MethodSymbol init = new MethodSymbol(flags, names.init,
- initType, c);
- init.params = createDefaultConstructorParams(make, baseInit, init,
- argtypes, based);
- List<JCVariableDecl> params = make.Params(argtypes, init);
- List<JCStatement> stats = List.nil();
- if (c.type != syms.objectType) {
- stats = stats.prepend(SuperCall(make, typarams, params, based));
- }
- result = make.MethodDef(init, make.Block(0, stats));
- return result;
- }
-
- private List<VarSymbol> createDefaultConstructorParams(
- TreeMaker make,
- MethodSymbol baseInit,
- MethodSymbol init,
- List<Type> argtypes,
- boolean based) {
- List<VarSymbol> initParams = null;
- List<Type> argTypesList = argtypes;
- if (based) {
- /* In this case argtypes will have an extra type, compared to baseInit,
- * corresponding to the type of the enclosing instance i.e.:
- *
- * Inner i = outer.new Inner(1){}
- *
- * in the above example argtypes will be (Outer, int) and baseInit
- * will have parameter's types (int). So in this case we have to add
- * first the extra type in argtypes and then get the names of the
- * parameters from baseInit.
- */
- initParams = List.nil();
- VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
- initParams = initParams.append(param);
- argTypesList = argTypesList.tail;
- }
- if (baseInit != null && baseInit.params != null &&
- baseInit.params.nonEmpty() && argTypesList.nonEmpty()) {
- initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
- List<VarSymbol> baseInitParams = baseInit.params;
- while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
- VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
- baseInitParams.head.name, argTypesList.head, init);
- initParams = initParams.append(param);
- baseInitParams = baseInitParams.tail;
- argTypesList = argTypesList.tail;
- }
- }
- return initParams;
- }
-
- /** Generate call to superclass constructor. This is:
- *
- * super(id_0, ..., id_n)
- *
- * or, if based == true
- *
- * id_0.super(id_1,...,id_n)
- *
- * where id_0, ..., id_n are the names of the given parameters.
- *
- * @param make The tree factory
- * @param params The parameters that need to be passed to super
- * @param typarams The type parameters that need to be passed to super
- * @param based Is first parameter a this$n?
- */
- JCExpressionStatement SuperCall(TreeMaker make,
- List<Type> typarams,
- List<JCVariableDecl> params,
- boolean based) {
- JCExpression meth;
- if (based) {
- meth = make.Select(make.Ident(params.head), names._super);
- params = params.tail;
- } else {
- meth = make.Ident(names._super);
- }
- List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
- return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
- }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Dec 04 15:22:53 2014 -0800
@@ -3172,7 +3172,7 @@
super(referenceTree, name, site, argtypes.tail, typeargtypes, maxPhase);
if (site.isRaw() && !argtypes.head.hasTag(NONE)) {
Type asSuperSite = types.asSuper(argtypes.head, site.tsym);
- this.site = asSuperSite;
+ this.site = types.capture(asSuperSite);
}
}
@@ -4039,7 +4039,7 @@
s : new MethodSymbol(
s.flags(),
s.name,
- types.createMethodTypeWithThrown(mt, allThrown),
+ types.createMethodTypeWithThrown(s.type, allThrown),
s.owner);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,1070 @@
+/*
+ * 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package com.sun.tools.javac.comp;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.tools.JavaFileObject;
+
+import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Lint.LintCategory;
+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.tree.*;
+import com.sun.tools.javac.util.*;
+import com.sun.tools.javac.util.DefinedBy.Api;
+
+import com.sun.tools.javac.code.Symbol.*;
+import com.sun.tools.javac.code.Type.*;
+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.Scope.LookupKind.NON_RECURSIVE;
+import static com.sun.tools.javac.code.Kinds.Kind.*;
+import static com.sun.tools.javac.code.TypeTag.CLASS;
+import static com.sun.tools.javac.code.TypeTag.ERROR;
+import static com.sun.tools.javac.tree.JCTree.Tag.*;
+
+import com.sun.tools.javac.util.Dependencies.AttributionKind;
+import com.sun.tools.javac.util.Dependencies.CompletionCause;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
+import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
+
+/** This is the second phase of Enter, in which classes are completed
+ * by resolving their headers and entering their members in the into
+ * the class scope. See Enter for an overall overview.
+ *
+ * This class uses internal phases to process the classes. When a phase
+ * processes classes, the lower phases are not invoked until all classes
+ * pass through the current phase. Note that it is possible that upper phases
+ * are run due to recursive completion. The internal phases are:
+ * - ImportPhase: shallow pass through imports, adds information about imports
+ * the NamedImportScope and StarImportScope, but avoids queries
+ * about class hierarchy.
+ * - HierarchyPhase: resolves the supertypes of the given class. Does not handle
+ * type parameters of the class or type argument of the supertypes.
+ * - HeaderPhase: finishes analysis of the header of the given class by resolving
+ * type parameters, attributing supertypes including type arguments
+ * and scheduling full annotation attribution. This phase also adds
+ * a synthetic default constructor if needed and synthetic "this" field.
+ * - MembersPhase: resolves headers for fields, methods and constructors in the given class.
+ * Also generates synthetic enum members.
+ *
+ * <p><b>This is NOT part of any supported API.
+ * If you write code that depends on this, you do so at your own risk.
+ * This code and its internal interfaces are subject to change or
+ * deletion without notice.</b>
+ */
+public class TypeEnter implements Completer {
+ protected static final Context.Key<TypeEnter> typeEnterKey = new Context.Key<>();
+
+ /** A switch to determine whether we check for package/class conflicts
+ */
+ final static boolean checkClash = true;
+
+ private final Names names;
+ private final Enter enter;
+ private final MemberEnter memberEnter;
+ private final Log log;
+ private final Check chk;
+ private final Attr attr;
+ private final Symtab syms;
+ private final TreeMaker make;
+ private final Todo todo;
+ private final Annotate annotate;
+ private final TypeAnnotations typeAnnotations;
+ private final Types types;
+ private final JCDiagnostic.Factory diags;
+ private final Source source;
+ private final DeferredLintHandler deferredLintHandler;
+ private final Lint lint;
+ private final TypeEnvs typeEnvs;
+ private final Dependencies dependencies;
+
+ public static TypeEnter instance(Context context) {
+ TypeEnter instance = context.get(typeEnterKey);
+ if (instance == null)
+ instance = new TypeEnter(context);
+ return instance;
+ }
+
+ protected TypeEnter(Context context) {
+ context.put(typeEnterKey, this);
+ names = Names.instance(context);
+ enter = Enter.instance(context);
+ memberEnter = MemberEnter.instance(context);
+ log = Log.instance(context);
+ chk = Check.instance(context);
+ attr = Attr.instance(context);
+ syms = Symtab.instance(context);
+ make = TreeMaker.instance(context);
+ todo = Todo.instance(context);
+ annotate = Annotate.instance(context);
+ typeAnnotations = TypeAnnotations.instance(context);
+ types = Types.instance(context);
+ diags = JCDiagnostic.Factory.instance(context);
+ source = Source.instance(context);
+ deferredLintHandler = DeferredLintHandler.instance(context);
+ lint = Lint.instance(context);
+ typeEnvs = TypeEnvs.instance(context);
+ dependencies = Dependencies.instance(context);
+ allowTypeAnnos = source.allowTypeAnnotations();
+ allowDeprecationOnImport = source.allowDeprecationOnImport();
+ }
+
+ /** Switch: support type annotations.
+ */
+ boolean allowTypeAnnos;
+
+ /**
+ * Switch: should deprecation warnings be issued on import
+ */
+ boolean allowDeprecationOnImport;
+
+ /** A flag to disable completion from time to time during member
+ * enter, as we only need to look up types. This avoids
+ * unnecessarily deep recursion.
+ */
+ boolean completionEnabled = true;
+
+ /* Verify Imports:
+ */
+ protected void ensureImportsChecked(List<JCCompilationUnit> trees) {
+ // 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.isEmpty()) {
+ Env<AttrContext> topEnv = enter.topLevelEnv(tree);
+ finishImports(tree, () -> { completeClass.resolveImports(tree, topEnv); });
+ }
+ }
+ }
+
+/* ********************************************************************
+ * Source completer
+ *********************************************************************/
+
+ /** Complete entering a class.
+ * @param sym The symbol of the class to be completed.
+ */
+ public void complete(Symbol sym) throws CompletionFailure {
+ // Suppress some (recursive) MemberEnter invocations
+ if (!completionEnabled) {
+ // Re-install same completer for next time around and return.
+ Assert.check((sym.flags() & Flags.COMPOUND) == 0);
+ sym.completer = this;
+ return;
+ }
+
+ try {
+ annotate.enterStart();
+ sym.flags_field |= UNATTRIBUTED;
+
+ List<Env<AttrContext>> queue;
+
+ dependencies.push((ClassSymbol) sym, CompletionCause.MEMBER_ENTER);
+ try {
+ queue = completeClass.runPhase(List.of(typeEnvs.get((ClassSymbol) sym)));
+ } finally {
+ dependencies.pop();
+ }
+
+ if (!queue.isEmpty()) {
+ Set<JCCompilationUnit> seen = new HashSet<>();
+
+ for (Env<AttrContext> env : queue) {
+ if (env.toplevel.defs.contains(env.enclClass) && seen.add(env.toplevel)) {
+ finishImports(env.toplevel, () -> {});
+ }
+ }
+ }
+ } finally {
+ annotate.enterDone();
+ }
+ }
+
+ void finishImports(JCCompilationUnit toplevel, Runnable resolve) {
+ JavaFileObject prev = log.useSource(toplevel.sourcefile);
+ try {
+ resolve.run();
+ chk.checkImportsUnique(toplevel);
+ chk.checkImportsResolvable(toplevel);
+ toplevel.namedImportScope.finalizeScope();
+ toplevel.starImportScope.finalizeScope();
+ } finally {
+ log.useSource(prev);
+ }
+ }
+
+ abstract class Phase {
+ private final ListBuffer<Env<AttrContext>> queue = new ListBuffer<>();
+ private final Phase next;
+ private final CompletionCause phaseName;
+
+ Phase(CompletionCause phaseName, Phase next) {
+ this.phaseName = phaseName;
+ this.next = next;
+ }
+
+ public List<Env<AttrContext>> runPhase(List<Env<AttrContext>> envs) {
+ boolean firstToComplete = queue.isEmpty();
+
+ for (Env<AttrContext> env : envs) {
+ JCClassDecl tree = (JCClassDecl)env.tree;
+
+ queue.add(env);
+
+ JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+ DiagnosticPosition prevLintPos = deferredLintHandler.setPos(tree.pos());
+ try {
+ dependencies.push(env.enclClass.sym, phaseName);
+ doRunPhase(env);
+ } catch (CompletionFailure ex) {
+ chk.completionError(tree.pos(), ex);
+ } finally {
+ dependencies.pop();
+ deferredLintHandler.setPos(prevLintPos);
+ log.useSource(prev);
+ }
+ }
+
+ if (firstToComplete) {
+ List<Env<AttrContext>> out = queue.toList();
+
+ queue.clear();
+ return next != null ? next.runPhase(out) : out;
+ } else {
+ return List.nil();
+ }
+ }
+
+ protected abstract void doRunPhase(Env<AttrContext> env);
+ }
+
+ private final ImportsPhase completeClass = new ImportsPhase();
+
+ /**Analyze import clauses.
+ */
+ private final class ImportsPhase extends Phase {
+
+ public ImportsPhase() {
+ super(CompletionCause.IMPORTS_PHASE, new HierarchyPhase());
+ }
+
+ Env<AttrContext> env;
+ ImportFilter staticImportFilter;
+ ImportFilter typeImportFilter = new ImportFilter() {
+ @Override
+ public boolean accepts(Scope origin, Symbol t) {
+ return t.kind == TYP;
+ }
+ };
+
+ @Override
+ protected void doRunPhase(Env<AttrContext> env) {
+ JCClassDecl tree = env.enclClass;
+ ClassSymbol sym = tree.sym;
+
+ // If sym is a toplevel-class, make sure any import
+ // clauses in its source file have been seen.
+ if (sym.owner.kind == PCK) {
+ resolveImports(env.toplevel, env.enclosing(TOPLEVEL));
+ todo.append(env);
+ }
+
+ if (sym.owner.kind == TYP)
+ sym.owner.complete();
+ }
+
+ private void resolveImports(JCCompilationUnit tree, Env<AttrContext> env) {
+ if (!tree.starImportScope.isEmpty()) {
+ // we must have already processed this toplevel
+ return;
+ }
+
+ ImportFilter prevStaticImportFilter = staticImportFilter;
+ DiagnosticPosition prevLintPos = deferredLintHandler.immediate();
+ Lint prevLint = chk.setLint(lint);
+ Env<AttrContext> prevEnv = this.env;
+ try {
+ this.env = env;
+ 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);
+ }
+ };
+
+ // Import-on-demand java.lang.
+ importAll(tree.pos, syms.enterPackage(names.java_lang), env);
+
+ // Process the package def and all import clauses.
+ if (tree.getPackage() != null)
+ checkClassPackageClash(tree.getPackage());
+
+ for (JCImport imp : tree.getImports()) {
+ doImport(imp);
+ }
+ } finally {
+ this.env = prevEnv;
+ chk.setLint(prevLint);
+ deferredLintHandler.setPos(prevLintPos);
+ this.staticImportFilter = prevStaticImportFilter;
+ }
+ }
+
+ private void checkClassPackageClash(JCPackageDecl tree) {
+ // check that no class exists with same fully qualified name as
+ // toplevel package
+ if (checkClash && tree.pid != null) {
+ Symbol p = env.toplevel.packge;
+ while (p.owner != syms.rootPackage) {
+ p.owner.complete(); // enter all class members of p
+ if (syms.classes.get(p.getQualifiedName()) != null) {
+ log.error(tree.pos,
+ "pkg.clashes.with.class.of.same.name",
+ p);
+ }
+ p = p.owner;
+ }
+ }
+ // process package annotations
+ annotate.annotateLater(tree.annotations, env, env.toplevel.packge, null);
+ }
+
+ private void doImport(JCImport tree) {
+ dependencies.push(AttributionKind.IMPORT, tree);
+ JCFieldAccess imp = (JCFieldAccess)tree.qualid;
+ Name name = TreeInfo.name(imp);
+
+ // Create a local environment pointing to this tree to disable
+ // effects of other imports in Resolve.findGlobalType
+ Env<AttrContext> localEnv = env.dup(tree);
+
+ TypeSymbol p = attr.attribImportQualifier(tree, localEnv).tsym;
+ if (name == names.asterisk) {
+ // Import on demand.
+ chk.checkCanonical(imp.selected);
+ if (tree.staticImport)
+ importStaticAll(tree.pos, p, env);
+ else
+ importAll(tree.pos, p, env);
+ } else {
+ // Named type import.
+ if (tree.staticImport) {
+ importNamedStatic(tree.pos(), p, name, localEnv, tree);
+ chk.checkCanonical(imp.selected);
+ } else {
+ TypeSymbol c = attribImportType(imp, localEnv).tsym;
+ chk.checkCanonical(imp);
+ importNamed(tree.pos(), c, env, tree);
+ }
+ }
+ dependencies.pop();
+ }
+
+ Type attribImportType(JCTree tree, Env<AttrContext> env) {
+ Assert.check(completionEnabled);
+ Lint prevLint = chk.setLint(allowDeprecationOnImport ?
+ lint : lint.suppress(LintCategory.DEPRECATION));
+ try {
+ // To prevent deep recursion, suppress completion of some
+ // types.
+ completionEnabled = false;
+ return attr.attribType(tree, env);
+ } finally {
+ completionEnabled = true;
+ chk.setLint(prevLint);
+ }
+ }
+
+ /** Import all classes of a class or package on demand.
+ * @param pos Position to be used for error reporting.
+ * @param tsym The class or package the members of which are imported.
+ * @param env The env in which the imported classes will be entered.
+ */
+ private void importAll(int pos,
+ final TypeSymbol tsym,
+ Env<AttrContext> env) {
+ // Check that packages imported from exist (JLS ???).
+ 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");
+ throw new FatalError(msg);
+ } else {
+ log.error(DiagnosticFlag.RESOLVE_ERROR, pos, "doesnt.exist", tsym);
+ }
+ }
+ env.toplevel.starImportScope.importAll(types, tsym.members(), typeImportFilter, false);
+ }
+
+ /** Import all static members of a class or package on demand.
+ * @param pos Position to be used for error reporting.
+ * @param tsym The class or package the members of which are imported.
+ * @param env The env in which the imported classes will be entered.
+ */
+ private void importStaticAll(int pos,
+ final TypeSymbol tsym,
+ Env<AttrContext> env) {
+ final StarImportScope toScope = env.toplevel.starImportScope;
+ final TypeSymbol origin = tsym;
+
+ toScope.importAll(types, origin.members(), staticImportFilter, true);
+ }
+
+ /** Import statics types of a given name. Non-types are handled in Attr.
+ * @param pos Position to be used for error reporting.
+ * @param tsym The class from which the name is imported.
+ * @param name The (simple) name being imported.
+ * @param env The environment containing the named import
+ * scope to add to.
+ */
+ private void importNamedStatic(final DiagnosticPosition pos,
+ final TypeSymbol tsym,
+ final Name name,
+ final Env<AttrContext> env,
+ final JCImport imp) {
+ if (tsym.kind != TYP) {
+ log.error(DiagnosticFlag.RECOVERABLE, pos, "static.imp.only.classes.and.interfaces");
+ return;
+ }
+
+ final NamedImportScope toScope = env.toplevel.namedImportScope;
+ final Scope originMembers = tsym.members();
+
+ imp.importScope = toScope.importByName(types, originMembers, name, staticImportFilter);
+ }
+
+ /** 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, final Symbol tsym, Env<AttrContext> env, JCImport imp) {
+ if (tsym.kind == TYP)
+ imp.importScope = env.toplevel.namedImportScope.importType(tsym.owner.members(), tsym.owner.members(), tsym);
+ }
+
+ }
+
+ /**Defines common utility methods used by the HierarchyPhase and HeaderPhase.
+ */
+ private abstract class AbstractHeaderPhase extends Phase {
+
+ public AbstractHeaderPhase(CompletionCause phaseName, Phase next) {
+ super(phaseName, next);
+ }
+
+ protected Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
+ WriteableScope baseScope = WriteableScope.create(tree.sym);
+ //import already entered local classes into base scope
+ for (Symbol sym : env.outer.info.scope.getSymbols(NON_RECURSIVE)) {
+ if (sym.isLocal()) {
+ baseScope.enter(sym);
+ }
+ }
+ //import current type-parameters into base scope
+ if (tree.typarams != null)
+ for (List<JCTypeParameter> typarams = tree.typarams;
+ typarams.nonEmpty();
+ typarams = typarams.tail)
+ baseScope.enter(typarams.head.type.tsym);
+ Env<AttrContext> outer = env.outer; // the base clause can't see members of this class
+ Env<AttrContext> localEnv = outer.dup(tree, outer.info.dup(baseScope));
+ localEnv.baseClause = true;
+ localEnv.outer = outer;
+ localEnv.info.isSelfCall = false;
+ return localEnv;
+ }
+
+ /** Generate a base clause for an enum type.
+ * @param pos The position for trees and diagnostics, if any
+ * @param c The class symbol of the enum
+ */
+ protected JCExpression enumBase(int pos, ClassSymbol c) {
+ JCExpression result = make.at(pos).
+ TypeApply(make.QualIdent(syms.enumSym),
+ List.<JCExpression>of(make.Type(c.type)));
+ return result;
+ }
+
+ protected Type modelMissingTypes(Type t, final JCExpression tree, final boolean interfaceExpected) {
+ if (!t.hasTag(ERROR))
+ return t;
+
+ return new ErrorType(t.getOriginalType(), t.tsym) {
+ private Type modelType;
+
+ @Override
+ public Type getModelType() {
+ if (modelType == null)
+ modelType = new Synthesizer(getOriginalType(), interfaceExpected).visit(tree);
+ return modelType;
+ }
+ };
+ }
+ // where:
+ private class Synthesizer extends JCTree.Visitor {
+ Type originalType;
+ boolean interfaceExpected;
+ List<ClassSymbol> synthesizedSymbols = List.nil();
+ Type result;
+
+ Synthesizer(Type originalType, boolean interfaceExpected) {
+ this.originalType = originalType;
+ this.interfaceExpected = interfaceExpected;
+ }
+
+ Type visit(JCTree tree) {
+ tree.accept(this);
+ return result;
+ }
+
+ List<Type> visit(List<? extends JCTree> trees) {
+ ListBuffer<Type> lb = new ListBuffer<>();
+ for (JCTree t: trees)
+ lb.append(visit(t));
+ return lb.toList();
+ }
+
+ @Override
+ public void visitTree(JCTree tree) {
+ result = syms.errType;
+ }
+
+ @Override
+ public void visitIdent(JCIdent tree) {
+ if (!tree.type.hasTag(ERROR)) {
+ result = tree.type;
+ } else {
+ result = synthesizeClass(tree.name, syms.unnamedPackage).type;
+ }
+ }
+
+ @Override
+ public void visitSelect(JCFieldAccess tree) {
+ if (!tree.type.hasTag(ERROR)) {
+ result = tree.type;
+ } else {
+ Type selectedType;
+ boolean prev = interfaceExpected;
+ try {
+ interfaceExpected = false;
+ selectedType = visit(tree.selected);
+ } finally {
+ interfaceExpected = prev;
+ }
+ ClassSymbol c = synthesizeClass(tree.name, selectedType.tsym);
+ result = c.type;
+ }
+ }
+
+ @Override
+ public void visitTypeApply(JCTypeApply tree) {
+ if (!tree.type.hasTag(ERROR)) {
+ result = tree.type;
+ } else {
+ ClassType clazzType = (ClassType) visit(tree.clazz);
+ if (synthesizedSymbols.contains(clazzType.tsym))
+ synthesizeTyparams((ClassSymbol) clazzType.tsym, tree.arguments.size());
+ final List<Type> actuals = visit(tree.arguments);
+ result = new ErrorType(tree.type, clazzType.tsym) {
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public List<Type> getTypeArguments() {
+ return actuals;
+ }
+ };
+ }
+ }
+
+ ClassSymbol synthesizeClass(Name name, Symbol owner) {
+ int flags = interfaceExpected ? INTERFACE : 0;
+ ClassSymbol c = new ClassSymbol(flags, name, owner);
+ c.members_field = new Scope.ErrorScope(c);
+ c.type = new ErrorType(originalType, c) {
+ @Override @DefinedBy(Api.LANGUAGE_MODEL)
+ public List<Type> getTypeArguments() {
+ return typarams_field;
+ }
+ };
+ synthesizedSymbols = synthesizedSymbols.prepend(c);
+ return c;
+ }
+
+ void synthesizeTyparams(ClassSymbol sym, int n) {
+ ClassType ct = (ClassType) sym.type;
+ Assert.check(ct.typarams_field.isEmpty());
+ if (n == 1) {
+ TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
+ ct.typarams_field = ct.typarams_field.prepend(v);
+ } else {
+ for (int i = n; i > 0; i--) {
+ TypeVar v = new TypeVar(names.fromString("T" + i), sym,
+ syms.botType);
+ ct.typarams_field = ct.typarams_field.prepend(v);
+ }
+ }
+ }
+ }
+
+ protected void attribSuperTypes(Env<AttrContext> env, Env<AttrContext> baseEnv) {
+ JCClassDecl tree = env.enclClass;
+ ClassSymbol sym = tree.sym;
+ ClassType ct = (ClassType)sym.type;
+ // Determine supertype.
+ Type supertype;
+ JCExpression extending;
+
+ if (tree.extending != null) {
+ extending = clearTypeParams(tree.extending);
+ dependencies.push(AttributionKind.EXTENDS, tree.extending);
+ try {
+ supertype = attr.attribBase(extending, baseEnv,
+ true, false, true);
+ } finally {
+ dependencies.pop();
+ }
+ } else {
+ extending = null;
+ supertype = ((tree.mods.flags & Flags.ENUM) != 0)
+ ? attr.attribBase(enumBase(tree.pos, sym), baseEnv,
+ true, false, false)
+ : (sym.fullname == names.java_lang_Object)
+ ? Type.noType
+ : syms.objectType;
+ }
+ ct.supertype_field = modelMissingTypes(supertype, extending, false);
+
+ // Determine interfaces.
+ ListBuffer<Type> interfaces = new ListBuffer<>();
+ ListBuffer<Type> all_interfaces = null; // lazy init
+ List<JCExpression> interfaceTrees = tree.implementing;
+ for (JCExpression iface : interfaceTrees) {
+ iface = clearTypeParams(iface);
+ dependencies.push(AttributionKind.IMPLEMENTS, iface);
+ try {
+ Type it = attr.attribBase(iface, baseEnv, false, true, true);
+ if (it.hasTag(CLASS)) {
+ interfaces.append(it);
+ if (all_interfaces != null) all_interfaces.append(it);
+ } else {
+ if (all_interfaces == null)
+ all_interfaces = new ListBuffer<Type>().appendList(interfaces);
+ all_interfaces.append(modelMissingTypes(it, iface, true));
+
+ }
+ } finally {
+ dependencies.pop();
+ }
+ }
+
+ if ((sym.flags_field & ANNOTATION) != 0) {
+ ct.interfaces_field = List.of(syms.annotationType);
+ ct.all_interfaces_field = ct.interfaces_field;
+ } else {
+ ct.interfaces_field = interfaces.toList();
+ ct.all_interfaces_field = (all_interfaces == null)
+ ? ct.interfaces_field : all_interfaces.toList();
+ }
+ }
+ //where:
+ protected JCExpression clearTypeParams(JCExpression superType) {
+ return superType;
+ }
+ }
+
+ private final class HierarchyPhase extends AbstractHeaderPhase {
+
+ public HierarchyPhase() {
+ super(CompletionCause.HIERARCHY_PHASE, new HeaderPhase());
+ }
+
+ @Override
+ protected void doRunPhase(Env<AttrContext> env) {
+ JCClassDecl tree = env.enclClass;
+ ClassSymbol sym = tree.sym;
+ ClassType ct = (ClassType)sym.type;
+
+ Env<AttrContext> baseEnv = baseEnv(tree, env);
+
+ attribSuperTypes(env, baseEnv);
+
+ if (sym.fullname == names.java_lang_Object) {
+ if (tree.extending != null) {
+ chk.checkNonCyclic(tree.extending.pos(),
+ ct.supertype_field);
+ ct.supertype_field = Type.noType;
+ }
+ else if (tree.implementing.nonEmpty()) {
+ chk.checkNonCyclic(tree.implementing.head.pos(),
+ ct.interfaces_field.head);
+ ct.interfaces_field = List.nil();
+ }
+ }
+
+ // Annotations.
+ // In general, we cannot fully process annotations yet, but we
+ // can attribute the annotation types and then check to see if the
+ // @Deprecated annotation is present.
+ attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
+ if (hasDeprecatedAnnotation(tree.mods.annotations))
+ sym.flags_field |= DEPRECATED;
+
+ chk.checkNonCyclicDecl(tree);
+ }
+ //where:
+ protected JCExpression clearTypeParams(JCExpression superType) {
+ switch (superType.getTag()) {
+ case TYPEAPPLY:
+ return ((JCTypeApply) superType).clazz;
+ }
+
+ return superType;
+ }
+
+ /**
+ * Check if a list of annotations contains a reference to
+ * java.lang.Deprecated.
+ **/
+ private boolean hasDeprecatedAnnotation(List<JCAnnotation> annotations) {
+ for (List<JCAnnotation> al = annotations; !al.isEmpty(); al = al.tail) {
+ JCAnnotation a = al.head;
+ if (a.annotationType.type == syms.deprecatedType && a.args.isEmpty())
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private final class HeaderPhase extends AbstractHeaderPhase {
+
+ public HeaderPhase() {
+ super(CompletionCause.HEADER_PHASE, new MembersPhase());
+ }
+
+ @Override
+ protected void doRunPhase(Env<AttrContext> env) {
+ JCClassDecl tree = env.enclClass;
+ ClassSymbol sym = tree.sym;
+ ClassType ct = (ClassType)sym.type;
+
+ // create an environment for evaluating the base clauses
+ Env<AttrContext> baseEnv = baseEnv(tree, env);
+
+ if (tree.extending != null)
+ annotate.annotateTypeLater(tree.extending, baseEnv, sym, tree.pos());
+ for (JCExpression impl : tree.implementing)
+ annotate.annotateTypeLater(impl, baseEnv, sym, tree.pos());
+ annotate.flush();
+
+ attribSuperTypes(env, baseEnv);
+
+ Set<Type> interfaceSet = new HashSet<>();
+
+ for (JCExpression iface : tree.implementing) {
+ Type it = iface.type;
+ if (it.hasTag(CLASS))
+ chk.checkNotRepeated(iface.pos(), types.erasure(it), interfaceSet);
+ }
+
+ annotate.annotateLater(tree.mods.annotations, baseEnv,
+ sym, tree.pos());
+
+ attr.attribTypeVariables(tree.typarams, baseEnv);
+ for (JCTypeParameter tp : tree.typarams)
+ annotate.annotateTypeLater(tp, baseEnv, sym, tree.pos());
+
+ // check that no package exists with same fully qualified name,
+ // but admit classes in the unnamed package which have the same
+ // name as a top-level package.
+ if (checkClash &&
+ sym.owner.kind == PCK && sym.owner != syms.unnamedPackage &&
+ syms.packageExists(sym.fullname)) {
+ log.error(tree.pos, "clash.with.pkg.of.same.name", Kinds.kindName(sym), sym);
+ }
+ if (sym.owner.kind == PCK && (sym.flags_field & PUBLIC) == 0 &&
+ !env.toplevel.sourcefile.isNameCompatible(sym.name.toString(),JavaFileObject.Kind.SOURCE)) {
+ sym.flags_field |= AUXILIARY;
+ }
+ }
+ }
+
+ /** Enter member fields and methods of a class
+ */
+ private final class MembersPhase extends Phase {
+
+ public MembersPhase() {
+ super(CompletionCause.MEMBERS_PHASE, null);
+ }
+
+ @Override
+ protected void doRunPhase(Env<AttrContext> env) {
+ JCClassDecl tree = env.enclClass;
+ ClassSymbol sym = tree.sym;
+ ClassType ct = (ClassType)sym.type;
+
+ // Add default constructor if needed.
+ if ((sym.flags() & INTERFACE) == 0 &&
+ !TreeInfo.hasConstructors(tree.defs)) {
+ List<Type> argtypes = List.nil();
+ List<Type> typarams = List.nil();
+ List<Type> thrown = List.nil();
+ long ctorFlags = 0;
+ boolean based = false;
+ boolean addConstructor = true;
+ JCNewClass nc = null;
+ if (sym.name.isEmpty()) {
+ nc = (JCNewClass)env.next.tree;
+ if (nc.constructor != null) {
+ addConstructor = nc.constructor.kind != ERR;
+ Type superConstrType = types.memberType(sym.type,
+ nc.constructor);
+ argtypes = superConstrType.getParameterTypes();
+ typarams = superConstrType.getTypeArguments();
+ ctorFlags = nc.constructor.flags() & VARARGS;
+ if (nc.encl != null) {
+ argtypes = argtypes.prepend(nc.encl.type);
+ based = true;
+ }
+ thrown = superConstrType.getThrownTypes();
+ }
+ }
+ if (addConstructor) {
+ MethodSymbol basedConstructor = nc != null ?
+ (MethodSymbol)nc.constructor : null;
+ JCTree constrDef = DefaultConstructor(make.at(tree.pos), sym,
+ basedConstructor,
+ typarams, argtypes, thrown,
+ ctorFlags, based);
+ tree.defs = tree.defs.prepend(constrDef);
+ }
+ }
+
+ // enter symbols for 'this' into current scope.
+ VarSymbol thisSym =
+ new VarSymbol(FINAL | HASINIT, names._this, sym.type, sym);
+ thisSym.pos = Position.FIRSTPOS;
+ env.info.scope.enter(thisSym);
+ // if this is a class, enter symbol for 'super' into current scope.
+ if ((sym.flags_field & INTERFACE) == 0 &&
+ ct.supertype_field.hasTag(CLASS)) {
+ VarSymbol superSym =
+ new VarSymbol(FINAL | HASINIT, names._super,
+ ct.supertype_field, sym);
+ superSym.pos = Position.FIRSTPOS;
+ env.info.scope.enter(superSym);
+ }
+
+ finishClass(tree, env);
+
+ if (allowTypeAnnos) {
+ typeAnnotations.organizeTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
+ typeAnnotations.validateTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
+ }
+ }
+
+ /** Enter members for a class.
+ */
+ void finishClass(JCClassDecl tree, Env<AttrContext> env) {
+ if ((tree.mods.flags & Flags.ENUM) != 0 &&
+ (types.supertype(tree.sym.type).tsym.flags() & Flags.ENUM) == 0) {
+ addEnumMembers(tree, env);
+ }
+ memberEnter.memberEnter(tree.defs, env);
+ }
+
+ /** Add the implicit members for an enum type
+ * to the symbol table.
+ */
+ private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
+ JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
+
+ // public static T[] values() { return ???; }
+ JCMethodDecl values = make.
+ MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
+ names.values,
+ valuesType,
+ List.<JCTypeParameter>nil(),
+ List.<JCVariableDecl>nil(),
+ List.<JCExpression>nil(), // thrown
+ null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
+ null);
+ memberEnter.memberEnter(values, env);
+
+ // public static T valueOf(String name) { return ???; }
+ JCMethodDecl valueOf = make.
+ MethodDef(make.Modifiers(Flags.PUBLIC|Flags.STATIC),
+ names.valueOf,
+ make.Type(tree.sym.type),
+ List.<JCTypeParameter>nil(),
+ List.of(make.VarDef(make.Modifiers(Flags.PARAMETER |
+ Flags.MANDATED),
+ names.fromString("name"),
+ make.Type(syms.stringType), null)),
+ List.<JCExpression>nil(), // thrown
+ null, //make.Block(0, Tree.emptyList.prepend(make.Return(make.Ident(names._null)))),
+ null);
+ memberEnter.memberEnter(valueOf, env);
+ }
+
+ }
+
+/* ***************************************************************************
+ * tree building
+ ****************************************************************************/
+
+ /** Generate default constructor for given class. For classes different
+ * from java.lang.Object, this is:
+ *
+ * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
+ * super(x_0, ..., x_n)
+ * }
+ *
+ * or, if based == true:
+ *
+ * c(argtype_0 x_0, ..., argtype_n x_n) throws thrown {
+ * x_0.super(x_1, ..., x_n)
+ * }
+ *
+ * @param make The tree factory.
+ * @param c The class owning the default constructor.
+ * @param argtypes The parameter types of the constructor.
+ * @param thrown The thrown exceptions of the constructor.
+ * @param based Is first parameter a this$n?
+ */
+ JCTree DefaultConstructor(TreeMaker make,
+ ClassSymbol c,
+ MethodSymbol baseInit,
+ List<Type> typarams,
+ List<Type> argtypes,
+ List<Type> thrown,
+ long flags,
+ boolean based) {
+ JCTree result;
+ if ((c.flags() & ENUM) != 0 &&
+ (types.supertype(c.type).tsym == syms.enumSym)) {
+ // constructors of true enums are private
+ flags = (flags & ~AccessFlags) | PRIVATE | GENERATEDCONSTR;
+ } else
+ flags |= (c.flags() & AccessFlags) | GENERATEDCONSTR;
+ if (c.name.isEmpty()) {
+ flags |= ANONCONSTR;
+ }
+ Type mType = new MethodType(argtypes, null, thrown, c);
+ Type initType = typarams.nonEmpty() ?
+ new ForAll(typarams, mType) :
+ mType;
+ MethodSymbol init = new MethodSymbol(flags, names.init,
+ initType, c);
+ init.params = createDefaultConstructorParams(make, baseInit, init,
+ argtypes, based);
+ List<JCVariableDecl> params = make.Params(argtypes, init);
+ List<JCStatement> stats = List.nil();
+ if (c.type != syms.objectType) {
+ stats = stats.prepend(SuperCall(make, typarams, params, based));
+ }
+ result = make.MethodDef(init, make.Block(0, stats));
+ return result;
+ }
+
+ private List<VarSymbol> createDefaultConstructorParams(
+ TreeMaker make,
+ MethodSymbol baseInit,
+ MethodSymbol init,
+ List<Type> argtypes,
+ boolean based) {
+ List<VarSymbol> initParams = null;
+ List<Type> argTypesList = argtypes;
+ if (based) {
+ /* In this case argtypes will have an extra type, compared to baseInit,
+ * corresponding to the type of the enclosing instance i.e.:
+ *
+ * Inner i = outer.new Inner(1){}
+ *
+ * in the above example argtypes will be (Outer, int) and baseInit
+ * will have parameter's types (int). So in this case we have to add
+ * first the extra type in argtypes and then get the names of the
+ * parameters from baseInit.
+ */
+ initParams = List.nil();
+ VarSymbol param = new VarSymbol(PARAMETER, make.paramName(0), argtypes.head, init);
+ initParams = initParams.append(param);
+ argTypesList = argTypesList.tail;
+ }
+ if (baseInit != null && baseInit.params != null &&
+ baseInit.params.nonEmpty() && argTypesList.nonEmpty()) {
+ initParams = (initParams == null) ? List.<VarSymbol>nil() : initParams;
+ List<VarSymbol> baseInitParams = baseInit.params;
+ while (baseInitParams.nonEmpty() && argTypesList.nonEmpty()) {
+ VarSymbol param = new VarSymbol(baseInitParams.head.flags() | PARAMETER,
+ baseInitParams.head.name, argTypesList.head, init);
+ initParams = initParams.append(param);
+ baseInitParams = baseInitParams.tail;
+ argTypesList = argTypesList.tail;
+ }
+ }
+ return initParams;
+ }
+
+ /** Generate call to superclass constructor. This is:
+ *
+ * super(id_0, ..., id_n)
+ *
+ * or, if based == true
+ *
+ * id_0.super(id_1,...,id_n)
+ *
+ * where id_0, ..., id_n are the names of the given parameters.
+ *
+ * @param make The tree factory
+ * @param params The parameters that need to be passed to super
+ * @param typarams The type parameters that need to be passed to super
+ * @param based Is first parameter a this$n?
+ */
+ JCExpressionStatement SuperCall(TreeMaker make,
+ List<Type> typarams,
+ List<JCVariableDecl> params,
+ boolean based) {
+ JCExpression meth;
+ if (based) {
+ meth = make.Select(make.Ident(params.head), names._super);
+ params = params.tail;
+ } else {
+ meth = make.Ident(names._super);
+ }
+ List<JCExpression> typeargs = typarams.nonEmpty() ? make.Types(typarams) : null;
+ return make.Exec(make.Apply(typeargs, meth, make.Idents(params)));
+ }
+}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileObject.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/BaseFileObject.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, 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
@@ -25,20 +25,19 @@
package com.sun.tools.javac.file;
-import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.CharsetDecoder;
+import java.nio.file.Path;
+
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.FileObject;
import javax.tools.JavaFileObject;
-import static javax.tools.JavaFileObject.Kind.*;
-
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -78,7 +77,7 @@
throw new UnsupportedOperationException();
}
- protected abstract String inferBinaryName(Iterable<? extends File> path);
+ protected abstract String inferBinaryName(Iterable<? extends Path> path);
protected static JavaFileObject.Kind getKind(String filename) {
return BaseFileManager.getKind(filename);
@@ -89,8 +88,8 @@
return (lastDot == -1 ? fileName : fileName.substring(0, lastDot));
}
- protected static URI createJarUri(File jarFile, String entryName) {
- URI jarURI = jarFile.toURI().normalize();
+ protected static URI createJarUri(Path jarFile, String entryName) {
+ URI jarURI = jarFile.toUri().normalize();
String separator = entryName.startsWith("/") ? "!" : "!/";
try {
// The jar URI convention appears to be not to re-encode the jarURI
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/CacheFSInfo.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/CacheFSInfo.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2011, 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
@@ -25,8 +25,8 @@
package com.sun.tools.javac.file;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -61,31 +61,31 @@
}
@Override
- public File getCanonicalFile(File file) {
+ public Path getCanonicalFile(Path file) {
Entry e = getEntry(file);
return e.canonicalFile;
}
@Override
- public boolean exists(File file) {
+ public boolean exists(Path file) {
Entry e = getEntry(file);
return e.exists;
}
@Override
- public boolean isDirectory(File file) {
+ public boolean isDirectory(Path file) {
Entry e = getEntry(file);
return e.isDirectory;
}
@Override
- public boolean isFile(File file) {
+ public boolean isFile(Path file) {
Entry e = getEntry(file);
return e.isFile;
}
@Override
- public List<File> getJarClassPath(File file) throws IOException {
+ public List<Path> getJarClassPath(Path file) throws IOException {
// don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical
// jar class paths together and have one overwrite the other.
@@ -95,7 +95,7 @@
return e.jarClassPath;
}
- private Entry getEntry(File file) {
+ private Entry getEntry(Path file) {
// don't bother to lock the cache, because it is thread-safe, and
// because the worst that can happen would be to create two identical
// entries together and have one overwrite the other.
@@ -112,13 +112,13 @@
}
// could also be a Map<File,SoftReference<Entry>> ?
- private Map<File,Entry> cache = new ConcurrentHashMap<>();
+ private final Map<Path,Entry> cache = new ConcurrentHashMap<>();
private static class Entry {
- File canonicalFile;
+ Path canonicalFile;
boolean exists;
boolean isFile;
boolean isDirectory;
- List<File> jarClassPath;
+ List<Path> jarClassPath;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,8 +1,10 @@
package com.sun.tools.javac.file;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -42,29 +44,29 @@
context.put(FSInfo.class, this);
}
- public File getCanonicalFile(File file) {
+ public Path getCanonicalFile(Path file) {
try {
- return file.getCanonicalFile();
+ return file.toRealPath();
} catch (IOException e) {
- return file.getAbsoluteFile();
+ return file.toAbsolutePath();
}
}
- public boolean exists(File file) {
- return file.exists();
+ public boolean exists(Path file) {
+ return Files.exists(file);
}
- public boolean isDirectory(File file) {
- return file.isDirectory();
+ public boolean isDirectory(Path file) {
+ return Files.isDirectory(file);
}
- public boolean isFile(File file) {
- return file.isFile();
+ public boolean isFile(Path file) {
+ return Files.isRegularFile(file);
}
- public List<File> getJarClassPath(File file) throws IOException {
- String parent = file.getParent();
- try (JarFile jarFile = new JarFile(file)) {
+ public List<Path> getJarClassPath(Path file) throws IOException {
+ Path parent = file.getParent();
+ try (JarFile jarFile = new JarFile(file.toFile())) {
Manifest man = jarFile.getManifest();
if (man == null)
return Collections.emptyList();
@@ -77,14 +79,14 @@
if (path == null)
return Collections.emptyList();
- List<File> list = new ArrayList<>();
+ List<Path> list = new ArrayList<>();
for (StringTokenizer st = new StringTokenizer(path);
st.hasMoreTokens(); ) {
String elt = st.nextToken();
- File f = new File(elt);
+ Path f = Paths.get(elt);
if (!f.isAbsolute() && parent != null)
- f = new File(parent,elt).getAbsoluteFile();
+ f = parent.resolve(f).toAbsolutePath();
list.add(f);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JRTIndex.java Thu Dec 04 15:22:53 2014 -0800
@@ -31,8 +31,10 @@
import java.nio.file.DirectoryStream;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
+import java.nio.file.FileSystemNotFoundException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.ProviderNotFoundException;
import java.nio.file.spi.FileSystemProvider;
import java.util.Collections;
import java.util.HashMap;
@@ -79,11 +81,12 @@
}
public static boolean isAvailable() {
- for (FileSystemProvider p: FileSystemProvider.installedProviders()) {
- if (p.getScheme().equals("jrt"))
- return true;
+ try {
+ FileSystems.getFileSystem(URI.create("jrt:/"));
+ return true;
+ } catch (ProviderNotFoundException | FileSystemNotFoundException e) {
+ return false;
}
- return false;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Dec 04 15:22:53 2014 -0800
@@ -34,7 +34,12 @@
import java.net.URL;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.InvalidPathException;
+import java.nio.file.LinkOption;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -45,6 +50,8 @@
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
import java.util.zip.ZipFile;
import javax.lang.model.SourceVersion;
@@ -97,17 +104,17 @@
protected boolean mmappedIO;
protected boolean symbolFileEnabled;
- protected enum SortFiles implements Comparator<File> {
+ protected enum SortFiles implements Comparator<Path> {
FORWARD {
@Override
- public int compare(File f1, File f2) {
- return f1.getName().compareTo(f2.getName());
+ public int compare(Path f1, Path f2) {
+ return f1.getFileName().compareTo(f2.getFileName());
}
},
REVERSE {
@Override
- public int compare(File f1, File f2) {
- return -f1.getName().compareTo(f2.getName());
+ public int compare(Path f1, Path f2) {
+ return -f1.getFileName().compareTo(f2.getFileName());
}
}
}
@@ -171,10 +178,10 @@
}
public JavaFileObject getFileForInput(String name) {
- return getRegularFile(new File(name));
+ return getRegularFile(Paths.get(name));
}
- public JavaFileObject getRegularFile(File file) {
+ public JavaFileObject getRegularFile(Path file) {
return new RegularFileObject(this, file);
}
@@ -298,25 +305,36 @@
* Insert all files in subdirectory subdirectory of directory directory
* which match fileKinds into resultList
*/
- private void listDirectory(File directory,
+ private void listDirectory(Path directory,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
ListBuffer<JavaFileObject> resultList) {
- File d = subdirectory.getFile(directory);
- if (!caseMapCheck(d, subdirectory))
+ Path d;
+ try {
+ d = subdirectory.getFile(directory);
+ } catch (InvalidPathException ignore) {
return;
+ }
- File[] files = d.listFiles();
- if (files == null)
+ if (!Files.exists(d)) {
+ return;
+ }
+
+ if (!caseMapCheck(d, subdirectory)) {
return;
-
- if (sortFiles != null)
- Arrays.sort(files, sortFiles);
+ }
- for (File f: files) {
- String fname = f.getName();
- if (f.isDirectory()) {
+ java.util.List<Path> files;
+ try (Stream<Path> s = Files.list(d)) {
+ files = (sortFiles == null ? s : s.sorted(sortFiles)).collect(Collectors.toList());
+ } catch (IOException ignore) {
+ return;
+ }
+
+ for (Path f: files) {
+ String fname = f.getFileName().toString();
+ if (Files.isDirectory(f)) {
if (recurse && SourceVersion.isIdentifier(fname)) {
listDirectory(directory,
new RelativeDirectory(subdirectory, fname),
@@ -327,7 +345,7 @@
} else {
if (isValidFile(fname, fileKinds)) {
JavaFileObject fe =
- new RegularFileObject(this, fname, new File(d, fname));
+ new RegularFileObject(this, fname, d.resolve(fname));
resultList.append(fe);
}
}
@@ -370,7 +388,7 @@
* Insert all files in subdirectory subdirectory of container which
* match fileKinds into resultList
*/
- private void listContainer(File container,
+ private void listContainer(Path container,
RelativeDirectory subdirectory,
Set<JavaFileObject.Kind> fileKinds,
boolean recurse,
@@ -378,10 +396,10 @@
Archive archive = archives.get(container);
if (archive == null) {
// Very temporary and obnoxious interim hack
- if (container.getName().equals("bootmodules.jimage")) {
+ if (container.endsWith("bootmodules.jimage")) {
System.err.println("Warning: reference to bootmodules.jimage replaced by jrt:");
container = Locations.JRT_MARKER_FILE;
- } else if (container.getName().endsWith(".jimage")) {
+ } else if (container.getFileName().toString().endsWith(".jimage")) {
System.err.println("Warning: reference to " + container + " ignored");
return;
}
@@ -436,13 +454,15 @@
* ends in a string of characters with the same case as given name.
* Ignore file separators in both path and name.
*/
- private boolean caseMapCheck(File f, RelativePath name) {
+ private boolean caseMapCheck(Path f, RelativePath name) {
if (fileSystemIsCaseSensitive) return true;
- // Note that getCanonicalPath() returns the case-sensitive
+ // Note that toRealPath() returns the case-sensitive
// spelled file name.
String path;
+ char sep;
try {
- path = f.getCanonicalPath();
+ path = f.toRealPath(LinkOption.NOFOLLOW_LINKS).toString();
+ sep = f.getFileSystem().getSeparator().charAt(0);
} catch (IOException ex) {
return false;
}
@@ -451,7 +471,7 @@
int i = pcs.length - 1;
int j = ncs.length - 1;
while (i >= 0 && j >= 0) {
- while (i >= 0 && pcs[i] == File.separatorChar) i--;
+ while (i >= 0 && pcs[i] == sep) i--;
while (j >= 0 && ncs[j] == '/') j--;
if (i >= 0 && j >= 0) {
if (pcs[i] != ncs[j]) return false;
@@ -479,8 +499,8 @@
}
public class MissingArchive implements Archive {
- final File zipFileName;
- public MissingArchive(File name) {
+ final Path zipFileName;
+ public MissingArchive(Path name) {
zipFileName = name;
}
@Override
@@ -515,7 +535,7 @@
/** A directory of zip files already opened.
*/
- Map<File, Archive> archives = new HashMap<>();
+ Map<Path, Archive> archives = new HashMap<>();
/*
* This method looks for a ZipFormatException and takes appropriate
@@ -523,7 +543,7 @@
* fail over to the platform zip, and allow it to deal with a potentially
* non compliant zip file.
*/
- protected Archive openArchive(File zipFilename) throws IOException {
+ protected Archive openArchive(Path zipFilename) throws IOException {
try {
return openArchive(zipFilename, contextUseOptimizedZip);
} catch (IOException ioe) {
@@ -537,7 +557,7 @@
/** Open a new zip file directory, and cache it.
*/
- private Archive openArchive(File zipFileName, boolean useOptimizedZip) throws IOException {
+ private Archive openArchive(Path zipFileName, boolean useOptimizedZip) throws IOException {
Archive archive;
try {
@@ -547,7 +567,7 @@
String preindexCacheLocation = null;
if (!useOptimizedZip) {
- zdir = new ZipFile(zipFileName);
+ zdir = new ZipFile(zipFileName.toFile());
} else {
usePreindexedCache = options.isSet("usezipindex");
preindexCacheLocation = options.get("java.io.tmpdir");
@@ -584,12 +604,12 @@
preindexCacheLocation,
options.isSet("writezipindexfiles")));
}
- } catch (FileNotFoundException ex) {
+ } catch (FileNotFoundException | NoSuchFileException ex) {
archive = new MissingArchive(zipFileName);
} catch (ZipFileIndex.ZipFormatException zfe) {
throw zfe;
} catch (IOException ex) {
- if (zipFileName.exists())
+ if (Files.exists(zipFileName))
log.error("error.reading.file", zipFileName, getMessage(ex));
archive = new MissingArchive(zipFileName);
}
@@ -649,13 +669,13 @@
nullCheck(packageName);
nullCheck(kinds);
- Iterable<? extends File> path = getLocation(location);
+ Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null)
return List.nil();
RelativeDirectory subdirectory = RelativeDirectory.forPackage(packageName);
ListBuffer<JavaFileObject> results = new ListBuffer<>();
- for (File directory : path)
+ for (Path directory : path)
listContainer(directory, subdirectory, kinds, recurse, results);
return results.toList();
}
@@ -665,7 +685,7 @@
file.getClass(); // null check
location.getClass(); // null check
// Need to match the path semantics of list(location, ...)
- Iterable<? extends File> path = getLocation(location);
+ Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null) {
return null;
}
@@ -730,11 +750,11 @@
}
private JavaFileObject getFileForInput(Location location, RelativeFile name) throws IOException {
- Iterable<? extends File> path = getLocation(location);
+ Iterable<? extends Path> path = getLocationAsPaths(location);
if (path == null)
return null;
- for (File file: path) {
+ for (Path file: path) {
Archive a = archives.get(file);
if (a == null) {
// archives are not created for directories or jrt: images
@@ -747,9 +767,12 @@
return PathFileObject.createJRTPathFileObject(this, p);
continue;
} else if (fsInfo.isDirectory(file)) {
- File f = name.getFile(file);
- if (f.exists())
- return new RegularFileObject(this, f);
+ try {
+ Path f = name.getFile(file);
+ if (Files.exists(f))
+ return new RegularFileObject(this, f);
+ } catch (InvalidPathException ignore) {
+ }
continue;
}
// Not a directory, create the archive
@@ -802,31 +825,37 @@
FileObject sibling)
throws IOException
{
- File dir;
+ Path dir;
if (location == CLASS_OUTPUT) {
if (getClassOutDir() != null) {
dir = getClassOutDir();
} else {
- File siblingDir = null;
+ Path siblingDir = null;
if (sibling != null && sibling instanceof RegularFileObject) {
- siblingDir = ((RegularFileObject)sibling).file.getParentFile();
+ siblingDir = ((RegularFileObject)sibling).file.getParent();
}
- return new RegularFileObject(this, new File(siblingDir, fileName.basename()));
+ if (siblingDir == null)
+ return new RegularFileObject(this, Paths.get(fileName.basename()));
+ else
+ return new RegularFileObject(this, siblingDir.resolve(fileName.basename()));
}
} else if (location == SOURCE_OUTPUT) {
dir = (getSourceOutDir() != null ? getSourceOutDir() : getClassOutDir());
} else {
- Iterable<? extends File> path = locations.getLocation(location);
+ Iterable<? extends Path> path = locations.getLocation(location);
dir = null;
- for (File f: path) {
+ for (Path f: path) {
dir = f;
break;
}
}
- File file = fileName.getFile(dir); // null-safe
- return new RegularFileObject(this, file);
-
+ try {
+ Path file = fileName.getFile(dir); // null-safe
+ return new RegularFileObject(this, file);
+ } catch (InvalidPathException e) {
+ throw new IOException("bad filename " + fileName, e);
+ }
}
@Override @DefinedBy(Api.COMPILER)
@@ -839,7 +868,7 @@
else
result = new ArrayList<>();
for (File f: files)
- result.add(new RegularFileObject(this, nullCheck(f)));
+ result.add(new RegularFileObject(this, nullCheck(f).toPath()));
return result;
}
@@ -850,24 +879,29 @@
@Override @DefinedBy(Api.COMPILER)
public void setLocation(Location location,
- Iterable<? extends File> path)
+ Iterable<? extends File> searchpath)
throws IOException
{
nullCheck(location);
- locations.setLocation(location, path);
+ locations.setLocation(location, asPaths(searchpath));
}
@Override @DefinedBy(Api.COMPILER)
public Iterable<? extends File> getLocation(Location location) {
nullCheck(location);
+ return asFiles(locations.getLocation(location));
+ }
+
+ private Iterable<? extends Path> getLocationAsPaths(Location location) {
+ nullCheck(location);
return locations.getLocation(location);
}
- private File getClassOutDir() {
+ private Path getClassOutDir() {
return locations.getOutputLocation(CLASS_OUTPUT);
}
- private File getSourceOutDir() {
+ private Path getSourceOutDir() {
return locations.getOutputLocation(SOURCE_OUTPUT);
}
@@ -938,4 +972,50 @@
return s;
return e.toString();
}
+
+ /* Converters between files and paths.
+ * These are temporary until we can update the StandardJavaFileManager API.
+ */
+
+ private static Iterable<Path> asPaths(final Iterable<? extends File> files) {
+ if (files == null)
+ return null;
+
+ return () -> new Iterator<Path>() {
+ Iterator<? extends File> iter = files.iterator();
+
+ @Override
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ @Override
+ public Path next() {
+ return iter.next().toPath();
+ }
+ };
+ }
+
+ private static Iterable<File> asFiles(final Iterable<? extends Path> paths) {
+ if (paths == null)
+ return null;
+
+ return () -> new Iterator<File>() {
+ Iterator<? extends Path> iter = paths.iterator();
+
+ @Override
+ public boolean hasNext() {
+ return iter.hasNext();
+ }
+
+ @Override
+ public File next() {
+ return iter.next().toFile();
+ }
+ };
+ }
+
+ private static File asFile(Path path) {
+ return path == null ? null : path.toFile();
+ }
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu Dec 04 15:22:53 2014 -0800
@@ -33,6 +33,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -44,7 +45,7 @@
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
-import java.util.StringTokenizer;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.zip.ZipFile;
@@ -104,7 +105,7 @@
// should use the jrt: file system.
// When Locations has been converted to use java.nio.file.Path,
// Locations can use Paths.get(URI.create("jrt:"))
- static final File JRT_MARKER_FILE = new File("JRT_MARKER_FILE");
+ static final Path JRT_MARKER_FILE = Paths.get("JRT_MARKER_FILE");
public Locations() {
initHandlers();
@@ -117,7 +118,7 @@
this.fsInfo = fsInfo;
}
- public Collection<File> bootClassPath() {
+ public Collection<Path> bootClassPath() {
return getLocation(PLATFORM_CLASS_PATH);
}
@@ -127,50 +128,46 @@
return h.isDefault();
}
- public Collection<File> userClassPath() {
+ public Collection<Path> userClassPath() {
return getLocation(CLASS_PATH);
}
- public Collection<File> sourcePath() {
- Collection<File> p = getLocation(SOURCE_PATH);
+ public Collection<Path> sourcePath() {
+ Collection<Path> p = getLocation(SOURCE_PATH);
// TODO: this should be handled by the LocationHandler
return p == null || p.isEmpty() ? null : p;
}
/**
- * Split a path into its elements. Empty path elements will be ignored.
+ * Split a search path into its elements. Empty path elements will be ignored.
*
- * @param path The path to be split
+ * @param searchPath The search path to be split
* @return The elements of the path
*/
- private static Iterable<File> getPathEntries(String path) {
- return getPathEntries(path, null);
+ private static Iterable<Path> getPathEntries(String searchPath) {
+ return getPathEntries(searchPath, null);
}
/**
- * Split a path into its elements. If emptyPathDefault is not null, all empty elements in the
+ * Split a search path into its elements. If emptyPathDefault is not null, all empty elements in the
* path, including empty elements at either end of the path, will be replaced with the value of
* emptyPathDefault.
*
- * @param path The path to be split
+ * @param searchPath The search path to be split
* @param emptyPathDefault The value to substitute for empty path elements, or null, to ignore
* empty path elements
* @return The elements of the path
*/
- private static Iterable<File> getPathEntries(String path, File emptyPathDefault) {
- ListBuffer<File> entries = new ListBuffer<>();
- int start = 0;
- while (start <= path.length()) {
- int sep = path.indexOf(File.pathSeparatorChar, start);
- if (sep == -1) {
- sep = path.length();
+ private static Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) {
+ ListBuffer<Path> entries = new ListBuffer<>();
+ for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) {
+ if (s.isEmpty()) {
+ if (emptyPathDefault != null) {
+ entries.add(emptyPathDefault);
+ }
+ } else {
+ entries.add(Paths.get(s));
}
- if (start < sep) {
- entries.add(new File(path.substring(start, sep)));
- } else if (emptyPathDefault != null) {
- entries.add(emptyPathDefault);
- }
- start = sep + 1;
}
return entries;
}
@@ -179,12 +176,12 @@
* Utility class to help evaluate a path option. Duplicate entries are ignored, jar class paths
* can be expanded.
*/
- private class SearchPath extends LinkedHashSet<File> {
+ private class SearchPath extends LinkedHashSet<Path> {
private static final long serialVersionUID = 0;
private boolean expandJarClassPaths = false;
- private final Set<File> canonicalValues = new HashSet<>();
+ private final Set<Path> canonicalValues = new HashSet<>();
public SearchPath expandJarClassPaths(boolean x) {
expandJarClassPaths = x;
@@ -194,9 +191,9 @@
/**
* What to use when path element is the empty string
*/
- private File emptyPathDefault = null;
+ private Path emptyPathDefault = null;
- public SearchPath emptyPathDefault(File x) {
+ public SearchPath emptyPathDefault(Path x) {
emptyPathDefault = x;
return this;
}
@@ -206,7 +203,7 @@
expandJarClassPaths = true;
try {
if (dirs != null) {
- for (File dir : getPathEntries(dirs)) {
+ for (Path dir : getPathEntries(dirs)) {
addDirectory(dir, warn);
}
}
@@ -220,8 +217,8 @@
return addDirectories(dirs, warn);
}
- private void addDirectory(File dir, boolean warn) {
- if (!dir.isDirectory()) {
+ private void addDirectory(Path dir, boolean warn) {
+ if (!Files.isDirectory(dir)) {
if (warn) {
log.warning(Lint.LintCategory.PATH,
"dir.path.element.not.found", dir);
@@ -229,15 +226,10 @@
return;
}
- File[] files = dir.listFiles();
- if (files == null) {
- return;
- }
-
- for (File direntry : files) {
- if (isArchive(direntry)) {
- addFile(direntry, warn);
- }
+ try (Stream<Path> s = Files.list(dir)) {
+ s.filter(dirEntry -> isArchive(dirEntry))
+ .forEach(dirEntry -> addFile(dirEntry, warn));
+ } catch (IOException ignore) {
}
}
@@ -252,20 +244,20 @@
return addFiles(files, warn);
}
- public SearchPath addFiles(Iterable<? extends File> files, boolean warn) {
+ public SearchPath addFiles(Iterable<? extends Path> files, boolean warn) {
if (files != null) {
- for (File file : files) {
+ for (Path file : files) {
addFile(file, warn);
}
}
return this;
}
- public SearchPath addFiles(Iterable<? extends File> files) {
+ public SearchPath addFiles(Iterable<? extends Path> files) {
return addFiles(files, warn);
}
- public void addFile(File file, boolean warn) {
+ public void addFile(Path file, boolean warn) {
if (contains(file)) {
// discard duplicates
return;
@@ -281,7 +273,7 @@
return;
}
- File canonFile = fsInfo.getCanonicalFile(file);
+ Path canonFile = fsInfo.getCanonicalFile(file);
if (canonicalValues.contains(canonFile)) {
/* Discard duplicates and avoid infinite recursion */
return;
@@ -289,11 +281,11 @@
if (fsInfo.isFile(file)) {
/* File is an ordinary file. */
- if (!isArchive(file) && !file.getName().endsWith(".jimage")) {
+ if (!isArchive(file) && !file.getFileName().toString().endsWith(".jimage")) {
/* Not a recognized extension; open it to see if
it looks like a valid zip file. */
try {
- ZipFile z = new ZipFile(file);
+ ZipFile z = new ZipFile(file.toFile());
z.close();
if (warn) {
log.warning(Lint.LintCategory.PATH,
@@ -315,7 +307,7 @@
super.add(file);
canonicalValues.add(canonFile);
- if (expandJarClassPaths && fsInfo.isFile(file) && !file.getName().endsWith(".jimage")) {
+ if (expandJarClassPaths && fsInfo.isFile(file) && !file.getFileName().toString().endsWith(".jimage")) {
addJarClassPath(file, warn);
}
}
@@ -324,9 +316,9 @@
// Manifest entry. In some future release, we may want to
// update this code to recognize URLs rather than simple
// filenames, but if we do, we should redo all path-related code.
- private void addJarClassPath(File jarFile, boolean warn) {
+ private void addJarClassPath(Path jarFile, boolean warn) {
try {
- for (File f : fsInfo.getJarClassPath(jarFile)) {
+ for (Path f : fsInfo.getJarClassPath(jarFile)) {
addFile(f, warn);
}
} catch (IOException e) {
@@ -371,12 +363,12 @@
/**
* @see StandardJavaFileManager#getLocation
*/
- abstract Collection<File> getLocation();
+ abstract Collection<Path> getLocation();
/**
* @see StandardJavaFileManager#setLocation
*/
- abstract void setLocation(Iterable<? extends File> files) throws IOException;
+ abstract void setLocation(Iterable<? extends Path> files) throws IOException;
}
/**
@@ -386,7 +378,7 @@
*/
private class OutputLocationHandler extends LocationHandler {
- private File outputDir;
+ private Path outputDir;
OutputLocationHandler(Location location, Option... options) {
super(location, options);
@@ -402,31 +394,31 @@
// need to decide how best to report issue for benefit of
// direct API call on JavaFileManager.handleOption(specifies IAE)
// vs. command line decoding.
- outputDir = (value == null) ? null : new File(value);
+ outputDir = (value == null) ? null : Paths.get(value);
return true;
}
@Override
- Collection<File> getLocation() {
+ Collection<Path> getLocation() {
return (outputDir == null) ? null : Collections.singleton(outputDir);
}
@Override
- void setLocation(Iterable<? extends File> files) throws IOException {
+ void setLocation(Iterable<? extends Path> files) throws IOException {
if (files == null) {
outputDir = null;
} else {
- Iterator<? extends File> pathIter = files.iterator();
+ Iterator<? extends Path> pathIter = files.iterator();
if (!pathIter.hasNext()) {
throw new IllegalArgumentException("empty path for directory");
}
- File dir = pathIter.next();
+ Path dir = pathIter.next();
if (pathIter.hasNext()) {
throw new IllegalArgumentException("path too long for directory");
}
- if (!dir.exists()) {
+ if (!Files.exists(dir)) {
throw new FileNotFoundException(dir + ": does not exist");
- } else if (!dir.isDirectory()) {
+ } else if (!Files.isDirectory(dir)) {
throw new IOException(dir + ": not a directory");
}
outputDir = dir;
@@ -441,7 +433,7 @@
*/
private class SimpleLocationHandler extends LocationHandler {
- protected Collection<File> searchPath;
+ protected Collection<Path> searchPath;
SimpleLocationHandler(Location location, Option... options) {
super(location, options);
@@ -458,12 +450,12 @@
}
@Override
- Collection<File> getLocation() {
+ Collection<Path> getLocation() {
return searchPath;
}
@Override
- void setLocation(Iterable<? extends File> files) {
+ void setLocation(Iterable<? extends Path> files) {
SearchPath p;
if (files == null) {
p = computePath(null);
@@ -494,7 +486,7 @@
}
@Override
- Collection<File> getLocation() {
+ Collection<Path> getLocation() {
lazy();
return searchPath;
}
@@ -526,7 +518,7 @@
protected SearchPath createPath() {
return new SearchPath()
.expandJarClassPaths(true) // Only search user jars for Class-Paths
- .emptyPathDefault(new File(".")); // Empty path elt ==> current directory
+ .emptyPathDefault(Paths.get(".")); // Empty path elt ==> current directory
}
private void lazy() {
@@ -545,7 +537,7 @@
*/
private class BootClassPathLocationHandler extends LocationHandler {
- private Collection<File> searchPath;
+ private Collection<Path> searchPath;
final Map<Option, String> optionValues = new EnumMap<>(Option.class);
/**
@@ -599,13 +591,13 @@
}
@Override
- Collection<File> getLocation() {
+ Collection<Path> getLocation() {
lazy();
return searchPath;
}
@Override
- void setLocation(Iterable<? extends File> files) {
+ void setLocation(Iterable<? extends Path> files) {
if (files == null) {
searchPath = null; // reset to "uninitialized"
} else {
@@ -638,7 +630,7 @@
path.addFiles(bootclasspathOpt);
} else {
// Standard system classes for this compiler's release.
- Collection<File> systemClasses = systemClasses(java_home);
+ Collection<Path> systemClasses = systemClasses(java_home);
if (systemClasses != null) {
path.addFiles(systemClasses, false);
} else {
@@ -657,8 +649,8 @@
path.addDirectories(extdirsOpt);
} else {
// Add lib/jfxrt.jar to the search path
- File jfxrt = new File(new File(java_home, "lib"), "jfxrt.jar");
- if (jfxrt.exists()) {
+ Path jfxrt = Paths.get(java_home, "lib", "jfxrt.jar");
+ if (Files.exists(jfxrt)) {
path.addFile(jfxrt, false);
}
path.addDirectories(System.getProperty("java.ext.dirs"), false);
@@ -678,7 +670,7 @@
*
* @throws UncheckedIOException if an I/O errors occurs
*/
- private Collection<File> systemClasses(String java_home) throws IOException {
+ private Collection<Path> systemClasses(String java_home) throws IOException {
// Return .jimage files if available
Path libModules = Paths.get(java_home, "lib", "modules");
if (Files.exists(libModules)) {
@@ -695,7 +687,6 @@
if (Files.exists(libModules.resolve("java.base"))) {
return Files.list(libModules)
.map(d -> d.resolve("classes"))
- .map(Path::toFile)
.collect(Collectors.toList());
}
@@ -703,7 +694,6 @@
Path modules = Paths.get(java_home, "modules");
if (Files.isDirectory(modules.resolve("java.base"))) {
return Files.list(modules)
- .map(Path::toFile)
.collect(Collectors.toList());
}
@@ -753,12 +743,12 @@
return (h == null ? false : h.handleOption(option, value));
}
- Collection<File> getLocation(Location location) {
+ Collection<Path> getLocation(Location location) {
LocationHandler h = getHandler(location);
return (h == null ? null : h.getLocation());
}
- File getOutputLocation(Location location) {
+ Path getOutputLocation(Location location) {
if (!location.isOutputLocation()) {
throw new IllegalArgumentException();
}
@@ -766,7 +756,7 @@
return ((OutputLocationHandler) h).outputDir;
}
- void setLocation(Location location, Iterable<? extends File> files) throws IOException {
+ void setLocation(Location location, Iterable<? extends Path> files) throws IOException {
LocationHandler h = getHandler(location);
if (h == null) {
if (location.isOutputLocation()) {
@@ -787,8 +777,8 @@
/**
* Is this the name of an archive file?
*/
- private boolean isArchive(File file) {
- String n = StringUtils.toLowerCase(file.getName());
+ private boolean isArchive(Path file) {
+ String n = StringUtils.toLowerCase(file.getFileName().toString());
return fsInfo.isFile(file)
&& (n.endsWith(".jar") || n.endsWith(".zip"));
}
@@ -797,50 +787,41 @@
* Utility method for converting a search path string to an array of directory and JAR file
* URLs.
*
- * Note that this method is called by apt and the DocletInvoker.
+ * Note that this method is called by the DocletInvoker.
*
* @param path the search path string
* @return the resulting array of directory and JAR file URLs
*/
public static URL[] pathToURLs(String path) {
- StringTokenizer st = new StringTokenizer(path, File.pathSeparator);
- URL[] urls = new URL[st.countTokens()];
- int count = 0;
- while (st.hasMoreTokens()) {
- URL url = fileToURL(new File(st.nextToken()));
- if (url != null) {
- urls[count++] = url;
+ java.util.List<URL> urls = new ArrayList<>();
+ for (String s: path.split(Pattern.quote(File.pathSeparator))) {
+ if (!s.isEmpty()) {
+ URL url = fileToURL(Paths.get(s));
+ if (url != null) {
+ urls.add(url);
+ }
}
}
- urls = Arrays.copyOf(urls, count);
- return urls;
+ return urls.toArray(new URL[urls.size()]);
}
/**
* Returns the directory or JAR file URL corresponding to the specified local file name.
*
- * @param file the File object
+ * @param file the Path object
* @return the resulting directory or JAR file URL, or null if unknown
*/
- private static URL fileToURL(File file) {
- String name;
+ private static URL fileToURL(Path file) {
+ Path p;
try {
- name = file.getCanonicalPath();
+ p = file.toRealPath();
} catch (IOException e) {
- name = file.getAbsolutePath();
- }
- name = name.replace(File.separatorChar, '/');
- if (!name.startsWith("/")) {
- name = "/" + name;
- }
- // If the file does not exist, then assume that it's a directory
- if (!file.isFile()) {
- name = name + "/";
+ p = file.toAbsolutePath();
}
try {
- return new URL("file", "", name);
+ return p.normalize().toUri().toURL();
} catch (MalformedURLException e) {
- throw new IllegalArgumentException(file.toString());
+ return null;
}
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RegularFileObject.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RegularFileObject.java Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -25,9 +25,6 @@
package com.sun.tools.javac.file;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -39,8 +36,12 @@
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.text.Normalizer;
+
import javax.tools.JavaFileObject;
-import java.text.Normalizer;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -59,33 +60,33 @@
*/
private boolean hasParents = false;
private String name;
- final File file;
- private Reference<File> absFileRef;
+ final Path file;
+ private Reference<Path> absFileRef;
final static boolean isMacOS = System.getProperty("os.name", "").contains("OS X");
- public RegularFileObject(JavacFileManager fileManager, File f) {
- this(fileManager, f.getName(), f);
+ public RegularFileObject(JavacFileManager fileManager, Path f) {
+ this(fileManager, f.getFileName().toString(), f);
}
- public RegularFileObject(JavacFileManager fileManager, String name, File f) {
+ public RegularFileObject(JavacFileManager fileManager, String name, Path f) {
super(fileManager);
- if (f.isDirectory()) {
+ if (Files.isDirectory(f)) {
throw new IllegalArgumentException("directories not supported");
}
this.name = name;
this.file = f;
- if (f.lastModified() > System.currentTimeMillis())
+ if (getLastModified() > System.currentTimeMillis())
fileManager.log.warning("file.from.future", f);
}
@Override @DefinedBy(Api.COMPILER)
public URI toUri() {
- return file.toURI().normalize();
+ return file.toUri().normalize();
}
@Override @DefinedBy(Api.COMPILER)
public String getName() {
- return file.getPath();
+ return file.toString();
}
@Override
@@ -100,21 +101,21 @@
@Override @DefinedBy(Api.COMPILER)
public InputStream openInputStream() throws IOException {
- return new FileInputStream(file);
+ return Files.newInputStream(file);
}
@Override @DefinedBy(Api.COMPILER)
public OutputStream openOutputStream() throws IOException {
fileManager.flushCache(this);
ensureParentDirectoriesExist();
- return new FileOutputStream(file);
+ return Files.newOutputStream(file);
}
@Override @DefinedBy(Api.COMPILER)
public CharBuffer getCharContent(boolean ignoreEncodingErrors) throws IOException {
CharBuffer cb = fileManager.getCachedContent(this);
if (cb == null) {
- try (InputStream in = new FileInputStream(file)) {
+ try (InputStream in = Files.newInputStream(file)) {
ByteBuffer bb = fileManager.makeByteBuffer(in);
JavaFileObject prev = fileManager.log.useSource(this);
try {
@@ -135,17 +136,26 @@
public Writer openWriter() throws IOException {
fileManager.flushCache(this);
ensureParentDirectoriesExist();
- return new OutputStreamWriter(new FileOutputStream(file), fileManager.getEncodingName());
+ return new OutputStreamWriter(Files.newOutputStream(file), fileManager.getEncodingName());
}
@Override @DefinedBy(Api.COMPILER)
public long getLastModified() {
- return file.lastModified();
+ try {
+ return Files.getLastModifiedTime(file).toMillis();
+ } catch (IOException e) {
+ return 0;
+ }
}
@Override @DefinedBy(Api.COMPILER)
public boolean delete() {
- return file.delete();
+ try {
+ Files.delete(file);
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
}
@Override
@@ -154,20 +164,21 @@
}
@Override
- protected String inferBinaryName(Iterable<? extends File> path) {
- String fPath = file.getPath();
+ protected String inferBinaryName(Iterable<? extends Path> path) {
+ String fPath = file.toString();
//System.err.println("RegularFileObject " + file + " " +r.getPath());
- for (File dir: path) {
+ for (Path dir: path) {
//System.err.println("dir: " + dir);
- String dPath = dir.getPath();
+ String sep = dir.getFileSystem().getSeparator();
+ String dPath = dir.toString();
if (dPath.length() == 0)
dPath = System.getProperty("user.dir");
- if (!dPath.endsWith(File.separator))
- dPath += File.separator;
+ if (!dPath.endsWith(sep))
+ dPath += sep;
if (fPath.regionMatches(true, 0, dPath, 0, dPath.length())
- && new File(fPath.substring(0, dPath.length())).equals(new File(dPath))) {
+ && Paths.get(fPath.substring(0, dPath.length())).equals(Paths.get(dPath))) {
String relativeName = fPath.substring(dPath.length());
- return removeExtension(relativeName).replace(File.separatorChar, '.');
+ return removeExtension(relativeName).replace(sep, ".");
}
}
return null;
@@ -199,7 +210,7 @@
if (name.equalsIgnoreCase(n)) {
try {
// allow for Windows
- return file.getCanonicalFile().getName().equals(n);
+ return file.toRealPath().getFileName().toString().equals(n);
} catch (IOException e) {
}
}
@@ -208,12 +219,12 @@
private void ensureParentDirectoriesExist() throws IOException {
if (!hasParents) {
- File parent = file.getParentFile();
- if (parent != null && !parent.exists()) {
- if (!parent.mkdirs()) {
- if (!parent.exists() || !parent.isDirectory()) {
- throw new IOException("could not create parent directories");
- }
+ Path parent = file.getParent();
+ if (parent != null && !Files.isDirectory(parent)) {
+ try {
+ Files.createDirectories(parent);
+ } catch (IOException e) {
+ throw new IOException("could not create parent directories", e);
}
}
hasParents = true;
@@ -242,10 +253,10 @@
return getAbsoluteFile().hashCode();
}
- private File getAbsoluteFile() {
- File absFile = (absFileRef == null ? null : absFileRef.get());
+ private Path getAbsoluteFile() {
+ Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) {
- absFile = file.getAbsoluteFile();
+ absFile = file.toAbsolutePath();
absFileRef = new SoftReference<>(absFile);
}
return absFile;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java Thu Dec 04 15:22:53 2014 -0800
@@ -57,12 +57,6 @@
public abstract String basename();
- public File getFile(File directory) {
- if (path.length() == 0)
- return directory;
- return new File(directory, path.replace('/', File.separatorChar));
- }
-
public Path getFile(Path directory) throws /*unchecked*/ InvalidPathException {
if (directory == null) {
String sep = FileSystems.getDefault().getSeparator();
@@ -73,6 +67,7 @@
}
}
+ @Override
public int compareTo(RelativePath other) {
return path.compareTo(other.path);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipArchive.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipArchive.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2009, 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
@@ -25,15 +25,18 @@
package com.sun.tools.javac.file;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
import java.net.URI;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
@@ -49,8 +52,6 @@
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.List;
-import java.lang.ref.Reference;
-import java.lang.ref.SoftReference;
/**
* <p><b>This is NOT part of any supported API.
@@ -131,10 +132,10 @@
return "ZipArchive[" + zfile.getName() + "]";
}
- private File getAbsoluteFile() {
- File absFile = (absFileRef == null ? null : absFileRef.get());
+ private Path getAbsoluteFile() {
+ Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) {
- absFile = new File(zfile.getName()).getAbsoluteFile();
+ absFile = Paths.get(zfile.getName()).toAbsolutePath();
absFileRef = new SoftReference<>(absFile);
}
return absFile;
@@ -155,7 +156,7 @@
/**
* A reference to the absolute filename for the zip file for the archive.
*/
- protected Reference<File> absFileRef;
+ protected Reference<Path> absFileRef;
/**
* A subclass of JavaFileObject representing zip entries.
@@ -175,7 +176,7 @@
@DefinedBy(Api.COMPILER)
public URI toUri() {
- File zipFile = new File(zarch.zfile.getName());
+ Path zipFile = Paths.get(zarch.zfile.getName());
return createJarUri(zipFile, entry.getName());
}
@@ -186,7 +187,7 @@
@Override
public String getShortName() {
- return new File(zarch.zfile.getName()).getName() + "(" + entry + ")";
+ return Paths.get(zarch.zfile.getName()).getFileName() + "(" + entry + ")";
}
@Override @DefinedBy(Api.COMPILER)
@@ -246,7 +247,7 @@
}
@Override
- protected String inferBinaryName(Iterable<? extends File> path) {
+ protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName();
return removeExtension(entryName).replace('/', '.');
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndex.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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,18 +26,20 @@
package com.sun.tools.javac.file;
-import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.lang.ref.Reference;
import java.lang.ref.SoftReference;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections;
+import java.util.HashMap;
import java.util.LinkedHashMap;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -91,14 +93,14 @@
Collections.<RelativeDirectory>emptySet();
// ZipFileIndex data entries
- final File zipFile;
- private Reference<File> absFileRef;
+ final Path zipFile;
+ private Reference<Path> absFileRef;
long zipFileLastModified = NOT_MODIFIED;
private RandomAccessFile zipRandomFile;
private Entry[] entries;
private boolean readFromIndex = false;
- private File zipIndexFile = null;
+ private Path zipIndexFile = null;
private boolean triedToReadIndex = false;
final RelativeDirectory symbolFilePrefix;
private final int symbolFilePrefixLength;
@@ -117,7 +119,7 @@
return (zipRandomFile != null);
}
- ZipFileIndex(File zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
+ ZipFileIndex(Path zipFile, RelativeDirectory symbolFilePrefix, boolean writeIndex,
boolean useCache, String cacheLocation) throws IOException {
this.zipFile = zipFile;
this.symbolFilePrefix = symbolFilePrefix;
@@ -128,7 +130,7 @@
this.preindexedCacheLocation = cacheLocation;
if (zipFile != null) {
- this.zipFileLastModified = zipFile.lastModified();
+ this.zipFileLastModified = Files.getLastModifiedTime(zipFile).toMillis();
}
// Validate integrity of the zip file
@@ -148,10 +150,11 @@
}
private boolean isUpToDate() {
- if (zipFile != null
- && ((!NON_BATCH_MODE) || zipFileLastModified == zipFile.lastModified())
- && hasPopulatedData) {
- return true;
+ try {
+ return (zipFile != null
+ && ((!NON_BATCH_MODE) || zipFileLastModified == Files.getLastModifiedTime(zipFile).toMillis())
+ && hasPopulatedData);
+ } catch (IOException ignore) {
}
return false;
@@ -199,7 +202,7 @@
private void openFile() throws FileNotFoundException {
if (zipRandomFile == null && zipFile != null) {
- zipRandomFile = new RandomAccessFile(zipFile, "r");
+ zipRandomFile = new RandomAccessFile(zipFile.toFile(), "r");
}
}
@@ -785,11 +788,11 @@
entries.add(zipFileIndex.entries[i]);
}
} else {
- File indexFile = zipFileIndex.getIndexFile();
+ Path indexFile = zipFileIndex.getIndexFile();
if (indexFile != null) {
RandomAccessFile raf = null;
try {
- raf = new RandomAccessFile(indexFile, "r");
+ raf = new RandomAccessFile(indexFile.toFile(), "r");
raf.seek(writtenOffsetOffset);
for (int nFiles = 0; nFiles < numEntries; nFiles++) {
@@ -856,11 +859,11 @@
triedToReadIndex = true;
RandomAccessFile raf = null;
try {
- File indexFileName = getIndexFile();
- raf = new RandomAccessFile(indexFileName, "r");
+ Path indexFileName = getIndexFile();
+ raf = new RandomAccessFile(indexFileName.toFile(), "r");
long fileStamp = raf.readLong();
- if (zipFile.lastModified() != fileStamp) {
+ if (Files.getLastModifiedTime(zipFile).toMillis() != fileStamp) {
ret = false;
} else {
directories = new LinkedHashMap<>();
@@ -908,7 +911,7 @@
return true;
}
- File indexFile = getIndexFile();
+ Path indexFile = getIndexFile();
if (indexFile == null) {
return false;
}
@@ -916,7 +919,7 @@
RandomAccessFile raf = null;
long writtenSoFar = 0;
try {
- raf = new RandomAccessFile(indexFile, "rw");
+ raf = new RandomAccessFile(indexFile.toFile(), "rw");
raf.writeLong(zipFileLastModified);
writtenSoFar += 8;
@@ -1016,27 +1019,27 @@
}
}
- private File getIndexFile() {
+ private Path getIndexFile() {
if (zipIndexFile == null) {
if (zipFile == null) {
return null;
}
- zipIndexFile = new File((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
- zipFile.getName() + ".index");
+ zipIndexFile = Paths.get((preindexedCacheLocation == null ? "" : preindexedCacheLocation) +
+ zipFile.getFileName() + ".index");
}
return zipIndexFile;
}
- public File getZipFile() {
+ public Path getZipFile() {
return zipFile;
}
- File getAbsoluteFile() {
- File absFile = (absFileRef == null ? null : absFileRef.get());
+ Path getAbsoluteFile() {
+ Path absFile = (absFileRef == null ? null : absFileRef.get());
if (absFile == null) {
- absFile = zipFile.getAbsoluteFile();
+ absFile = zipFile.toAbsolutePath();
absFileRef = new SoftReference<>(absFile);
}
return absFile;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexArchive.java Thu Dec 04 15:22:53 2014 -0800
@@ -25,12 +25,8 @@
package com.sun.tools.javac.file;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.util.Set;
-import javax.tools.JavaFileObject;
-
-import java.io.ByteArrayInputStream;
-import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Writer;
@@ -38,6 +34,10 @@
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharsetDecoder;
+import java.nio.file.Path;
+import java.util.Set;
+
+import javax.tools.JavaFileObject;
import com.sun.tools.javac.file.JavacFileManager.Archive;
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
@@ -56,7 +56,7 @@
public class ZipFileIndexArchive implements Archive {
private final ZipFileIndex zfIndex;
- private JavacFileManager fileManager;
+ private final JavacFileManager fileManager;
public ZipFileIndexArchive(JavacFileManager fileManager, ZipFileIndex zdir) throws IOException {
super();
@@ -111,10 +111,10 @@
/** The name of the zip file where this entry resides.
*/
- File zipName;
+ Path zipName;
- ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, File zipFileName) {
+ ZipFileIndexFileObject(JavacFileManager fileManager, ZipFileIndex zfIndex, ZipFileIndex.Entry entry, Path zipFileName) {
super(fileManager);
this.name = entry.getFileName();
this.zfIndex = zfIndex;
@@ -134,7 +134,7 @@
@Override
public String getShortName() {
- return zipName.getName() + "(" + entry.getName() + ")";
+ return zipName.getFileName() + "(" + entry.getName() + ")";
}
@Override @DefinedBy(Api.COMPILER)
@@ -194,7 +194,7 @@
}
@Override
- protected String inferBinaryName(Iterable<? extends File> path) {
+ protected String inferBinaryName(Iterable<? extends Path> path) {
String entryName = entry.getName();
if (zfIndex.symbolFilePrefix != null) {
String prefix = zfIndex.symbolFilePrefix.path;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexCache.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/ZipFileIndexCache.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 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,21 +25,22 @@
package com.sun.tools.javac.file;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import com.sun.tools.javac.file.RelativePath.RelativeDirectory;
import com.sun.tools.javac.util.Context;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
/** A cache for ZipFileIndex objects. */
public class ZipFileIndexCache {
- private final Map<File, ZipFileIndex> map = new HashMap<>();
+ private final Map<Path, ZipFileIndex> map = new HashMap<>();
/** Get a shared instance of the cache. */
private static ZipFileIndexCache sharedInstance;
@@ -89,13 +90,13 @@
return zipFileIndexes;
}
- public synchronized ZipFileIndex getZipFileIndex(File zipFile,
+ public synchronized ZipFileIndex getZipFileIndex(Path zipFile,
RelativeDirectory symbolFilePrefix,
boolean useCache, String cacheLocation,
boolean writeIndex) throws IOException {
ZipFileIndex zi = getExistingZipIndex(zipFile);
- if (zi == null || (zi != null && zipFile.lastModified() != zi.zipFileLastModified)) {
+ if (zi == null || (zi != null && Files.getLastModifiedTime(zipFile).toMillis() != zi.zipFileLastModified)) {
zi = new ZipFileIndex(zipFile, symbolFilePrefix, writeIndex,
useCache, cacheLocation);
map.put(zipFile, zi);
@@ -103,7 +104,7 @@
return zi;
}
- public synchronized ZipFileIndex getExistingZipIndex(File zipFile) {
+ public synchronized ZipFileIndex getExistingZipIndex(Path zipFile) {
return map.get(zipFile);
}
@@ -112,7 +113,7 @@
}
public synchronized void clearCache(long timeNotUsed) {
- for (File cachedFile : map.keySet()) {
+ for (Path cachedFile : map.keySet()) {
ZipFileIndex cachedZipIndex = map.get(cachedFile);
if (cachedZipIndex != null) {
long timeToTest = cachedZipIndex.lastReferenceTimeStamp + timeNotUsed;
@@ -124,7 +125,7 @@
}
}
- public synchronized void removeFromCache(File file) {
+ public synchronized void removeFromCache(Path file) {
map.remove(file);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Dec 04 15:22:53 2014 -0800
@@ -29,23 +29,27 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.CharBuffer;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import javax.tools.JavaFileObject;
+
import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
-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.code.Type.*;
+import com.sun.tools.javac.comp.Annotate;
import com.sun.tools.javac.file.BaseFileObject;
+import com.sun.tools.javac.jvm.ClassFile.NameAndType;
+import com.sun.tools.javac.jvm.ClassFile.Version;
import com.sun.tools.javac.util.*;
import com.sun.tools.javac.util.DefinedBy.Api;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -2467,7 +2471,7 @@
}
@Override
- protected String inferBinaryName(Iterable<? extends File> path) {
+ protected String inferBinaryName(Iterable<? extends Path> path) {
return flatname.toString();
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Dec 04 15:22:53 2014 -0800
@@ -640,6 +640,27 @@
}
+ private void writeParamAnnotations(List<VarSymbol> params,
+ RetentionPolicy retention) {
+ for (VarSymbol s : params) {
+ ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
+ for (Attribute.Compound a : s.getRawAttributes())
+ if (types.getRetention(a) == retention)
+ buf.append(a);
+ databuf.appendChar(buf.length());
+ for (Attribute.Compound a : buf)
+ writeCompoundAttribute(a);
+ }
+
+ }
+
+ private void writeParamAnnotations(MethodSymbol m,
+ RetentionPolicy retention) {
+ databuf.appendByte(m.params.length() + m.extraParams.length());
+ writeParamAnnotations(m.extraParams, retention);
+ writeParamAnnotations(m.params, retention);
+ }
+
/** Write method parameter annotations;
* return number of attributes written.
*/
@@ -662,31 +683,13 @@
int attrCount = 0;
if (hasVisible) {
int attrIndex = writeAttr(names.RuntimeVisibleParameterAnnotations);
- databuf.appendByte(m.params.length());
- for (VarSymbol s : m.params) {
- ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
- for (Attribute.Compound a : s.getRawAttributes())
- if (types.getRetention(a) == RetentionPolicy.RUNTIME)
- buf.append(a);
- databuf.appendChar(buf.length());
- for (Attribute.Compound a : buf)
- writeCompoundAttribute(a);
- }
+ writeParamAnnotations(m, RetentionPolicy.RUNTIME);
endAttr(attrIndex);
attrCount++;
}
if (hasInvisible) {
int attrIndex = writeAttr(names.RuntimeInvisibleParameterAnnotations);
- databuf.appendByte(m.params.length());
- for (VarSymbol s : m.params) {
- ListBuffer<Attribute.Compound> buf = new ListBuffer<>();
- for (Attribute.Compound a : s.getRawAttributes())
- if (types.getRetention(a) == RetentionPolicy.CLASS)
- buf.append(a);
- databuf.appendChar(buf.length());
- for (Attribute.Compound a : buf)
- writeCompoundAttribute(a);
- }
+ writeParamAnnotations(m, RetentionPolicy.CLASS);
endAttr(attrIndex);
attrCount++;
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Main.java Thu Dec 04 15:22:53 2014 -0800
@@ -29,10 +29,10 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.net.URL;
+import java.nio.file.NoSuchFileException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-
import java.util.Set;
import javax.tools.JavaFileManager;
@@ -160,13 +160,15 @@
Option.HELP.process(new OptionHelper.GrumpyHelper(log) {
@Override
public String getOwnName() { return ownName; }
+ @Override
+ public void put(String name, String value) { }
}, "-help");
return Result.CMDERR;
}
try {
argv = CommandLine.parse(argv);
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
warning("err.file.not.found", e.getMessage());
return Result.SYSERR;
} catch (IOException ex) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java Thu Dec 04 15:22:53 2014 -0800
@@ -30,12 +30,13 @@
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
-import java.nio.file.Files;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitOption;
import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
@@ -48,6 +49,7 @@
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
+
import javax.lang.model.SourceVersion;
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
@@ -55,9 +57,6 @@
import javax.tools.JavaFileObject.Kind;
import javax.tools.StandardLocation;
-import static java.nio.file.FileVisitOption.*;
-import static javax.tools.StandardLocation.*;
-
import com.sun.tools.javac.util.BaseFileManager;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.DefinedBy;
@@ -65,6 +64,10 @@
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
+import static java.nio.file.FileVisitOption.*;
+
+import static javax.tools.StandardLocation.*;
+
import static com.sun.tools.javac.main.Option.*;
@@ -221,7 +224,7 @@
}
private void setDefaultForLocation(Location locn) {
- Collection<File> files = null;
+ Collection<Path> files = null;
if (locn instanceof StandardLocation) {
switch ((StandardLocation) locn) {
case CLASS_PATH:
@@ -235,12 +238,12 @@
break;
case CLASS_OUTPUT: {
String arg = options.get(D);
- files = (arg == null ? null : Collections.singleton(new File(arg)));
+ files = (arg == null ? null : Collections.singleton(Paths.get(arg)));
break;
}
case SOURCE_OUTPUT: {
String arg = options.get(S);
- files = (arg == null ? null : Collections.singleton(new File(arg)));
+ files = (arg == null ? null : Collections.singleton(Paths.get(arg)));
break;
}
}
@@ -248,8 +251,8 @@
PathsForLocation pl = new PathsForLocation();
if (files != null) {
- for (File f: files)
- pl.add(f.toPath());
+ for (Path f: files)
+ pl.add(f);
}
if (!pl.isEmpty())
pathsForLocation.put(locn, pl);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Dec 04 15:22:53 2014 -0800
@@ -145,6 +145,8 @@
this.names = fac.names;
this.source = fac.source;
this.allowTWR = source.allowTryWithResources();
+ this.allowEffectivelyFinalVariablesInTWR =
+ source.allowEffectivelyFinalVariablesInTryWithResources();
this.allowDiamond = source.allowDiamond();
this.allowMulticatch = source.allowMulticatch();
this.allowStringFolding = fac.options.getBoolean("allowStringFolding", true);
@@ -184,6 +186,10 @@
*/
boolean allowTWR;
+ /** Switch: should we allow (effectively) final variables as resources in try-with-resources?
+ */
+ boolean allowEffectivelyFinalVariablesInTWR;
+
/** Switch: should we fold strings?
*/
boolean allowStringFolding;
@@ -3003,14 +3009,28 @@
return defs.toList();
}
- /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
+ /** Resource = VariableModifiersOpt Type VariableDeclaratorId "=" Expression
+ * | Expression
*/
protected JCTree resource() {
- JCModifiers optFinal = optFinal(Flags.FINAL);
- JCExpression type = parseType();
- int pos = token.pos;
- Name ident = ident();
- return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
+ int startPos = token.pos;
+ if (token.kind == FINAL || token.kind == MONKEYS_AT) {
+ JCModifiers mods = optFinal(Flags.FINAL);
+ JCExpression t = parseType();
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ }
+ JCExpression t = term(EXPR | TYPE);
+ if ((lastmode & TYPE) != 0 && LAX_IDENTIFIER.accepts(token.kind)) {
+ JCModifiers mods = toP(F.at(startPos).Modifiers(Flags.FINAL));
+ return variableDeclaratorRest(token.pos, mods, t, ident(), true, null);
+ } else {
+ checkVariableInTryWithResources(startPos);
+ if (!t.hasTag(IDENT) && !t.hasTag(SELECT)) {
+ log.error(t.pos(), "try.with.resources.expr.needs.var");
+ }
+
+ return t;
+ }
}
/** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
@@ -3933,6 +3953,12 @@
allowTWR = true;
}
}
+ void checkVariableInTryWithResources(int startPos) {
+ if (!allowEffectivelyFinalVariablesInTWR) {
+ error(startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
+ allowEffectivelyFinalVariablesInTWR = true;
+ }
+ }
void checkLambda() {
if (!allowLambda) {
log.error(token.pos, "lambda.not.supported.in.source", source.name);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Dec 04 15:22:53 2014 -0800
@@ -252,6 +252,14 @@
compiler.err.cant.ref.non.effectively.final.var=\
local variables referenced from {1} must be final or effectively final
+compiler.err.try.with.resources.expr.needs.var=\
+ the try-with-resources resource must either be a variable declaration or an expression denoting \
+a reference to a final or effectively final variable
+
+# 0: symbol
+compiler.err.try.with.resources.expr.effectively.final.var=\
+ variable {0} used as a try-with-resources resource neither final nor effectively final
+
compiler.misc.lambda=\
a lambda expression
@@ -2262,6 +2270,11 @@
try-with-resources is not supported in -source {0}\n\
(use -source 7 or higher to enable try-with-resources)
+# 0: string
+compiler.err.var.in.try.with.resources.not.supported.in.source=\
+ variables in try-with-resources not supported in -source {0}\n\
+ (use -source 9 or higher to enable variables in try-with-resources)
+
compiler.warn.underscore.as.identifier=\
''_'' used as an identifier\n\
(use of ''_'' as an identifier might not be supported in releases after Java SE 8)
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -1526,7 +1526,7 @@
compiler.warn.override.unchecked.thrown={0}\n\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3055\u308C\u305F\u30E1\u30BD\u30C3\u30C9\u306F{1}\u3092\u30B9\u30ED\u30FC\u3057\u307E\u305B\u3093
# 0: symbol
-compiler.warn.override.equals.but.not.hashcode=\u30AF\u30E9\u30B9{0}\u306F\u7B49\u53F7\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059\u304C\u3001\u3053\u306E\u30AF\u30E9\u30B9\u3082\u30B9\u30FC\u30D1\u30FC\u30AF\u30E9\u30B9\u3082hashCode\u30E1\u30BD\u30C3\u30C9\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u305B\u3093
+compiler.warn.override.equals.but.not.hashcode=\u30AF\u30E9\u30B9{0}\u306Fequals\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u3059\u304C\u3001\u3053\u306E\u30AF\u30E9\u30B9\u3082\u3001\u307E\u305F\u3001\u3044\u304B\u306A\u308B\u30B9\u30FC\u30D1\u30FC\u30AF\u30E9\u30B9\u3082\u3001hashCode\u30E1\u30BD\u30C3\u30C9\u3092\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3057\u307E\u305B\u3093
## The following are all possible strings for the first argument ({0}) of the
## above strings.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -1526,7 +1526,7 @@
compiler.warn.override.unchecked.thrown={0}\n\u88AB\u8986\u76D6\u7684\u65B9\u6CD5\u672A\u629B\u51FA{1}
# 0: symbol
-compiler.warn.override.equals.but.not.hashcode=\u7C7B{0}\u8986\u76D6\u4E86\u7B49\u53F7, \u4F46\u8BE5\u7C7B\u6216\u4EFB\u4F55\u8D85\u7C7B\u90FD\u672A\u8986\u76D6 hashCode \u65B9\u6CD5
+compiler.warn.override.equals.but.not.hashcode=\u7C7B{0}\u8986\u76D6\u4E86 equals, \u4F46\u8BE5\u7C7B\u6216\u4EFB\u4F55\u8D85\u7C7B\u90FD\u672A\u8986\u76D6 hashCode \u65B9\u6CD5
## The following are all possible strings for the first argument ({0}) of the
## above strings.
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java Thu Dec 04 15:22:53 2014 -0800
@@ -612,6 +612,7 @@
public boolean staticImport;
/** The imported class(es). */
public JCTree qualid;
+ public com.sun.tools.javac.code.Scope importScope;
protected JCImport(JCTree qualid, boolean importStatic) {
this.qualid = qualid;
this.staticImport = importStatic;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/AbstractDiagnosticFormatter.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,7 @@
*/
package com.sun.tools.javac.util;
+import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.EnumSet;
@@ -48,6 +49,7 @@
import com.sun.tools.javac.jvm.Profile;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.Pretty;
+
import static com.sun.tools.javac.util.JCDiagnostic.DiagnosticType.*;
/**
@@ -186,7 +188,7 @@
else if (arg instanceof JCExpression) {
return expr2String((JCExpression)arg);
}
- else if (arg instanceof Iterable<?>) {
+ else if (arg instanceof Iterable<?> && !(arg instanceof Path)) {
return formatIterable(d, (Iterable<?>)arg, l);
}
else if (arg instanceof Type) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Dependencies.java Thu Dec 04 15:22:53 2014 -0800
@@ -73,7 +73,7 @@
return instance;
}
- Dependencies(Context context) {
+ protected Dependencies(Context context) {
context.put(dependenciesKey, this);
}
@@ -122,7 +122,7 @@
/**
* Push a new completion node on the stack.
*/
- abstract public void push(ClassSymbol s);
+ abstract public void push(ClassSymbol s, CompletionCause phase);
/**
* Push a new attribution node on the stack.
@@ -134,6 +134,15 @@
*/
abstract public void pop();
+ public enum CompletionCause {
+ CLASS_READER,
+ HEADER_PHASE,
+ HIERARCHY_PHASE,
+ IMPORTS_PHASE,
+ MEMBER_ENTER,
+ MEMBERS_PHASE;
+ }
+
/**
* This class creates a graph of all dependencies as symbols are completed;
* when compilation finishes, the resulting dependecy graph is then dumped
@@ -391,7 +400,7 @@
Map<String, Node> dependencyNodeMap = new LinkedHashMap<>();
@Override
- public void push(ClassSymbol s) {
+ public void push(ClassSymbol s, CompletionCause phase) {
Node n = new CompletionNode(s);
if (n == push(n)) {
s.completer = this;
@@ -454,7 +463,7 @@
@Override
public void complete(Symbol sym) throws CompletionFailure {
- push((ClassSymbol) sym);
+ push((ClassSymbol) sym, null);
pop();
sym.completer = this;
}
@@ -542,7 +551,7 @@
}
@Override
- public void push(ClassSymbol s) {
+ public void push(ClassSymbol s, CompletionCause phase) {
//do nothing
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java Thu Dec 04 15:22:53 2014 -0800
@@ -24,6 +24,7 @@
*/
package com.sun.tools.javac.util;
+import java.nio.file.Path;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
@@ -39,8 +40,8 @@
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.code.Types;
+import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.TypeTag.*;
-import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.util.LayoutCharacters.*;
@@ -186,7 +187,7 @@
else if (arg instanceof JCDiagnostic) {
preprocessDiagnostic((JCDiagnostic)arg);
}
- else if (arg instanceof Iterable<?>) {
+ else if (arg instanceof Iterable<?> && !(arg instanceof Path)) {
for (Object o : (Iterable<?>)arg) {
preprocessArgument(o);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/Gen.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/Gen.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 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,7 +25,6 @@
package com.sun.tools.javah;
-import java.io.UnsupportedEncodingException;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -33,6 +32,8 @@
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.nio.file.NoSuchFileException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -40,7 +41,6 @@
import java.util.Stack;
import javax.annotation.processing.ProcessingEnvironment;
-
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.TypeElement;
@@ -48,7 +48,6 @@
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
-
import javax.tools.FileObject;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -204,7 +203,7 @@
event = "[Overwriting file ";
}
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
mustWrite = true;
event = "[Creating file ";
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/JavahTask.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javah/JavahTask.java Thu Dec 04 15:22:53 2014 -0800
@@ -31,6 +31,7 @@
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
+import java.nio.file.NoSuchFileException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
@@ -50,7 +51,6 @@
import javax.annotation.processing.ProcessingEnvironment;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
-
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
@@ -62,7 +62,6 @@
import javax.lang.model.util.ElementFilter;
import javax.lang.model.util.SimpleTypeVisitor9;
import javax.lang.model.util.Types;
-
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
@@ -72,13 +71,15 @@
import javax.tools.StandardJavaFileManager;
import javax.tools.StandardLocation;
import javax.tools.ToolProvider;
-import static javax.tools.Diagnostic.Kind.*;
import com.sun.tools.javac.code.Symbol.CompletionFailure;
import com.sun.tools.javac.main.CommandLine;
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
+import static javax.tools.Diagnostic.Kind.*;
+
+
/**
* Javah generates support files for native methods.
* Parse commandline options and invokes javadoc to execute those commands.
@@ -420,7 +421,7 @@
List<String> l = new ArrayList<>();
for (String arg: args) l.add(arg);
return Arrays.asList(CommandLine.parse(l.toArray(new String[l.size()])));
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
throw new BadArgs("at.args.file.not.found", e.getLocalizedMessage());
} catch (IOException e) {
throw new BadArgs("at.args.io.exception", e.getLocalizedMessage());
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/JavapTask.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javap/JavapTask.java Thu Dec 04 15:22:53 2014 -0800
@@ -36,6 +36,10 @@
import java.io.StringWriter;
import java.io.Writer;
import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.file.NoSuchFileException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@@ -61,10 +65,6 @@
import javax.tools.StandardLocation;
import com.sun.tools.classfile.*;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLConnection;
-
import com.sun.tools.javac.util.DefinedBy;
import com.sun.tools.javac.util.DefinedBy.Api;
@@ -568,7 +568,7 @@
} catch (EOFException e) {
reportError("err.end.of.file", className);
result = EXIT_ERROR;
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
reportError("err.file.not.found", e.getLocalizedMessage());
result = EXIT_ERROR;
} catch (IOException e) {
@@ -668,9 +668,12 @@
if (fileManager instanceof StandardJavaFileManager) {
StandardJavaFileManager sfm = (StandardJavaFileManager) fileManager;
- fo = sfm.getJavaFileObjects(className).iterator().next();
- if (fo != null && fo.getLastModified() != 0) {
- return fo;
+ try {
+ fo = sfm.getJavaFileObjects(className).iterator().next();
+ if (fo != null && fo.getLastModified() != 0) {
+ return fo;
+ }
+ } catch (IllegalArgumentException ignore) {
}
}
@@ -860,11 +863,15 @@
}
private JavaFileObject getClassFileObject(String className) throws IOException {
- JavaFileObject fo;
- fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
- if (fo == null)
- fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
- return fo;
+ try {
+ JavaFileObject fo;
+ fo = fileManager.getJavaFileForInput(StandardLocation.PLATFORM_CLASS_PATH, className, JavaFileObject.Kind.CLASS);
+ if (fo == null)
+ fo = fileManager.getJavaFileForInput(StandardLocation.CLASS_PATH, className, JavaFileObject.Kind.CLASS);
+ return fo;
+ } catch (IllegalArgumentException e) {
+ return null;
+ }
}
private void showHelp() {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/JavacState.java Thu Dec 04 15:22:53 2014 -0800
@@ -26,16 +26,17 @@
package com.sun.tools.sjavac;
import java.io.*;
+import java.net.URI;
+import java.nio.file.NoSuchFileException;
+import java.text.SimpleDateFormat;
+import java.util.*;
import java.util.Collections;
import java.util.Date;
-import java.util.Set;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.HashMap;
-import java.text.SimpleDateFormat;
-import java.net.URI;
-import java.util.*;
+import java.util.Set;
import com.sun.tools.sjavac.options.Options;
import com.sun.tools.sjavac.server.Sjavac;
@@ -364,7 +365,7 @@
}
}
}
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
// Silently create a new javac_state file.
noFileFound = true;
} catch (IOException e) {
@@ -841,7 +842,7 @@
}
listedSources.add(l);
}
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
throw new ProblemException("Could not open "+makefileSourceList.getPath()+" since it does not exist!");
} catch (IOException e) {
throw new ProblemException("Could not read "+makefileSourceList.getPath());
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/sjavac/comp/SmartFileObject.java Thu Dec 04 15:22:53 2014 -0800
@@ -27,6 +27,8 @@
import java.io.*;
import java.net.URI;
+import java.nio.file.NoSuchFileException;
+
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.tools.JavaFileObject;
@@ -108,7 +110,7 @@
while (r.ready()) {
s.append(r.readLine()+lineseparator);
}
- } catch (FileNotFoundException e) {
+ } catch (FileNotFoundException | NoSuchFileException e) {
// Perfectly ok.
}
return new SmartWriter(file, s.toString(), file.getName(), stdout);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/lib/annotations/annotations/classfile/ClassfileInspector.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,1733 @@
+/*
+ * 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
+ * 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.
+ */
+
+package annotations.classfile;
+
+import java.io.*;
+import java.net.URL;
+import java.util.List;
+
+import com.sun.tools.classfile.*;
+
+/**
+ * A class providing utilities for writing tests that inspect class
+ * files directly, looking for specific type annotations.
+ *
+ * Note: this framework does not currently handle repeating
+ * annotations.
+ */
+public class ClassfileInspector {
+
+ /**
+ * A group of expected annotations to be found in a given class.
+ * If the class name is null, then the template will be applied to
+ * every class.
+ */
+ public static class Expected {
+ /**
+ * The name of the class. If {@code null} this template will
+ * apply to every class; otherwise, it will only be applied to
+ * the named class.
+ */
+ public final String classname;
+
+ /**
+ * The expected class annotations. These will be checked
+ * against the class' attributes.
+ */
+ public final ExpectedAnnotation[] classAnnos;
+
+ /**
+ * The expected method annotations. These will be checked
+ * against all methods in the class.
+ */
+ public final ExpectedMethodAnnotation[] methodAnnos;
+
+ /**
+ * The expected method parameter annotations. These will be checked
+ * against all methods in the class.
+ */
+ public final ExpectedParameterAnnotation[] methodParamAnnos;
+
+ /**
+ * The expected field type annotations. These will be checked
+ * against all fields in the class.
+ */
+ public final ExpectedFieldAnnotation[] fieldAnnos;
+
+ /**
+ * The expected class type annotations. These will be checked
+ * against the class' attributes.
+ */
+ public final ExpectedTypeAnnotation[] classTypeAnnos;
+
+ /**
+ * The expected method type annotations. These will be checked
+ * against all methods in the class.
+ */
+ public final ExpectedMethodTypeAnnotation[] methodTypeAnnos;
+
+ /**
+ * The expected field type annotations. These will be checked
+ * against all fields in the class.
+ */
+ public final ExpectedFieldTypeAnnotation[] fieldTypeAnnos;
+
+ /**
+ * Create an {@code Expected} from all components.
+ *
+ * @param classname The name of the class to match, or {@code
+ * null} for all classes.
+ * @param classAnnos The expected class annotations.
+ * @param methodAnnos The expected method annotations.
+ * @param methodParamAnnos The expected method parameter annotations.
+ * @param fieldAnnos The expected field annotations.
+ * @param classTypeAnnos The expected class type annotations.
+ * @param methodTypeAnnos The expected method type annotations.
+ * @param fieldTypeAnnos The expected field type annotations.
+ */
+ public Expected(String classname,
+ ExpectedAnnotation[] classAnnos,
+ ExpectedMethodAnnotation[] methodAnnos,
+ ExpectedParameterAnnotation[] methodParamAnnos,
+ ExpectedFieldAnnotation[] fieldAnnos,
+ ExpectedTypeAnnotation[] classTypeAnnos,
+ ExpectedMethodTypeAnnotation[] methodTypeAnnos,
+ ExpectedFieldTypeAnnotation[] fieldTypeAnnos) {
+ this.classname = classname;
+ this.classAnnos = classAnnos;
+ this.methodAnnos = methodAnnos;
+ this.methodParamAnnos = methodParamAnnos;
+ this.fieldAnnos = fieldAnnos;
+ this.classTypeAnnos = classTypeAnnos;
+ this.methodTypeAnnos = methodTypeAnnos;
+ this.fieldTypeAnnos = fieldTypeAnnos;
+ }
+
+ /**
+ * Create an {@code Expected} from regular annotation components.
+ *
+ * @param classname The name of the class to match, or {@code
+ * null} for all classes.
+ * @param classAnnos The expected class annotations.
+ * @param methodAnnos The expected method annotations.
+ * @param methodParamAnnos The expected method parameter annotations.
+ * @param fieldAnnos The expected field annotations.
+ */
+ public Expected(String classname,
+ ExpectedAnnotation[] classAnnos,
+ ExpectedMethodAnnotation[] methodAnnos,
+ ExpectedParameterAnnotation[] methodParamAnnos,
+ ExpectedFieldAnnotation[] fieldAnnos) {
+ this(classname, classAnnos, methodAnnos, methodParamAnnos,
+ fieldAnnos, null, null, null);
+ }
+
+ /**
+ * Create an {@code Expected} from type annotation components.
+ *
+ * @param classname The name of the class to match, or {@code
+ * null} for all classes.
+ * @param classTypeAnnos The expected class type annotations.
+ * @param methodTypeAnnos The expected method type annotations.
+ * @param fieldTypeAnnos The expected field type annotations.
+ */
+ public Expected(String classname,
+ ExpectedTypeAnnotation[] classTypeAnnos,
+ ExpectedMethodTypeAnnotation[] methodTypeAnnos,
+ ExpectedFieldTypeAnnotation[] fieldTypeAnnos) {
+ this(classname, null, null, null, null,
+ classTypeAnnos, methodTypeAnnos, fieldTypeAnnos);
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ final String newline = System.lineSeparator();
+ sb.append("Expected on class ").append(classname);
+ if (null != classAnnos) {
+ sb.append(newline).append("Class annotations:").append(newline);
+ for(ExpectedAnnotation anno : classAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != methodAnnos) {
+ sb.append(newline).append("Method annotations:").append(newline);
+ for(ExpectedAnnotation anno : methodAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != methodParamAnnos) {
+ sb.append(newline).append("Method param annotations:").append(newline);
+ for(ExpectedAnnotation anno : methodParamAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != fieldAnnos) {
+ sb.append(newline).append("Field annotations:").append(newline);
+ for(ExpectedAnnotation anno : fieldAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != classTypeAnnos) {
+ sb.append(newline).append("Class type annotations:").append(newline);
+ for(ExpectedAnnotation anno : classTypeAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != methodTypeAnnos) {
+ sb.append(newline).append("Method type annotations:").append(newline);
+ for(ExpectedAnnotation anno : methodTypeAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ if (null != fieldTypeAnnos) {
+ sb.append(newline).append("Field type annotations:").append(newline);
+ for(ExpectedAnnotation anno : fieldTypeAnnos) {
+ sb.append(anno).append(newline);
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a class.
+ *
+ * @param classname The classname to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchClassName(String classname) {
+ return this.classname == null || this.classname.equals(classname);
+ }
+
+ /**
+ * After applying the template to all classes, check to see if
+ * any of the expected annotations weren't matched.
+ *
+ * @return The number of missed matches.
+ */
+ public int check() {
+ int count = 0;
+ if (classAnnos != null) {
+ for(ExpectedAnnotation expected : classAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (methodAnnos != null) {
+ for(ExpectedAnnotation expected : methodAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (methodParamAnnos != null) {
+ for(ExpectedAnnotation expected : methodParamAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (fieldAnnos != null) {
+ for(ExpectedAnnotation expected : fieldAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (classTypeAnnos != null) {
+ for(ExpectedAnnotation expected : classTypeAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (methodTypeAnnos != null) {
+ for(ExpectedAnnotation expected : methodTypeAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ if (fieldTypeAnnos != null) {
+ for(ExpectedAnnotation expected : fieldTypeAnnos) {
+ if (!expected.check()) {
+ count++;
+ }
+ }
+ }
+ return count;
+ }
+ }
+
+ /**
+ * An expected annotation. This is both a superclass for
+ * method, field, and type annotations, as well as a class for
+ * annotations on a class.
+ */
+ public static class ExpectedAnnotation {
+ protected int count = 0;
+ protected final String expectedName;
+ protected final int expectedCount;
+ protected final boolean visibility;
+
+ /**
+ * Create an {@code ExpectedAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should
+ * be seen. If 0, this asserts that the
+ * described annotation is not present.
+ */
+ public ExpectedAnnotation(String expectedName,
+ boolean visibility,
+ int expectedCount) {
+ this.expectedName = expectedName;
+ this.visibility = visibility;
+ this.expectedCount = expectedCount;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ return sb.toString();
+ }
+
+ /**
+ * See if this template matches the given visibility.
+ *
+ * @param Whether or not the annotation is visible at runtime.
+ * @return Whether or not this template matches the visibility.
+ */
+ public boolean matchVisibility(boolean visibility) {
+ return this.visibility == visibility;
+ }
+
+ /**
+ * Attempty to match this template against an annotation. If
+ * it does match, then the match count for the template will
+ * be incremented. Otherwise, nothing will be done.
+ *
+ * @param anno The annotation to attempt to match.
+ */
+ public void matchAnnotation(ConstantPool cpool,
+ Annotation anno) {
+ if (checkMatch(cpool, anno)) {
+ count++;
+ }
+ }
+
+ /**
+ * Indicate whether an annotation matches this expected
+ * annotation.
+ *
+ * @param ConstantPool The constant pool to use.
+ * @param anno The annotation to check.
+ * @return Whether the annotation matches.
+ */
+ protected boolean checkMatch(ConstantPool cpool,
+ Annotation anno) {
+ try {
+ return cpool.getUTF8Info(anno.type_index).value.equals("L" + expectedName + ";");
+ } catch(Exception e) {
+ return false;
+ }
+ }
+
+ /**
+ * After all matching, check to see if the expected number of
+ * matches equals the actual number. If not, then print a
+ * failure message and return {@code false}.
+ *
+ * @return Whether or not the expected number of matched
+ * equals the actual number.
+ */
+ public boolean check() {
+ if (count != expectedCount) {
+ System.err.println(this + ", but saw " + count);
+ return false;
+ } else {
+ return true;
+ }
+ }
+ }
+
+ /**
+ * An annotation found on a method.
+ */
+ public static class ExpectedMethodAnnotation extends ExpectedAnnotation {
+ protected final String methodname;
+
+ /**
+ * Create an {@code ExpectedMethodAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param methodname The expected method name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public ExpectedMethodAnnotation(String methodname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, visibility, expectedCount);
+ this.methodname = methodname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(" on method ");
+ sb.append(methodname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a method.
+ *
+ * @param methodname The method name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchMethodName(String methodname) {
+ return this.methodname.equals(methodname);
+ }
+
+ }
+
+ /**
+ * An annotation found on a method parameter.
+ */
+ public static class ExpectedParameterAnnotation
+ extends ExpectedMethodAnnotation {
+ protected final int index;
+
+ /**
+ * Create an {@code ExpectedParameterAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param methodname The expected method name.
+ * @param index The parameter index.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public ExpectedParameterAnnotation(String methodname,
+ int index,
+ String expectedName,
+ boolean visibility,
+ int expectedCount) {
+ super(methodname, expectedName, visibility, expectedCount);
+ this.index = index;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(" on method ");
+ sb.append(methodname);
+ sb.append(" parameter " + index);
+ return sb.toString();
+ }
+
+ }
+
+ /**
+ * An annotation found on a field.
+ */
+ public static class ExpectedFieldAnnotation extends ExpectedAnnotation {
+ private final String fieldname;
+
+ /**
+ * Create an {@code ExpectedFieldAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param fieldname The expected field name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public ExpectedFieldAnnotation(String fieldname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, visibility, expectedCount);
+ this.fieldname = fieldname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ").append(expectedCount)
+ .append(" annotation ").append(expectedName)
+ .append(visibility ? ", runtime visibile " : ", runtime invisibile ")
+ .append(" on field ").append(fieldname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a field.
+ *
+ * @param fieldname The field name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchFieldName(String fieldname) {
+ return this.fieldname.equals(fieldname);
+ }
+
+ }
+
+ /**
+ * An expected type annotation. This is both a superclass for
+ * method and field type annotations, as well as a class for type
+ * annotations on a class.
+ */
+ public static class ExpectedTypeAnnotation extends ExpectedAnnotation {
+ protected final TypeAnnotation.TargetType targetType;
+ protected final int bound_index;
+ protected final int parameter_index;
+ protected final int type_index;
+ protected final int exception_index;
+ protected final TypeAnnotation.Position.TypePathEntry[] typePath;
+
+ /**
+ * Create an {@code ExpectedTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should
+ * be seen. If 0, this asserts that the
+ * described annotation is not present.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedTypeAnnotation(String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ super(expectedName, visibility, expectedCount);
+ this.targetType = targetType;
+ this.bound_index = bound_index;
+ this.parameter_index = parameter_index;
+ this.type_index = type_index;
+ this.exception_index = exception_index;
+ this.typePath = typePath;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(targetType);
+ sb.append(", bound_index = ");
+ sb.append(bound_index);
+ sb.append(", parameter_index = ");
+ sb.append(parameter_index);
+ sb.append(", type_index = ");
+ sb.append(type_index);
+ sb.append(", exception_index = ");
+ sb.append(exception_index);
+ sb.append(", type_path = [");
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ @Override
+ public void matchAnnotation(ConstantPool cpool,
+ Annotation anno) {}
+
+ public void matchAnnotation(TypeAnnotation anno) {
+ if (checkMatch(anno)) {
+ count++;
+ }
+ }
+
+ public boolean checkMatch(TypeAnnotation anno) {
+ boolean matches = checkMatch(anno.constant_pool, anno.annotation);
+
+ matches = matches && anno.position.type == targetType;
+ matches = matches && anno.position.bound_index == bound_index;
+ matches = matches && anno.position.parameter_index == parameter_index;
+ matches = matches && anno.position.type_index == type_index;
+ matches = matches && anno.position.exception_index == exception_index;
+ matches = matches && anno.position.location.size() == typePath.length;
+
+ if (matches) {
+ int i = 0;
+ for(TypeAnnotation.Position.TypePathEntry entry :
+ anno.position.location) {
+ matches = matches && typePath[i++].equals(entry);
+ }
+ }
+
+ return matches;
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder {
+ protected final String expectedName;
+ protected final boolean visibility;
+ protected final int expectedCount;
+ protected final TypeAnnotation.TargetType targetType;
+ protected int bound_index = Integer.MIN_VALUE;
+ protected int parameter_index = Integer.MIN_VALUE;
+ protected int type_index = Integer.MIN_VALUE;
+ protected int exception_index = Integer.MIN_VALUE;
+ protected TypeAnnotation.Position.TypePathEntry[] typePath =
+ new TypeAnnotation.Position.TypePathEntry[0];
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ this.expectedName = expectedName;
+ this.visibility = visibility;
+ this.expectedCount = expectedCount;
+ this.targetType = targetType;
+ }
+
+ /**
+ * Create an {@code ExpectedTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedTypeAnnotation}.
+ */
+ public ExpectedTypeAnnotation build() {
+ return new ExpectedTypeAnnotation(expectedName, visibility,
+ expectedCount, targetType,
+ bound_index, parameter_index,
+ type_index, exception_index,
+ typePath);
+ }
+
+ /**
+ * Provide a bound index parameter.
+ *
+ * @param bound_index The bound_index value.
+ */
+ public Builder setBoundIndex(int bound_index) {
+ this.bound_index = bound_index;
+ return this;
+ }
+
+ /**
+ * Provide a parameter index parameter.
+ *
+ * @param bound_index The parameter_index value.
+ */
+ public Builder setParameterIndex(int parameter_index) {
+ this.parameter_index = parameter_index;
+ return this;
+ }
+
+ /**
+ * Provide a type index parameter.
+ *
+ * @param type_index The type_index value.
+ */
+ public Builder setTypeIndex(int type_index) {
+ this.type_index = type_index;
+ return this;
+ }
+
+ /**
+ * Provide an exception index parameter.
+ *
+ * @param exception_index The exception_index value.
+ */
+ public Builder setExceptionIndex(int exception_index) {
+ this.exception_index = exception_index;
+ return this;
+ }
+
+ /**
+ * Provide a type path parameter.
+ *
+ * @param typePath The type path value.
+ */
+ public Builder setTypePath(TypeAnnotation.Position.TypePathEntry[] typePath) {
+ this.typePath = typePath;
+ return this;
+ }
+ }
+ }
+
+ /**
+ * A type annotation found on a method.
+ */
+ public static class ExpectedMethodTypeAnnotation extends ExpectedTypeAnnotation {
+ private final String methodname;
+
+ /**
+ * Create an {@code ExpectedMethodTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param methodname The expected method name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedMethodTypeAnnotation(String methodname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ super(expectedName, visibility, expectedCount, targetType, bound_index,
+ parameter_index, type_index, exception_index, typePath);
+ this.methodname = methodname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ");
+ sb.append(expectedCount);
+ sb.append(" annotation ");
+ sb.append(expectedName);
+ sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
+ sb.append(targetType);
+ sb.append(", bound_index = ");
+ sb.append(bound_index);
+ sb.append(", parameter_index = ");
+ sb.append(parameter_index);
+ sb.append(", type_index = ");
+ sb.append(type_index);
+ sb.append(", exception_index = ");
+ sb.append(exception_index);
+ sb.append(", type_path = [");
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]");
+ sb.append(" on method ");
+ sb.append(methodname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a method.
+ *
+ * @param methodname The method name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchMethodName(String methodname) {
+ return this.methodname.equals(methodname);
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedMethodTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedMethodTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedMethodTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder extends ExpectedTypeAnnotation.Builder {
+ protected final String methodname;
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param methodname The expected method name.
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String methodname,
+ String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, targetType, visibility, expectedCount);
+ this.methodname = methodname;
+ }
+
+ /**
+ * Create an {@code ExpectedMethodTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedMethodTypeAnnotation}.
+ */
+ public ExpectedMethodTypeAnnotation build() {
+ return new ExpectedMethodTypeAnnotation(methodname, expectedName,
+ visibility, expectedCount,
+ targetType, bound_index,
+ parameter_index, type_index,
+ exception_index, typePath);
+ }
+ }
+ }
+
+ /**
+ * A type annotation found on a field.
+ */
+ public static class ExpectedFieldTypeAnnotation extends ExpectedTypeAnnotation {
+ private final String fieldname;
+
+ /**
+ * Create an {@code ExpectedFieldTypeAnnotation} from its
+ * components. It is usually a better idea to use a {@code
+ * Builder} to do this.
+ *
+ * @param fieldname The expected field name.
+ * @param expectedName The expected annotation name.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ * @param targetType The expected target type.
+ * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
+ * @param parameter_index The expected parameter index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
+ * @param exception_index The expected exception index, or
+ * {@code Integer.MIN_VALUE}.
+ * @param typePath The expected type path.
+ */
+ public ExpectedFieldTypeAnnotation(String fieldname,
+ String expectedName,
+ boolean visibility,
+ int expectedCount,
+ TypeAnnotation.TargetType targetType,
+ int bound_index,
+ int parameter_index,
+ int type_index,
+ int exception_index,
+ TypeAnnotation.Position.TypePathEntry... typePath) {
+ super(expectedName, visibility, expectedCount, targetType, bound_index,
+ parameter_index, type_index, exception_index, typePath);
+ this.fieldname = fieldname;
+ }
+
+ public String toString() {
+ final StringBuilder sb = new StringBuilder();
+ sb.append("Expected ").append(expectedCount)
+ .append(" annotation ").append(expectedName)
+ .append(visibility ? ", runtime visibile " : ", runtime invisibile ")
+ .append(targetType)
+ .append(", bound_index = ").append(bound_index)
+ .append(", parameter_index = ").append(parameter_index)
+ .append(", type_index = ").append(type_index)
+ .append(", exception_index = ").append(exception_index)
+ .append(", type_path = [");
+
+ for(int i = 0; i < typePath.length; i++) {
+ if (i != 0) {
+ sb.append(", ");
+ }
+ sb.append(typePath[i]);
+ }
+ sb.append("]")
+ .append(" on field ").append(fieldname);
+ return sb.toString();
+ }
+
+ /**
+ * See if this template applies to a field.
+ *
+ * @param fieldname The field name to check.
+ * @return Whether or not this template should apply.
+ */
+ public boolean matchFieldName(String fieldname) {
+ return this.fieldname.equals(fieldname);
+ }
+
+ /**
+ * A builder class for creating {@code
+ * ExpectedFieldTypeAnnotation}s in a more convenient fashion. The
+ * constructor for {@code ExpectedFieldTypeAnnotation} takes a
+ * large number of parameters (by necessity). This class
+ * allows users to construct a {@code ExpectedFieldTypeAnnotation}s
+ * using only the ones they need.
+ */
+ public static class Builder extends ExpectedTypeAnnotation.Builder {
+ protected final String fieldname;
+
+ /**
+ * Create a {@code Builder} from the mandatory parameters.
+ *
+ * @param fieldname The expected field name.
+ * @param expectedName The expected annotation name.
+ * @param targetType The expected target type.
+ * @param visibility Whether this annotation should be runtime-visible.
+ * @param expectedCount The number of annotations that should be seen.
+ */
+ public Builder(String fieldname,
+ String expectedName,
+ TypeAnnotation.TargetType targetType,
+ boolean visibility,
+ int expectedCount) {
+ super(expectedName, targetType, visibility, expectedCount);
+ this.fieldname = fieldname;
+ }
+
+ /**
+ * Create an {@code ExpectedFieldTypeAnnotation} from all
+ * parameters that have been provided. The default values
+ * will be used for those that have not.
+ *
+ * @return The cretaed {@code ExpectedFieldTypeAnnotation}.
+ */
+ public ExpectedFieldTypeAnnotation build() {
+ return new ExpectedFieldTypeAnnotation(fieldname, expectedName,
+ visibility, expectedCount,
+ targetType, bound_index,
+ parameter_index, type_index,
+ exception_index, typePath);
+ }
+ }
+ }
+
+ private void matchClassAnnotation(ClassFile classfile,
+ ExpectedAnnotation expected)
+ throws ConstantPoolException {
+ for(Attribute attr : classfile.attributes) {
+ attr.accept(annoMatcher(classfile.constant_pool), expected);
+ }
+ }
+
+ private void matchMethodAnnotation(ClassFile classfile,
+ ExpectedMethodAnnotation expected)
+ throws ConstantPoolException {
+ for(Method meth : classfile.methods) {
+ if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
+ for(Attribute attr : meth.attributes) {
+ attr.accept(annoMatcher(classfile.constant_pool), expected);
+ }
+ }
+ }
+ }
+
+ private void matchParameterAnnotation(ClassFile classfile,
+ ExpectedParameterAnnotation expected)
+ throws ConstantPoolException {
+ for(Method meth : classfile.methods) {
+ if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
+ for(Attribute attr : meth.attributes) {
+ attr.accept(paramMatcher(classfile.constant_pool), expected);
+ }
+ }
+ }
+ }
+
+ private void matchFieldAnnotation(ClassFile classfile,
+ ExpectedFieldAnnotation expected)
+ throws ConstantPoolException {
+ for(Field field : classfile.fields) {
+ if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
+ for(Attribute attr : field.attributes) {
+ attr.accept(annoMatcher(classfile.constant_pool), expected);
+ }
+ }
+ }
+ }
+
+ private void matchClassTypeAnnotation(ClassFile classfile,
+ ExpectedTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Attribute attr : classfile.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+
+ private void matchMethodTypeAnnotation(ClassFile classfile,
+ ExpectedMethodTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Method meth : classfile.methods) {
+ if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
+ for(Attribute attr : meth.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+ }
+ }
+
+ private void matchFieldTypeAnnotation(ClassFile classfile,
+ ExpectedFieldTypeAnnotation expected)
+ throws ConstantPoolException {
+ for(Field field : classfile.fields) {
+ if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
+ for(Attribute attr : field.attributes) {
+ attr.accept(typeAnnoMatcher, expected);
+ }
+ }
+ }
+ }
+
+ private void matchClassAnnotations(ClassFile classfile,
+ ExpectedAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedAnnotation one : expected) {
+ matchClassAnnotation(classfile, one);
+ }
+ }
+
+ private void matchMethodAnnotations(ClassFile classfile,
+ ExpectedMethodAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedMethodAnnotation one : expected) {
+ matchMethodAnnotation(classfile, one);
+ }
+ }
+
+ private void matchParameterAnnotations(ClassFile classfile,
+ ExpectedParameterAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedParameterAnnotation one : expected) {
+ matchParameterAnnotation(classfile, one);
+ }
+ }
+
+ private void matchFieldAnnotations(ClassFile classfile,
+ ExpectedFieldAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedFieldAnnotation one : expected) {
+ matchFieldAnnotation(classfile, one);
+ }
+ }
+
+ private void matchClassTypeAnnotations(ClassFile classfile,
+ ExpectedTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedTypeAnnotation one : expected) {
+ matchClassTypeAnnotation(classfile, one);
+ }
+ }
+
+ private void matchMethodTypeAnnotations(ClassFile classfile,
+ ExpectedMethodTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedMethodTypeAnnotation one : expected) {
+ matchMethodTypeAnnotation(classfile, one);
+ }
+ }
+
+ private void matchFieldTypeAnnotations(ClassFile classfile,
+ ExpectedFieldTypeAnnotation[] expected)
+ throws ConstantPoolException {
+ for(ExpectedFieldTypeAnnotation one : expected) {
+ matchFieldTypeAnnotation(classfile, one);
+ }
+ }
+
+ /**
+ * Run a template on a single {@code ClassFile}.
+ *
+ * @param classfile The {@code ClassFile} on which to run tests.
+ * @param expected The expected annotation template.
+ */
+ public void run(ClassFile classfile,
+ Expected... expected)
+ throws ConstantPoolException {
+ run(new ClassFile[] { classfile }, expected);
+ }
+
+ /**
+ * Run a template on multiple {@code ClassFile}s.
+ *
+ * @param classfile The {@code ClassFile}s on which to run tests.
+ * @param expected The expected annotation template.
+ */
+ public void run(ClassFile[] classfiles,
+ Expected... expected)
+ throws ConstantPoolException {
+ for(ClassFile classfile : classfiles) {
+ for(Expected one : expected) {
+ if (one.matchClassName(classfile.getName())) {
+ if (one.classAnnos != null)
+ matchClassAnnotations(classfile, one.classAnnos);
+ if (one.methodAnnos != null)
+ matchMethodAnnotations(classfile, one.methodAnnos);
+ if (one.methodParamAnnos != null)
+ matchParameterAnnotations(classfile, one.methodParamAnnos);
+ if (one.fieldAnnos != null)
+ matchFieldAnnotations(classfile, one.fieldAnnos);
+ if (one.classTypeAnnos != null)
+ matchClassTypeAnnotations(classfile, one.classTypeAnnos);
+ if (one.methodTypeAnnos != null)
+ matchMethodTypeAnnotations(classfile, one.methodTypeAnnos);
+ if (one.fieldTypeAnnos != null)
+ matchFieldTypeAnnotations(classfile, one.fieldTypeAnnos);
+ }
+ }
+ }
+ int count = 0;
+ for (Expected one : expected) {
+ count += one.check();
+ }
+
+ if (count != 0) {
+ throw new RuntimeException(count + " errors occurred in test");
+ }
+ }
+
+ /**
+ * Get a {@code ClassFile} from its file name.
+ *
+ * @param name The class' file name.
+ * @param host A class in the same package.
+ * @return The {@code ClassFile}
+ */
+ public static ClassFile getClassFile(String name,
+ Class<?> host)
+ throws IOException, ConstantPoolException {
+ final URL url = host.getResource(name);
+ final InputStream in = url.openStream();
+ try {
+ return ClassFile.read(in);
+ } finally {
+ in.close();
+ }
+ }
+
+ private static final Attribute.Visitor<Void, ExpectedTypeAnnotation> typeAnnoMatcher =
+ new Attribute.Visitor<Void, ExpectedTypeAnnotation>() {
+
+ @Override
+ public Void visitBootstrapMethods(BootstrapMethods_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDefault(DefaultAttribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitAnnotationDefault(AnnotationDefault_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCode(Code_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCompilationID(CompilationID_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitConstantValue(ConstantValue_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDeprecated(Deprecated_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitEnclosingMethod(EnclosingMethod_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitExceptions(Exceptions_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitInnerClasses(InnerClasses_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLineNumberTable(LineNumberTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTable(LocalVariableTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitMethodParameters(MethodParameters_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSignature(Signature_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceFile(SourceFile_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceID(SourceID_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMap(StackMap_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMapTable(StackMapTable_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSynthetic(Synthetic_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ if (expected.matchVisibility(true)) {
+ for(TypeAnnotation anno : attr.annotations) {
+ expected.matchAnnotation(anno);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
+ ExpectedTypeAnnotation expected) {
+ if (expected.matchVisibility(false)) {
+ for(TypeAnnotation anno : attr.annotations) {
+ expected.matchAnnotation(anno);
+ }
+ }
+
+ return null;
+ }
+ };
+
+ private static Attribute.Visitor<Void, ExpectedAnnotation> annoMatcher(ConstantPool cpool) {
+ return new Attribute.Visitor<Void, ExpectedAnnotation>() {
+
+ @Override
+ public Void visitBootstrapMethods(BootstrapMethods_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDefault(DefaultAttribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitAnnotationDefault(AnnotationDefault_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCode(Code_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCompilationID(CompilationID_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitConstantValue(ConstantValue_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDeprecated(Deprecated_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitEnclosingMethod(EnclosingMethod_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitExceptions(Exceptions_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitInnerClasses(InnerClasses_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLineNumberTable(LineNumberTable_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTable(LocalVariableTable_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitMethodParameters(MethodParameters_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSignature(Signature_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceFile(SourceFile_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceID(SourceID_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMap(StackMap_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMapTable(StackMapTable_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSynthetic(Synthetic_attribute attr,
+ ExpectedAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ if (expected.matchVisibility(true)) {
+ for(Annotation anno : attr.annotations) {
+ expected.matchAnnotation(cpool, anno);
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
+ ExpectedAnnotation expected) {
+ if (expected.matchVisibility(false)) {
+ for(Annotation anno : attr.annotations) {
+ expected.matchAnnotation(cpool, anno);
+ }
+ }
+
+ return null;
+ }
+ };
+ }
+
+ private static Attribute.Visitor<Void, ExpectedParameterAnnotation> paramMatcher(ConstantPool cpool) {
+ return new Attribute.Visitor<Void, ExpectedParameterAnnotation>() {
+
+ @Override
+ public Void visitBootstrapMethods(BootstrapMethods_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDefault(DefaultAttribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitAnnotationDefault(AnnotationDefault_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCode(Code_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitCompilationID(CompilationID_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitConstantValue(ConstantValue_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitDeprecated(Deprecated_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitEnclosingMethod(EnclosingMethod_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitExceptions(Exceptions_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitInnerClasses(InnerClasses_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLineNumberTable(LineNumberTable_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTable(LocalVariableTable_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitMethodParameters(MethodParameters_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSignature(Signature_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceFile(SourceFile_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSourceID(SourceID_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMap(StackMap_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitStackMapTable(StackMapTable_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitSynthetic(Synthetic_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ if (expected.matchVisibility(true)) {
+ if (expected.index < attr.parameter_annotations.length) {
+ for(Annotation anno :
+ attr.parameter_annotations[expected.index]) {
+ expected.matchAnnotation(cpool, anno);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
+ ExpectedParameterAnnotation expected) {
+ if (expected.matchVisibility(false)) {
+ if (expected.index < attr.parameter_annotations.length) {
+ for(Annotation anno :
+ attr.parameter_annotations[expected.index]) {
+ expected.matchAnnotation(cpool, anno);
+ }
+ }
+ }
+
+ return null;
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4980495/std/NonStatic2StaticImportClash.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7101822
+ * @summary Check the when clashing types are imported through an ordinary and static import,
+ * the compile-time error is properly reported.
+ * @compile/fail/ref=NonStatic2StaticImportClash.out -XDrawDiagnostics NonStatic2StaticImportClash.java p1/A1.java p2/A2.java
+ *
+ */
+
+import p1.A1.f;
+import static p2.A2.f;
+
+public class NonStatic2StaticImportClash {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4980495/std/NonStatic2StaticImportClash.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,2 @@
+NonStatic2StaticImportClash.java:11:1: compiler.err.already.defined.static.single.import: p1.A1.f
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4980495/std/Static2NonStaticImportClash.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7101822
+ * @summary Check the when clashing types are imported through an ordinary and static import,
+ * the compile-time error is properly reported.
+ * @compile/fail/ref=Static2NonStaticImportClash.out -XDrawDiagnostics Static2NonStaticImportClash.java p1/A1.java p2/A2.java
+ *
+ */
+
+import static p2.A2.f;
+import p1.A1.f;
+
+public class Static2NonStaticImportClash {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/4980495/std/Static2NonStaticImportClash.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,2 @@
+Static2NonStaticImportClash.java:11:1: compiler.err.already.defined.single.import: p2.A2.f
+1 error
--- a/langtools/test/tools/javac/4980495/std/Test.out Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/4980495/std/Test.out Thu Dec 04 15:22:53 2014 -0800
@@ -1,2 +1,3 @@
Test.java:11:1: compiler.err.already.defined.single.import: p1.A1.f
-1 error
+Test.java:16:13: compiler.err.ref.ambiguous: f, kindname.class, p1.A1.f, p1.A1, kindname.class, p2.A2.f, p2.A2
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8062359
+ * @summary NullPointerException in Attr when type-annotating an anonymous
+ * inner class in an unresolvable class
+ * @compile/fail/ref=UnresolvableClassNPEInAttrTest.out -XDrawDiagnostics UnresolvableClassNPEInAttrTest.java
+ */
+
+public class UnresolvableClassNPEInAttrTest {
+ public static void main(String[] args) {
+ new Undefined() {
+ void test() {
+ new Object() {};
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8062359/UnresolvableClassNPEInAttrTest.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,2 @@
+UnresolvableClassNPEInAttrTest.java:11:13: compiler.err.cant.resolve.location: kindname.class, Undefined, , , (compiler.misc.location: kindname.class, UnresolvableClassNPEInAttrTest, null)
+1 error
--- a/langtools/test/tools/javac/T6181889/EmptyFinallyTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/T6181889/EmptyFinallyTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,8 +1,3 @@
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.file.Paths;
-
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -32,6 +27,10 @@
* @summary Empty try/finally results in bytecodes being generated
*/
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
public class EmptyFinallyTest {
private static final String assertionErrorMsg =
"No \"Exception table\" should be generated in this case";
--- a/langtools/test/tools/javac/T6725036.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/T6725036.java Thu Dec 04 15:22:53 2014 -0800
@@ -60,7 +60,7 @@
long jarEntryTime = je.getTime();
ZipFileIndexCache zfic = ZipFileIndexCache.getSharedInstance();
- ZipFileIndex zfi = zfic.getZipFileIndex(testJar, null, false, null, false);
+ ZipFileIndex zfi = zfic.getZipFileIndex(testJar.toPath(), null, false, null, false);
long zfiTime = zfi.getLastModified(TEST_ENTRY_NAME);
check(je, jarEntryTime, zfi + ":" + TEST_ENTRY_NAME.getPath(), zfiTime);
@@ -85,7 +85,7 @@
try (JavaFileManager fm = comp.getStandardFileManager(null, null, null)) {
File f = new File(name);
ToolBox tb = new ToolBox();
- tb.new JarTask(f.getPath())
+ tb.new JarTask(name)
.files(fm, StandardLocation.PLATFORM_CLASS_PATH, paths)
.run();
return f;
--- a/langtools/test/tools/javac/T8020997/CannotCompileRepeatedAnnoTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/T8020997/CannotCompileRepeatedAnnoTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,31 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8059921
+ * @summary Missing compile error in Java 8 mode for Interface.super.field access
+ * @compile/fail/ref=ForbidAccessToFieldUsingSuperTest.out -XDrawDiagnostics ForbidAccessToFieldUsingSuperTest.java
+ */
+
+public class ForbidAccessToFieldUsingSuperTest {
+ class C {
+ int m() { return 0; }
+ }
+
+ interface T {
+ int f = 0;
+ C c = null;
+ default int mm() {
+ return 0;
+ }
+ }
+
+ interface T1 extends T {}
+
+ class X implements T1 {
+ int i = T1.super.f; //fail
+ int j = T1.super.c.m(); //fail
+
+ void foo(Runnable r) {
+ foo(T1.super::mm); //should'n fail
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8059921/ForbidAccessToFieldUsingSuperTest.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,3 @@
+ForbidAccessToFieldUsingSuperTest.java:24:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1
+ForbidAccessToFieldUsingSuperTest.java:25:19: compiler.err.not.encl.class: ForbidAccessToFieldUsingSuperTest.T1
+2 errors
--- a/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/BadTwrSyntax.out Thu Dec 04 15:22:53 2014 -0800
@@ -1,2 +1,2 @@
-BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.type
+BadTwrSyntax.java:14:43: compiler.err.illegal.start.of.expr
1 error
--- a/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.java Thu Dec 04 15:22:53 2014 -0800
@@ -13,6 +13,11 @@
String test1() {
try (tr1 = new ResDeclOutsideTry(); tr2;) {
}
+ return null;
+ }
+
+ @Override
+ public void close() throws Exception {
}
}
--- a/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.out Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/TryWithResources/ResDeclOutsideTry.out Thu Dec 04 15:22:53 2014 -0800
@@ -1,3 +1,2 @@
-ResDeclOutsideTry.java:14:17: compiler.err.expected: token.identifier
-ResDeclOutsideTry.java:14:48: compiler.err.expected: token.identifier
-2 errors
+ResDeclOutsideTry.java:14:18: compiler.err.try.with.resources.expr.needs.var
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable1.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,69 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that variables can be used as operands to try-with-resources
+ * @compile/fail/ref=TwrForVariable1.out -source 8 -XDrawDiagnostics -Xlint:-options TwrForVariable1.java
+ * @compile TwrForVariable1.java
+ * @run main TwrForVariable1
+ */
+public class TwrForVariable1 implements AutoCloseable {
+ private static int closeCount = 0;
+ public static void main(String... args) {
+ TwrForVariable1 v = new TwrForVariable1();
+
+ try (v) {
+ assertCloseCount(0);
+ }
+ try (/**@deprecated*/v) {
+ assertCloseCount(1);
+ }
+ try (v.finalWrapper.finalField) {
+ assertCloseCount(2);
+ } catch (Exception ex) {
+ }
+ try (new TwrForVariable1() { }.finalWrapper.finalField) {
+ assertCloseCount(3);
+ } catch (Exception ex) {
+ }
+ try ((args.length > 0 ? v : new TwrForVariable1()).finalWrapper.finalField) {
+ assertCloseCount(4);
+ } catch (Exception ex) {
+ }
+ try {
+ throw new CloseableException();
+ } catch (CloseableException ex) {
+ try (ex) {
+ assertCloseCount(5);
+ }
+ }
+
+ assertCloseCount(6);
+ }
+
+ static void assertCloseCount(int expectedCloseCount) {
+ if (closeCount != expectedCloseCount)
+ throw new RuntimeException("bad closeCount: " + closeCount +
+ "; expected: " + expectedCloseCount);
+ }
+
+ public void close() {
+ closeCount++;
+ }
+
+ final FinalWrapper finalWrapper = new FinalWrapper();
+
+ static class FinalWrapper {
+ public final AutoCloseable finalField = new AutoCloseable() {
+ @Override
+ public void close() throws Exception {
+ closeCount++;
+ }
+ };
+ }
+
+ static class CloseableException extends Exception implements AutoCloseable {
+ @Override
+ public void close() {
+ closeCount++;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable1.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,2 @@
+TwrForVariable1.java:13:14: compiler.err.var.in.try.with.resources.not.supported.in.source: 1.8
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,39 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that an improper combination of modifiers and variable is rejected
+ * in an operand to try-with-resources
+ * @compile/fail/ref=TwrForVariable2.out -XDrawDiagnostics -Xlint:-options TwrForVariable2.java
+ */
+public class TwrForVariable2 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable2 v = new TwrForVariable2();
+ TwrForVariable3[] v2 = new TwrForVariable3[1];
+
+ try (final v) {
+ fail("no modifiers before variables");
+ }
+ try (@Deprecated v) {
+ fail("no annotations before variables");
+ }
+ try (v;;) {
+ fail("illegal double semicolon");
+ }
+ try ((v)) {
+ fail("parentheses not allowed");
+ }
+ try (v2[0]) {
+ fail("array access not allowed");
+ }
+ try (args.length == 0 ? v : v) {
+ fail("general expressions not allowed");
+ }
+ }
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable2.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,7 @@
+TwrForVariable2.java:12:21: compiler.err.expected: token.identifier
+TwrForVariable2.java:15:27: compiler.err.expected: token.identifier
+TwrForVariable2.java:18:16: compiler.err.illegal.start.of.expr
+TwrForVariable2.java:21:14: compiler.err.try.with.resources.expr.needs.var
+TwrForVariable2.java:24:16: compiler.err.try.with.resources.expr.needs.var
+TwrForVariable2.java:27:31: compiler.err.try.with.resources.expr.needs.var
+6 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,29 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that improper expressions used as an operand to try-with-resources are rejected.
+ * @compile/fail/ref=TwrForVariable3.out -XDrawDiagnostics -Xlint:-options TwrForVariable3.java
+ */
+public class TwrForVariable3 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable3 v1 = new TwrForVariable3();
+ Object v2 = new Object();
+
+ try (v2) {
+ fail("no an AutoCloseable");
+ }
+ try (java.lang.Object) {
+ fail("not a variable access");
+ }
+ try (java.lang) {
+ fail("not a variable access");
+ }
+ }
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable3.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,4 @@
+TwrForVariable3.java:11:14: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type: (compiler.misc.inconvertible.types: java.lang.Object, java.lang.AutoCloseable))
+TwrForVariable3.java:14:18: compiler.err.cant.resolve.location: kindname.class, lang, , , (compiler.misc.location: kindname.package, java, null)
+TwrForVariable3.java:17:14: compiler.err.cant.resolve.location: kindname.variable, java, , , (compiler.misc.location: kindname.class, TwrForVariable3, null)
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable4.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,45 @@
+/* @test /nodynamiccopyright/
+ * @bug 7196163
+ * @summary Verify that variable used as an operand to try-with-resources is rejected if it is not
+ * definitelly assigned before use and or not final or effectivelly final.
+ * @compile/fail/ref=TwrForVariable4.out -XDrawDiagnostics -Xlint:-options TwrForVariable4.java
+ */
+public class TwrForVariable4 implements AutoCloseable {
+ public static void main(String... args) {
+ TwrForVariable4 uninitialized;
+
+ try (uninitialized) {
+ fail("must be initialized before use");
+ }
+ uninitialized = new TwrForVariable4();
+
+ TwrForVariable4 notEffectivellyFinal1 = new TwrForVariable4();
+
+ notEffectivellyFinal1 = new TwrForVariable4();
+
+ try (notEffectivellyFinal1) {
+ fail("not effectivelly final");
+ }
+
+ TwrForVariable4 notEffectivellyFinal2 = new TwrForVariable4();
+
+ try (notEffectivellyFinal2) {
+ notEffectivellyFinal2 = new TwrForVariable4();
+ fail("not effectivelly final");
+ }
+
+ try (notFinal) {
+ fail("not final");
+ }
+ }
+
+ static TwrForVariable4 notFinal = new TwrForVariable4();
+
+ static void fail(String reason) {
+ throw new RuntimeException(reason);
+ }
+
+ public void close() {
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/TryWithResources/TwrForVariable4.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,5 @@
+TwrForVariable4.java:11:14: compiler.err.var.might.not.have.been.initialized: uninitialized
+TwrForVariable4.java:20:14: compiler.err.try.with.resources.expr.effectively.final.var: notEffectivellyFinal1
+TwrForVariable4.java:26:14: compiler.err.try.with.resources.expr.effectively.final.var: notEffectivellyFinal2
+TwrForVariable4.java:31:14: compiler.err.try.with.resources.expr.effectively.final.var: notFinal
+4 errors
--- a/langtools/test/tools/javac/VersionOpt.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/VersionOpt.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/annotations/SyntheticParameters.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,198 @@
+/*
+ * 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 SyntheticParameters
+ * @bug 8065132
+ * @summary Test generation of annotations on inner class parameters.
+ * @library /lib/annotations/
+ * @run main SyntheticParameters
+ */
+
+import annotations.classfile.ClassfileInspector;
+
+import java.io.*;
+import java.lang.annotation.*;
+
+import com.sun.tools.classfile.*;
+
+public class SyntheticParameters extends ClassfileInspector {
+
+ private static final String Inner_class = "SyntheticParameters$Inner.class";
+ private static final String Foo_class = "SyntheticParameters$Foo.class";
+ private static final Expected Inner_expected =
+ new Expected("SyntheticParameters$Inner",
+ null,
+ null,
+ new ExpectedParameterAnnotation[] {
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // this$0 parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 0,
+ "A",
+ true,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 1,
+ "A",
+ true,
+ 1),
+ (ExpectedParameterAnnotation)
+ new ExpectedParameterAnnotation(
+ "foo",
+ 0,
+ "A",
+ true,
+ 1),
+ (ExpectedParameterAnnotation)
+ new ExpectedParameterAnnotation(
+ "foo",
+ 1,
+ "A",
+ true,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // this$0 parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 0,
+ "B",
+ false,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 1,
+ "B",
+ false,
+ 1),
+ (ExpectedParameterAnnotation)
+ new ExpectedParameterAnnotation(
+ "foo",
+ 0,
+ "B",
+ false,
+ 1),
+ (ExpectedParameterAnnotation)
+ new ExpectedParameterAnnotation(
+ "foo",
+ 1,
+ "B",
+ false,
+ 0)
+ },
+ null);
+ private static final Expected Foo_expected =
+ new Expected("SyntheticParameters$Foo",
+ null,
+ null,
+ new ExpectedParameterAnnotation[] {
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // $enum$name parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 0,
+ "A",
+ true,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // $enum$ordinal parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 1,
+ "A",
+ true,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 2,
+ "A",
+ true,
+ 1),
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // $enum$name parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 0,
+ "B",
+ false,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is no annotation on the
+ // $enum$ordinal parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 1,
+ "B",
+ false,
+ 0),
+ (ExpectedParameterAnnotation)
+ // Assert there is an annotation on the
+ // first parameter.
+ new ExpectedParameterAnnotation(
+ "<init>",
+ 2,
+ "B",
+ false,
+ 1)
+ },
+ null);
+
+ public static void main(String... args) throws Exception {
+ new SyntheticParameters().run(
+ new ClassFile[] { getClassFile(Inner_class, Inner.class),
+ getClassFile(Foo_class, Foo.class) },
+ new Expected[] { Inner_expected, Foo_expected });
+ }
+
+ public class Inner {
+ public Inner(@A @B int a) {}
+ public void foo(@A @B int a, int b) {}
+ }
+
+ public static enum Foo {
+ ONE(null);
+ Foo(@A @B Object a) {}
+ }
+}
+
+@Retention(RetentionPolicy.RUNTIME)
+@interface A {}
+
+@Retention(RetentionPolicy.CLASS)
+@interface B {}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/InnerClass.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,3 @@
-import java.lang.annotation.ElementType;
-
/*
* Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/ClassfileInspector.java Thu Dec 04 12:58:21 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,950 +0,0 @@
-/*
- * 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
- * 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.lang.annotation.*;
-import java.io.*;
-import java.net.URL;
-import java.util.List;
-
-import com.sun.tools.classfile.*;
-
-/**
- * A class providing utilities for writing tests that inspect class
- * files directly, looking for specific type annotations.
- *
- * Note: this framework does not currently handle repeating
- * annotations.
- */
-public class ClassfileInspector {
-
- /**
- * A group of expected annotations to be found in a given class.
- * If the class name is null, then the template will be applied to
- * every class.
- */
- public static class Expected {
- /**
- * The name of the class. If {@code null} this template will
- * apply to every class; otherwise, it will only be applied to
- * the named class.
- */
- public final String classname;
-
- /**
- * The expected class annotations. These will be checked
- * against the class' attributes.
- */
- public final ExpectedTypeAnnotation[] classAnnos;
-
- /**
- * The expected method annotations. These will be checked
- * against all methods in the class.
- */
- public final ExpectedMethodTypeAnnotation[] methodAnnos;
-
- /**
- * The expected field annotations. These will be checked
- * against all fields in the class.
- */
- public final ExpectedFieldTypeAnnotation[] fieldAnnos;
-
- /**
- * Create an {@code Expected} from its components.
- *
- * @param classname The name of the class to match, or {@code
- * null} for all classes.
- * @param classAnnos The expected class annotations.
- * @param methodAnnos The expected method annotations.
- * @param fieldAnnos The expected field annotations.
- */
- public Expected(String classname,
- ExpectedTypeAnnotation[] classAnnos,
- ExpectedMethodTypeAnnotation[] methodAnnos,
- ExpectedFieldTypeAnnotation[] fieldAnnos) {
- this.classname = classname;
- this.classAnnos = classAnnos;
- this.methodAnnos = methodAnnos;
- this.fieldAnnos = fieldAnnos;
- }
-
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- final String newline = System.lineSeparator();
- sb.append("Expected on class ").append(classname);
- if (null != classAnnos) {
- sb.append(newline).append("Class annotations:").append(newline);
- for(ExpectedTypeAnnotation anno : classAnnos) {
- sb.append(anno).append(newline);
- }
- }
- if (null != methodAnnos) {
- sb.append(newline).append("Method annotations:").append(newline);
- for(ExpectedTypeAnnotation anno : methodAnnos) {
- sb.append(anno).append(newline);
- }
- }
- if (null != fieldAnnos) {
- sb.append(newline).append("Field annotations:").append(newline);
- for(ExpectedTypeAnnotation anno : fieldAnnos) {
- sb.append(anno).append(newline);
- }
- }
- return sb.toString();
- }
-
- /**
- * See if this template applies to a class.
- *
- * @param classname The classname to check.
- * @return Whether or not this template should apply.
- */
- public boolean matchClassName(String classname) {
- return this.classname == null || this.classname.equals(classname);
- }
-
- /**
- * After applying the template to all classes, check to see if
- * any of the expected annotations weren't matched.
- *
- * @return The number of missed matches.
- */
- public int check() {
- int count = 0;
- if (classAnnos != null) {
- for(ExpectedTypeAnnotation expected : classAnnos) {
- if (!expected.check()) {
- count++;
- }
- }
- }
- if (methodAnnos != null) {
- for(ExpectedMethodTypeAnnotation expected : methodAnnos) {
- if (!expected.check()) {
- count++;
- }
- }
- }
- if (fieldAnnos != null) {
- for(ExpectedFieldTypeAnnotation expected : fieldAnnos) {
- if (!expected.check()) {
- count++;
- }
- }
- }
- return count;
- }
- }
-
- /**
- * An expected type annotation. This is both a superclass for
- * method and field type annotations, as well as a class for type
- * annotations on a class.
- */
- public static class ExpectedTypeAnnotation {
- private int count = 0;
- protected final String expectedName;
- protected final int expectedCount;
- protected final TypeAnnotation.TargetType targetType;
- protected final int bound_index;
- protected final int parameter_index;
- protected final int type_index;
- protected final int exception_index;
- protected final TypeAnnotation.Position.TypePathEntry[] typePath;
- protected final boolean visibility;
-
- /**
- * Create an {@code ExpectedTypeAnnotation} from its
- * components. It is usually a better idea to use a {@code
- * Builder} to do this.
- *
- * @param expectedName The expected annotation name.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should
- * be seen. If 0, this asserts that the
- * described annotation is not present.
- * @param targetType The expected target type.
- * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
- * @param parameter_index The expected parameter index, or
- * {@code Integer.MIN_VALUE}.
- * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
- * @param exception_index The expected exception index, or
- * {@code Integer.MIN_VALUE}.
- * @param typePath The expected type path.
- */
- public ExpectedTypeAnnotation(String expectedName,
- boolean visibility,
- int expectedCount,
- TypeAnnotation.TargetType targetType,
- int bound_index,
- int parameter_index,
- int type_index,
- int exception_index,
- TypeAnnotation.Position.TypePathEntry... typePath) {
- this.expectedName = expectedName;
- this.visibility = visibility;
- this.expectedCount = expectedCount;
- this.targetType = targetType;
- this.bound_index = bound_index;
- this.parameter_index = parameter_index;
- this.type_index = type_index;
- this.exception_index = exception_index;
- this.typePath = typePath;
- }
-
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("Expected ");
- sb.append(expectedCount);
- sb.append(" annotation ");
- sb.append(expectedName);
- sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
- sb.append(targetType);
- sb.append(", bound_index = ");
- sb.append(bound_index);
- sb.append(", parameter_index = ");
- sb.append(parameter_index);
- sb.append(", type_index = ");
- sb.append(type_index);
- sb.append(", exception_index = ");
- sb.append(exception_index);
- sb.append(", type_path = [");
- for(int i = 0; i < typePath.length; i++) {
- if (i != 0) {
- sb.append(", ");
- }
- sb.append(typePath[i]);
- }
- sb.append("]");
- return sb.toString();
- }
-
- /**
- * See if this template matches the given visibility.
- *
- * @param Whether or not the annotation is visible at runtime.
- * @return Whether or not this template matches the visibility.
- */
- public boolean matchVisibility(boolean visibility) {
- return this.visibility == visibility;
- }
-
- /**
- * Attempty to match this template against an annotation. If
- * it does match, then the match count for the template will
- * be incremented. Otherwise, nothing will be done.
- *
- * @param anno The annotation to attempt to match.
- */
- public void matchAnnotation(TypeAnnotation anno) {
- boolean matches = true;
-
- try {
- matches = anno.constant_pool.getUTF8Info(anno.annotation.type_index).value.equals("L" + expectedName + ";");
- } catch(Exception e) {
- matches = false;
- }
-
- matches = matches && anno.position.type == targetType;
- matches = matches && anno.position.bound_index == bound_index;
- matches = matches && anno.position.parameter_index == parameter_index;
- matches = matches && anno.position.type_index == type_index;
- matches = matches && anno.position.exception_index == exception_index;
- matches = matches && anno.position.location.size() == typePath.length;
-
- if (matches) {
- int i = 0;
- for(TypeAnnotation.Position.TypePathEntry entry :
- anno.position.location) {
- matches = matches && typePath[i++].equals(entry);
- }
- }
-
- if (matches) {
- count++;
- }
- }
-
- /**
- * After all matching, check to see if the expected number of
- * matches equals the actual number. If not, then print a
- * failure message and return {@code false}.
- *
- * @return Whether or not the expected number of matched
- * equals the actual number.
- */
- public boolean check() {
- if (count != expectedCount) {
- System.err.println(this + ", but saw " + count);
- return false;
- } else {
- return true;
- }
- }
-
- /**
- * A builder class for creating {@code
- * ExpectedTypeAnnotation}s in a more convenient fashion. The
- * constructor for {@code ExpectedTypeAnnotation} takes a
- * large number of parameters (by necessity). This class
- * allows users to construct a {@code ExpectedTypeAnnotation}s
- * using only the ones they need.
- */
- public static class Builder {
- protected final String expectedName;
- protected final int expectedCount;
- protected final TypeAnnotation.TargetType targetType;
- protected final boolean visibility;
- protected int bound_index = Integer.MIN_VALUE;
- protected int parameter_index = Integer.MIN_VALUE;
- protected int type_index = Integer.MIN_VALUE;
- protected int exception_index = Integer.MIN_VALUE;
- protected TypeAnnotation.Position.TypePathEntry[] typePath =
- new TypeAnnotation.Position.TypePathEntry[0];
-
- /**
- * Create a {@code Builder} from the mandatory parameters.
- *
- * @param expectedName The expected annotation name.
- * @param targetType The expected target type.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should be seen.
- */
- public Builder(String expectedName,
- TypeAnnotation.TargetType targetType,
- boolean visibility,
- int expectedCount) {
- this.expectedName = expectedName;
- this.visibility = visibility;
- this.expectedCount = expectedCount;
- this.targetType = targetType;
- }
-
- /**
- * Create an {@code ExpectedTypeAnnotation} from all
- * parameters that have been provided. The default values
- * will be used for those that have not.
- *
- * @return The cretaed {@code ExpectedTypeAnnotation}.
- */
- public ExpectedTypeAnnotation build() {
- return new ExpectedTypeAnnotation(expectedName, visibility,
- expectedCount, targetType,
- bound_index, parameter_index,
- type_index, exception_index,
- typePath);
- }
-
- /**
- * Provide a bound index parameter.
- *
- * @param bound_index The bound_index value.
- */
- public Builder setBoundIndex(int bound_index) {
- this.bound_index = bound_index;
- return this;
- }
-
- /**
- * Provide a parameter index parameter.
- *
- * @param bound_index The parameter_index value.
- */
- public Builder setParameterIndex(int parameter_index) {
- this.parameter_index = parameter_index;
- return this;
- }
-
- /**
- * Provide a type index parameter.
- *
- * @param type_index The type_index value.
- */
- public Builder setTypeIndex(int type_index) {
- this.type_index = type_index;
- return this;
- }
-
- /**
- * Provide an exception index parameter.
- *
- * @param exception_index The exception_index value.
- */
- public Builder setExceptionIndex(int exception_index) {
- this.exception_index = exception_index;
- return this;
- }
-
- /**
- * Provide a type path parameter.
- *
- * @param typePath The type path value.
- */
- public Builder setTypePath(TypeAnnotation.Position.TypePathEntry[] typePath) {
- this.typePath = typePath;
- return this;
- }
- }
- }
-
- /**
- * A type annotation found on a method.
- */
- public static class ExpectedMethodTypeAnnotation extends ExpectedTypeAnnotation {
- private final String methodname;
-
- /**
- * Create an {@code ExpectedMethodTypeAnnotation} from its
- * components. It is usually a better idea to use a {@code
- * Builder} to do this.
- *
- * @param methodname The expected method name.
- * @param expectedName The expected annotation name.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should be seen.
- * @param targetType The expected target type.
- * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
- * @param parameter_index The expected parameter index, or
- * {@code Integer.MIN_VALUE}.
- * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
- * @param exception_index The expected exception index, or
- * {@code Integer.MIN_VALUE}.
- * @param typePath The expected type path.
- */
- public ExpectedMethodTypeAnnotation(String methodname,
- String expectedName,
- boolean visibility,
- int expectedCount,
- TypeAnnotation.TargetType targetType,
- int bound_index,
- int parameter_index,
- int type_index,
- int exception_index,
- TypeAnnotation.Position.TypePathEntry... typePath) {
- super(expectedName, visibility, expectedCount, targetType, bound_index,
- parameter_index, type_index, exception_index, typePath);
- this.methodname = methodname;
- }
-
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("Expected ");
- sb.append(expectedCount);
- sb.append(" annotation ");
- sb.append(expectedName);
- sb.append(visibility ? ", runtime visibile " : ", runtime invisibile ");
- sb.append(targetType);
- sb.append(", bound_index = ");
- sb.append(bound_index);
- sb.append(", parameter_index = ");
- sb.append(parameter_index);
- sb.append(", type_index = ");
- sb.append(type_index);
- sb.append(", exception_index = ");
- sb.append(exception_index);
- sb.append(", type_path = [");
- for(int i = 0; i < typePath.length; i++) {
- if (i != 0) {
- sb.append(", ");
- }
- sb.append(typePath[i]);
- }
- sb.append("]");
- sb.append(" on method ");
- sb.append(methodname);
- return sb.toString();
- }
-
- /**
- * See if this template applies to a method.
- *
- * @param methodname The method name to check.
- * @return Whether or not this template should apply.
- */
- public boolean matchMethodName(String methodname) {
- return this.methodname.equals(methodname);
- }
-
- /**
- * A builder class for creating {@code
- * ExpectedMethodTypeAnnotation}s in a more convenient fashion. The
- * constructor for {@code ExpectedMethodTypeAnnotation} takes a
- * large number of parameters (by necessity). This class
- * allows users to construct a {@code ExpectedMethodTypeAnnotation}s
- * using only the ones they need.
- */
- public static class Builder extends ExpectedTypeAnnotation.Builder {
- protected final String methodname;
-
- /**
- * Create a {@code Builder} from the mandatory parameters.
- *
- * @param methodname The expected method name.
- * @param expectedName The expected annotation name.
- * @param targetType The expected target type.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should be seen.
- */
- public Builder(String methodname,
- String expectedName,
- TypeAnnotation.TargetType targetType,
- boolean visibility,
- int expectedCount) {
- super(expectedName, targetType, visibility, expectedCount);
- this.methodname = methodname;
- }
-
- /**
- * Create an {@code ExpectedMethodTypeAnnotation} from all
- * parameters that have been provided. The default values
- * will be used for those that have not.
- *
- * @return The cretaed {@code ExpectedMethodTypeAnnotation}.
- */
- public ExpectedMethodTypeAnnotation build() {
- return new ExpectedMethodTypeAnnotation(methodname, expectedName,
- visibility, expectedCount,
- targetType, bound_index,
- parameter_index, type_index,
- exception_index, typePath);
- }
- }
- }
-
- /**
- * A type annotation found on a field.
- */
- public static class ExpectedFieldTypeAnnotation extends ExpectedTypeAnnotation {
- private final String fieldname;
-
- /**
- * Create an {@code ExpectedFieldTypeAnnotation} from its
- * components. It is usually a better idea to use a {@code
- * Builder} to do this.
- *
- * @param fieldname The expected field name.
- * @param expectedName The expected annotation name.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should be seen.
- * @param targetType The expected target type.
- * @param bound_index The expected bound index, or {@code Integer.MIN_VALUE}.
- * @param parameter_index The expected parameter index, or
- * {@code Integer.MIN_VALUE}.
- * @param type_index The expected type index, or {@code Integer.MIN_VALUE}.
- * @param exception_index The expected exception index, or
- * {@code Integer.MIN_VALUE}.
- * @param typePath The expected type path.
- */
- public ExpectedFieldTypeAnnotation(String fieldname,
- String expectedName,
- boolean visibility,
- int expectedCount,
- TypeAnnotation.TargetType targetType,
- int bound_index,
- int parameter_index,
- int type_index,
- int exception_index,
- TypeAnnotation.Position.TypePathEntry... typePath) {
- super(expectedName, visibility, expectedCount, targetType, bound_index,
- parameter_index, type_index, exception_index, typePath);
- this.fieldname = fieldname;
- }
-
- public String toString() {
- final StringBuilder sb = new StringBuilder();
- sb.append("Expected ").append(expectedCount)
- .append(" annotation ").append(expectedName)
- .append(visibility ? ", runtime visibile " : ", runtime invisibile ")
- .append(targetType)
- .append(", bound_index = ").append(bound_index)
- .append(", parameter_index = ").append(parameter_index)
- .append(", type_index = ").append(type_index)
- .append(", exception_index = ").append(exception_index)
- .append(", type_path = [");
-
- for(int i = 0; i < typePath.length; i++) {
- if (i != 0) {
- sb.append(", ");
- }
- sb.append(typePath[i]);
- }
- sb.append("]")
- .append(" on field ").append(fieldname);
- return sb.toString();
- }
-
- /**
- * See if this template applies to a field.
- *
- * @param fieldname The field name to check.
- * @return Whether or not this template should apply.
- */
- public boolean matchFieldName(String fieldname) {
- return this.fieldname.equals(fieldname);
- }
-
- /**
- * A builder class for creating {@code
- * ExpectedFieldTypeAnnotation}s in a more convenient fashion. The
- * constructor for {@code ExpectedFieldTypeAnnotation} takes a
- * large number of parameters (by necessity). This class
- * allows users to construct a {@code ExpectedFieldTypeAnnotation}s
- * using only the ones they need.
- */
- public static class Builder extends ExpectedTypeAnnotation.Builder {
- protected final String fieldname;
-
- /**
- * Create a {@code Builder} from the mandatory parameters.
- *
- * @param fieldname The expected field name.
- * @param expectedName The expected annotation name.
- * @param targetType The expected target type.
- * @param visibility Whether this annotation should be runtime-visible.
- * @param expectedCount The number of annotations that should be seen.
- */
- public Builder(String fieldname,
- String expectedName,
- TypeAnnotation.TargetType targetType,
- boolean visibility,
- int expectedCount) {
- super(expectedName, targetType, visibility, expectedCount);
- this.fieldname = fieldname;
- }
-
- /**
- * Create an {@code ExpectedFieldTypeAnnotation} from all
- * parameters that have been provided. The default values
- * will be used for those that have not.
- *
- * @return The cretaed {@code ExpectedFieldTypeAnnotation}.
- */
- public ExpectedFieldTypeAnnotation build() {
- return new ExpectedFieldTypeAnnotation(fieldname, expectedName,
- visibility, expectedCount,
- targetType, bound_index,
- parameter_index, type_index,
- exception_index, typePath);
- }
- }
- }
-
- private void matchClassTypeAnnotation(ClassFile classfile,
- ExpectedTypeAnnotation expected)
- throws ConstantPoolException {
- for(Attribute attr : classfile.attributes) {
- attr.accept(typeAnnoMatcher, expected);
- }
- }
-
- private void matchMethodTypeAnnotation(ClassFile classfile,
- ExpectedMethodTypeAnnotation expected)
- throws ConstantPoolException {
- for(Method meth : classfile.methods) {
- if (expected.matchMethodName(meth.getName(classfile.constant_pool))) {
- for(Attribute attr : meth.attributes) {
- attr.accept(typeAnnoMatcher, expected);
- }
- }
- }
- }
-
- private void matchFieldTypeAnnotation(ClassFile classfile,
- ExpectedFieldTypeAnnotation expected)
- throws ConstantPoolException {
- for(Field field : classfile.fields) {
- if (expected.matchFieldName(field.getName(classfile.constant_pool))) {
- for(Attribute attr : field.attributes) {
- attr.accept(typeAnnoMatcher, expected);
- }
- }
- }
- }
-
- private void matchClassTypeAnnotations(ClassFile classfile,
- ExpectedTypeAnnotation[] expected)
- throws ConstantPoolException {
- for(ExpectedTypeAnnotation one : expected) {
- matchClassTypeAnnotation(classfile, one);
- }
- }
-
- private void matchMethodTypeAnnotations(ClassFile classfile,
- ExpectedMethodTypeAnnotation[] expected)
- throws ConstantPoolException {
- for(ExpectedMethodTypeAnnotation one : expected) {
- matchMethodTypeAnnotation(classfile, one);
- }
- }
-
- private void matchFieldTypeAnnotations(ClassFile classfile,
- ExpectedFieldTypeAnnotation[] expected)
- throws ConstantPoolException {
- for(ExpectedFieldTypeAnnotation one : expected) {
- matchFieldTypeAnnotation(classfile, one);
- }
- }
-
- /**
- * Run a template on a single {@code ClassFile}.
- *
- * @param classfile The {@code ClassFile} on which to run tests.
- * @param expected The expected annotation template.
- */
- public void run(ClassFile classfile,
- Expected... expected)
- throws ConstantPoolException {
- run(new ClassFile[] { classfile }, expected);
- }
-
- /**
- * Run a template on multiple {@code ClassFile}s.
- *
- * @param classfile The {@code ClassFile}s on which to run tests.
- * @param expected The expected annotation template.
- */
- public void run(ClassFile[] classfiles,
- Expected... expected)
- throws ConstantPoolException {
- for(ClassFile classfile : classfiles) {
- for(Expected one : expected) {
- if (one.matchClassName(classfile.getName())) {
- if (one.classAnnos != null)
- matchClassTypeAnnotations(classfile, one.classAnnos);
- if (one.methodAnnos != null)
- matchMethodTypeAnnotations(classfile, one.methodAnnos);
- if (one.fieldAnnos != null)
- matchFieldTypeAnnotations(classfile, one.fieldAnnos);
- }
- }
- }
- int count = 0;
- for (Expected one : expected) {
- count += one.check();
- }
-
- if (count != 0) {
- throw new RuntimeException(count + " errors occurred in test");
- }
- }
-
- /**
- * Get a {@code ClassFile} from its file name.
- *
- * @param name The class' file name.
- * @return The {@code ClassFile}
- */
- public static ClassFile getClassFile(String name)
- throws IOException, ConstantPoolException {
- final URL url = ClassfileInspector.class.getResource(name);
- final InputStream in = url.openStream();
- try {
- return ClassFile.read(in);
- } finally {
- in.close();
- }
- }
-
- private static final Attribute.Visitor<Void, ExpectedTypeAnnotation> typeAnnoMatcher =
- new Attribute.Visitor<Void, ExpectedTypeAnnotation>() {
-
- @Override
- public Void visitBootstrapMethods(BootstrapMethods_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitDefault(DefaultAttribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitAnnotationDefault(AnnotationDefault_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitCharacterRangeTable(CharacterRangeTable_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitCode(Code_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitCompilationID(CompilationID_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitConstantValue(ConstantValue_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitDeprecated(Deprecated_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitEnclosingMethod(EnclosingMethod_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitExceptions(Exceptions_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitInnerClasses(InnerClasses_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitLineNumberTable(LineNumberTable_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitLocalVariableTable(LocalVariableTable_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitLocalVariableTypeTable(LocalVariableTypeTable_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitMethodParameters(MethodParameters_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitSignature(Signature_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitSourceDebugExtension(SourceDebugExtension_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitSourceFile(SourceFile_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitSourceID(SourceID_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitStackMap(StackMap_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitStackMapTable(StackMapTable_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitSynthetic(Synthetic_attribute attr,
- ExpectedTypeAnnotation expected) {
- return null;
- }
-
- @Override
- public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- if (expected.matchVisibility(true)) {
- for(TypeAnnotation anno : attr.annotations) {
- expected.matchAnnotation(anno);
- }
- }
-
- return null;
- }
-
- @Override
- public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr,
- ExpectedTypeAnnotation expected) {
- if (expected.matchVisibility(false)) {
- for(TypeAnnotation anno : attr.annotations) {
- expected.matchAnnotation(anno);
- }
- }
-
- return null;
- }
- };
-}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/classfile/SyntheticParameters.java Thu Dec 04 15:22:53 2014 -0800
@@ -24,10 +24,12 @@
/*
* @test SyntheticParameters
* @summary Test generation of annotations on inner class parameters.
- * @build ClassfileInspector
+ * @library /lib/annotations/
* @run main SyntheticParameters
*/
+import annotations.classfile.ClassfileInspector;
+
import java.io.*;
import java.lang.annotation.*;
@@ -111,7 +113,8 @@
public static void main(String... args) throws Exception {
new SyntheticParameters().run(
- new ClassFile[] { getClassFile(Inner_class), getClassFile(Foo_class) },
+ new ClassFile[] { getClassFile(Inner_class, Inner.class),
+ getClassFile(Foo_class, Foo.class) },
new Expected[] { Inner_expected, Foo_expected });
}
--- a/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/newlocations/BasicTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- a/langtools/test/tools/javac/api/6440528/T6440528.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/api/6440528/T6440528.java Thu Dec 04 15:22:53 2014 -0800
@@ -34,6 +34,7 @@
import java.io.File;
import java.lang.reflect.Field;
+import java.nio.file.Path;
import java.util.Arrays;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
import javax.tools.*;
@@ -59,10 +60,10 @@
System.err.println("Got: " + got);
}
- private File getUnderlyingFile(Object o) throws Exception {
- Field file = o.getClass().getDeclaredField("file");
+ private File getUnderlyingFile(FileObject o) throws Exception {
+ Field file = o.getClass().getDeclaredField("file"); // assumes RegularFileObject
file.setAccessible(true);
- return (File)file.get(o);
+ return ((Path)file.get(o)).toFile();
}
public static void main(String... args) throws Exception {
--- a/langtools/test/tools/javac/api/TestJavacTask.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/api/TestJavacTask.java Thu Dec 04 15:22:53 2014 -0800
@@ -61,7 +61,10 @@
try {
getTask(testFile);
} catch (IllegalArgumentException iae) {
- if (!iae.getMessage().contains("\"" + testFile.getName() + "\"")) {
+ // The following check is somewhat fragile, since the content of the ILA is not
+ // formally specified. If we want to fix this, we should catch/rewrap ILA coming
+ // from use of java.nio.file.Path inside javac's impl of JavaFileManager.
+ if (!iae.getMessage().contains(testFile.getName())) {
System.err.println("Got message: " + iae.getMessage());
throw new RuntimeException("Error: expected string not found");
}
--- a/langtools/test/tools/javac/diags/Example.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/diags/Example.java Thu Dec 04 15:22:53 2014 -0800
@@ -321,12 +321,17 @@
first = opts.get(0);
rest = opts.subList(1, opts.size()).toArray(new String[opts.size() - 1]);
}
+ // For more details on the different compilers,
+ // see their respective class doc comments.
+ // See also README.examples.txt in this directory.
if (first == null || first.equals("jsr199"))
return new Jsr199Compiler(verbose, rest);
else if (first.equals("simple"))
return new SimpleCompiler(verbose);
else if (first.equals("backdoor"))
return new BackdoorCompiler(verbose);
+ else if (first.equals("exec"))
+ return new ExecCompiler(verbose);
else
throw new IllegalArgumentException(first);
}
@@ -506,6 +511,84 @@
}
}
+ /**
+ * Run the test in a separate process.
+ */
+ static class ExecCompiler extends Compiler {
+ ExecCompiler(boolean verbose) {
+ super(verbose);
+ }
+
+ @Override
+ boolean run(PrintWriter out, Set<String> keys, boolean raw, List<String> opts, List<File> files) {
+ if (out != null && keys != null)
+ throw new IllegalArgumentException();
+
+ if (verbose)
+ System.err.println("run_exec: " + opts + " " + files);
+
+ List<String> args = new ArrayList<String>();
+
+ File javaHome = new File(System.getProperty("java.home"));
+ if (javaHome.getName().equals("jre"))
+ javaHome = javaHome.getParentFile();
+ File javaExe = new File(new File(javaHome, "bin"), "java");
+ args.add(javaExe.getPath());
+
+ File toolsJar = new File(new File(javaHome, "lib"), "tools.jar");
+ if (toolsJar.exists()) {
+ args.add("-classpath");
+ args.add(toolsJar.getPath());
+ }
+
+ addOpts(args, "test.vm.opts");
+ addOpts(args, "test.java.opts");
+ args.add(com.sun.tools.javac.Main.class.getName());
+
+ if (keys != null || raw)
+ args.add("-XDrawDiagnostics");
+
+ args.addAll(opts);
+ for (File f: files)
+ args.add(f.getPath());
+
+ try {
+ ProcessBuilder pb = new ProcessBuilder(args);
+ pb.redirectErrorStream(true);
+ Process p = pb.start();
+ BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));
+ String line;
+ while ((line = in.readLine()) != null) {
+ if (keys != null)
+ scanForKeys(line, keys);
+ }
+ int rc = p.waitFor();
+
+ return (rc == 0);
+ } catch (IOException | InterruptedException e) {
+ System.err.println("Exception execing javac" + e);
+ System.err.println("Command line: " + opts);
+ return false;
+ }
+ }
+
+ private static void scanForKeys(String text, Set<String> keys) {
+ StringTokenizer st = new StringTokenizer(text, " ,\r\n():");
+ while (st.hasMoreElements()) {
+ String t = st.nextToken();
+ if (t.startsWith("compiler."))
+ keys.add(t);
+ }
+ }
+
+ private static void addOpts(List<String> args, String propName) {
+ String propValue = System.getProperty(propName);
+ if (propValue == null || propValue.isEmpty())
+ return;
+ args.addAll(Arrays.asList(propValue.split(" +", 0)));
+ }
+ }
+
static class BackdoorCompiler extends Compiler {
BackdoorCompiler(boolean verbose) {
super(verbose);
--- a/langtools/test/tools/javac/diags/README.examples.txt Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/diags/README.examples.txt Thu Dec 04 15:22:53 2014 -0800
@@ -123,6 +123,9 @@
is required to detect and track messages that bypass the normal
diagnostic mechanisms, such as output generated by the -verbose
option.
+ exec -- The example will be run in a subprocess. This mode is useful when
+ the example will leave files open, such that the only way to close
+ them is to exit the process.
The "jsr199" run mode accepts the following options:
-cantRead:pattern
--- a/langtools/test/tools/javac/diags/examples/ImportRequiresCanonical/ImportRequiresCanonical.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/diags/examples/ImportRequiresCanonical/ImportRequiresCanonical.java Thu Dec 04 15:22:53 2014 -0800
@@ -23,6 +23,6 @@
// key: compiler.err.import.requires.canonical
-import p.ExtendsBase.NestedInBase;
+import java.util.HashMap.Entry;
class ImportRequiredCanonical { }
--- a/langtools/test/tools/javac/diags/examples/ProcUnclosedTypeFiles/ProcUnclosedTypeFiles.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/diags/examples/ProcUnclosedTypeFiles/ProcUnclosedTypeFiles.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,5 +23,6 @@
// key: compiler.warn.proc.unclosed.type.files
// options: -Xlint:processing -processor AnnoProc
+// run: exec
class ProcUnclosedTypeFiles { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TryWithResourcesExprEffectivelyFinalVar.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// key: compiler.err.try.with.resources.expr.effectively.final.var
+
+class TryWithResourcesExprEffectivelyFinalVar {
+ void m() {
+ CloseableImpl ac = new CloseableImpl();
+
+ try (ac) {
+ ac = null;
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TryWithResourcesExprNeedsVar.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.try.with.resources.expr.needs.var
+
+class TryWithResourcesExprNeedsVar {
+ void m() {
+ try (new CloseableImpl()) {
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/VarInTryWithResourcesNotSupportedInSource.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+// key: compiler.err.var.in.try.with.resources.not.supported.in.source
+// key: compiler.warn.source.no.bootclasspath
+// options: -source 8
+
+class VarInTryWithResourcesNotSupportedInSource {
+ void m() {
+ AutoCloseable ac = new CloseableImpl();
+
+ try (ac) {
+ }
+ }
+}
+
+class CloseableImpl implements AutoCloseable {
+ @Override
+ public void close() throws Exception {
+ }
+}
--- a/langtools/test/tools/javac/file/T7018098.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/file/T7018098.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -99,7 +99,7 @@
round++;
if (round == 1) {
boolean expect = Boolean.valueOf(options.get("expect"));
- checkEqual("cache result", fsInfo.isDirectory(testDir), expect);
+ checkEqual("cache result", fsInfo.isDirectory(testDir.toPath()), expect);
initialFSInfo = fsInfo;
} else {
checkEqual("fsInfo", fsInfo, initialFSInfo);
--- a/langtools/test/tools/javac/file/T7068437.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/file/T7068437.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.Writer;
+import java.nio.file.NoSuchFileException;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
@@ -104,7 +105,7 @@
messager.printMessage(Kind.NOTE, "found previous content of length " +
filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length());
found = true;
- } catch (FileNotFoundException x) {
+ } catch (FileNotFoundException | NoSuchFileException x) {
messager.printMessage(Kind.NOTE, "not previously there");
found = false;
} catch (IOException x) {
--- a/langtools/test/tools/javac/file/T7068451.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/file/T7068451.java Thu Dec 04 15:22:53 2014 -0800
@@ -33,6 +33,7 @@
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
+import java.nio.file.NoSuchFileException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -143,7 +144,7 @@
try {
int len = filer.getResource(StandardLocation.SOURCE_OUTPUT, "p", "C.java").getCharContent(false).length();
messager.printMessage(Kind.NOTE, "C.java: found previous content of length " + len);
- } catch (FileNotFoundException x) {
+ } catch (FileNotFoundException | NoSuchFileException x) {
messager.printMessage(Kind.NOTE, "C.java: not previously there");
} catch (IOException x) {
messager.printMessage(Kind.ERROR, "while reading: " + x);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/flow/T8062747.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,24 @@
+/**
+ * @test
+ * @bug 8062747
+ * @summary Avoiding an error for lambdas with thrown types inference inside an anonymous class.
+ * @compile T8062747.java
+ */
+public class T8062747 {
+
+ public interface Throwing<Y extends Exception> {
+ void canThrow() throws Y;
+ }
+
+ public static <Y extends Exception> void wrap(Throwing<Y> action) {
+ }
+
+ public static void invoke(String a) {
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ wrap(() -> System.out.println(a));
+ }
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/8064803/T8064803.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,53 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8064803
+ * @summary Javac erroneously uses instantiated signatures when merging abstract most-specific methods
+ */
+public class T8064803 {
+ interface ParentA<T> {
+ T process() throws Exception;
+ }
+
+ interface ParentB<T> {
+ T process() throws Exception;
+ }
+
+ interface Child<T> extends ParentA<T>, ParentB<T> { }
+
+ static class ChildImpl<T> implements Child<T> {
+ @Override
+ public T process() {
+ return null;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ Child<String> child = new ChildImpl<String>();
+ child.process();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/8065986/T8065986a.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8065986
+ *
+ * @summary Compiler fails to NullPointerException when calling super with Object<>()
+ * @compile/fail/ref=T8065986a.out T8065986a.java -XDrawDiagnostics
+ *
+ */
+import java.util.ArrayList;
+
+class T8065986a {
+ T8065986a() {
+ super(new Object<>());
+ }
+
+ T8065986a(boolean b) {
+ super(new ArrayList<>());
+ }
+
+ T8065986a(boolean b1, boolean b2) {
+ super(()->{});
+ }
+
+ T8065986a(boolean b1, boolean b2, boolean b3) {
+ super(T8065986a::m);
+ }
+
+ T8065986a(boolean cond, Object o1, Object o2) {
+ super(cond ? o1 : o2);
+ }
+
+ static void m() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/8065986/T8065986a.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,6 @@
+T8065986a.java:13:25: compiler.err.cant.apply.diamond.1: java.lang.Object, (compiler.misc.diamond.non.generic: java.lang.Object)
+T8065986a.java:17:9: compiler.err.cant.apply.symbol: kindname.constructor, Object, compiler.misc.no.args, java.util.ArrayList<java.lang.Object>, kindname.class, java.lang.Object, (compiler.misc.arg.length.mismatch)
+T8065986a.java:21:9: compiler.err.cant.apply.symbol: kindname.constructor, Object, compiler.misc.no.args, @438, kindname.class, java.lang.Object, (compiler.misc.arg.length.mismatch)
+T8065986a.java:25:9: compiler.err.cant.apply.symbol: kindname.constructor, Object, compiler.misc.no.args, @520, kindname.class, java.lang.Object, (compiler.misc.arg.length.mismatch)
+T8065986a.java:29:9: compiler.err.cant.apply.symbol: kindname.constructor, Object, compiler.misc.no.args, @608, kindname.class, java.lang.Object, (compiler.misc.arg.length.mismatch)
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/8065986/T8065986b.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,33 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8065986
+ *
+ * @summary Compiler fails to NullPointerException when calling super with Object<>()
+ * @compile/fail/ref=T8065986b.out T8065986b.java -XDrawDiagnostics
+ *
+ */
+import java.util.ArrayList;
+
+class T8065986b {
+ T8065986b() {
+ this(new Object<>());
+ }
+
+ T8065986b(boolean b) {
+ this(new ArrayList<>());
+ }
+
+ T8065986b(boolean b1, boolean b2) {
+ this(()->{});
+ }
+
+ T8065986b(boolean b1, boolean b2, boolean b3) {
+ this(T8065986b::m);
+ }
+
+ T8065986b(boolean cond, Object o1, Object o2) {
+ this(cond ? o1 : o2);
+ }
+
+ static void m() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/diamond/8065986/T8065986b.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,6 @@
+T8065986b.java:13:24: compiler.err.cant.apply.diamond.1: java.lang.Object, (compiler.misc.diamond.non.generic: java.lang.Object)
+T8065986b.java:17:9: compiler.err.cant.apply.symbols: kindname.constructor, T8065986b, java.util.ArrayList<java.lang.Object>,{(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.cant.apply.diamond.1: (compiler.misc.diamond: java.util.ArrayList), (compiler.misc.infer.no.conforming.instance.exists: E, java.util.ArrayList<E>, boolean)))),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,java.lang.Object,java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T8065986b.java:21:9: compiler.err.cant.apply.symbols: kindname.constructor, T8065986b, @435,{(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: boolean))),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,java.lang.Object,java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T8065986b.java:25:9: compiler.err.cant.apply.symbols: kindname.constructor, T8065986b, @516,{(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: boolean))),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,java.lang.Object,java.lang.Object), (compiler.misc.arg.length.mismatch))}
+T8065986b.java:29:9: compiler.err.cant.apply.symbols: kindname.constructor, T8065986b, @603,{(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.type.in.conditional: (compiler.misc.inconvertible.types: java.lang.Object, boolean)))),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,boolean,boolean), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.constructor, T8065986b, T8065986b(boolean,java.lang.Object,java.lang.Object), (compiler.misc.arg.length.mismatch))}
+5 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importChecks/NoImportedNoClasses.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,10 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 7101822
+ * @summary Verify that statically importing non-existing constant causes a compile-time error
+ * for files without a class.
+ *
+ * @compile/fail/ref=NoImportedNoClasses.out -XDrawDiagnostics NoImportedNoClasses.java
+ */
+
+import static java.lang.Runnable.UNKNOWN;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importChecks/NoImportedNoClasses.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,2 @@
+NoImportedNoClasses.java:10:1: compiler.err.cant.resolve.location: kindname.static, UNKNOWN, , , kindname.interface, java.lang.Runnable
+1 error
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/ImportResolvedTooSoon.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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 7101822
+ * @summary Verify that imports are declarations are processed in the correct order.
+ * @compile ImportResolvedTooSoon.java
+ */
+package pkg;
+
+import static pkg.B.SubInner.Foo;
+
+class B extends A {
+ static class SubInner extends Inner { }
+}
+
+class A {
+ static class Inner {
+ static class Foo { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T7101822A.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,49 @@
+/*
+ * 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 7101822
+ * @summary Verify that imports are declarations are processed in the correct order.
+ * @compile T7101822A.java T7101822Z.java
+ */
+package a;
+
+import a.T7101822A.B.C;
+import z.T7101822Z;
+
+public class T7101822A {
+
+ class B extends T7101822Z {
+
+ class C {
+ }
+ }
+
+ class D {
+
+ Class foo() {
+ return C.class;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/T7101822Z.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package z;
+public class T7101822Z {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/TestDuplicateImport.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2011-2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 7101822
+ * @summary static import fails to resolve interfaces on nested enums via import statements
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+
+public class TestDuplicateImport {
+
+ static int checkCount = 0;
+
+ enum ImportKind {
+ NORMAL("import a.#Q.#N;"),
+ STATIC("import static a.#Q.#N;");
+
+ String importStr;
+
+ ImportKind(String importStr) {
+ this.importStr = importStr;
+ }
+
+ String getImportStatement(QualifierKind qk, NameKind nk) {
+ return importStr.replaceAll("#Q", qk.qualifierStr)
+ .replaceAll("#N", nk.nameStr);
+ }
+
+ boolean isStatic() {
+ return this == STATIC;
+ }
+ }
+
+ enum QualifierKind {
+ A("A"),
+ B("B"),
+ C("C");
+
+ String qualifierStr;
+
+ QualifierKind(String qualifierStr) {
+ this.qualifierStr = qualifierStr;
+ }
+
+ public boolean compatible(QualifierKind ik) {
+ return this == ik || (this != A && ik != A);
+ }
+ }
+
+ enum NameKind {
+ D("D"),
+ E("E"),
+ M("m"),
+ F("f"),
+ STAR("*"),
+ NON_EXISTENT("NonExistent");
+
+ String nameStr;
+
+ NameKind(String nameStr) {
+ this.nameStr = nameStr;
+ }
+
+ boolean exists() {
+ return this != NON_EXISTENT;
+ }
+
+ boolean isMember() {
+ return this == M || this == F;
+ }
+
+ boolean isType() {
+ return this == D || this == E;
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (ImportKind ik1 : ImportKind.values()) {
+ for (ImportKind ik2 : ImportKind.values()) {
+ for (QualifierKind qk1 : QualifierKind.values()) {
+ for (QualifierKind qk2 : QualifierKind.values()) {
+ for (NameKind nk1 : NameKind.values()) {
+ for (NameKind nk2 : NameKind.values()) {
+ new TestDuplicateImport(ik1, ik2, qk1, qk2, nk1, nk2).run(comp, fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ ImportKind ik1;
+ ImportKind ik2;
+ QualifierKind qk1;
+ QualifierKind qk2;
+ NameKind nk1;
+ NameKind nk2;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ TestDuplicateImport(ImportKind ik1, ImportKind ik2, QualifierKind qk1, QualifierKind qk2, NameKind nk1, NameKind nk2) {
+ this.ik1 = ik1;
+ this.ik2 = ik2;
+ this.qk1 = qk1;
+ this.qk2 = qk2;
+ this.nk1 = nk1;
+ this.nk2 = nk2;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+ class JavaSource extends SimpleJavaFileObject {
+
+ String bodyTemplate = "package a;\n" +
+ "#I1\n" +
+ "#I2\n" +
+ "class A {\n" +
+ " static class D { }\n" +
+ " static class E { }\n" +
+ " static Object f;\n" +
+ " static void m() { }\n" +
+ "}\n" +
+ "class B {\n" +
+ " static class D { }\n" +
+ " static class E { }\n" +
+ " static Object f;\n" +
+ " static void m() { }\n" +
+ "}\n" +
+ "class C extends B {\n" +
+ "}\n";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = bodyTemplate.replaceAll("#I1", ik1.getImportStatement(qk1, nk1))
+ .replaceAll("#I2", ik2.getImportStatement(qk2, nk2));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ checkCount++;
+
+ boolean errorExpected = false;
+
+ //error if the import refers to a non-existent symbol
+ if (!nk1.exists() || !nk2.exists()) {
+ errorExpected = true;
+ }
+
+ //error if a non-static import refers to a non-type symbol
+ if ((nk1.isMember() && !ik1.isStatic()) ||
+ (nk2.isMember() && !ik2.isStatic())) {
+ errorExpected = true;
+ }
+
+ //error if two single non-static (or one static and one non-static)
+ //imports import same names from different places
+ if (nk1 == nk2 && nk1 != NameKind.STAR && !qk1.compatible(qk2) &&
+ (!ik1.isStatic() || !ik2.isStatic())) {
+ errorExpected = true;
+ }
+
+ if ((qk1 == QualifierKind.C && !ik1.isStatic() && nk1 != NameKind.STAR) ||
+ (qk2 == QualifierKind.C && !ik2.isStatic() && nk2 != NameKind.STAR)) {
+ errorExpected = true;
+ }
+
+ if (errorExpected != diagChecker.errorFound) {
+ throw new Error("invalid diagnostics for source:\n" +
+ source.getCharContent(true) +
+ "\nFound error: " + diagChecker.errorFound +
+ "\nExpected error: " + errorExpected);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/TestLazyImportScope.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2011-2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 7101822
+ * @summary static import fails to resolve interfaces on nested enums via import statements
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import javax.tools.Diagnostic;
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
+public class TestLazyImportScope {
+
+ static int checkCount = 0;
+
+ enum ImportOrder {
+ NORMAL("import a.C.D;\n" +
+ "#I"),
+ REVERSE("#I\n" +
+ "import a.C.D;");
+
+ String importLayout;
+
+ ImportOrder(String importLayout) {
+ this.importLayout = importLayout;
+ }
+
+ String getImportString(ImportKind ik) {
+ return importLayout.replaceAll("#I", ik.importStr);
+ }
+ }
+
+ enum ImportKind {
+ NAMED("import a.A.B.E;"),
+ ON_DEMAND("import a.A.B.*;"),
+ STATIC_NAMED_TYPE("import static a.A.B.E;"),
+ STATIC_NAMED_MEMBER("import static a.A.B.bm;"),
+ STATIC_ON_DEMAND("import static a.A.B.*;");
+
+ String importStr;
+
+ private ImportKind(String importStr) {
+ this.importStr = importStr;
+ }
+ }
+
+ enum TypeRefKind {
+ NONE(""),
+ E("E e = null;"),
+ F("F f = null;"),
+ BOTH("E e = null; F f = null;");
+
+ String typeRefStr;
+
+ private TypeRefKind(String typeRefStr) {
+ this.typeRefStr = typeRefStr;
+ }
+
+ boolean isImported(ImportKind ik) {
+ switch (ik) {
+ case NAMED:
+ case STATIC_NAMED_TYPE: return this == NONE || this == E;
+ case ON_DEMAND:
+ case STATIC_ON_DEMAND: return true;
+ default: return this == NONE;
+ }
+ }
+ }
+
+ enum MemberRefKind {
+ NONE(""),
+ FIELD("Object o = bf;"),
+ METHOD("bm();"),
+ BOTH("Object o = bf; bm();");
+
+ String memberRefStr;
+
+ private MemberRefKind(String memberRefStr) {
+ this.memberRefStr = memberRefStr;
+ }
+
+ boolean isImported(ImportKind ik) {
+ switch (ik) {
+ case STATIC_NAMED_MEMBER: return this == NONE || this == METHOD;
+ case STATIC_ON_DEMAND: return true;
+ default: return this == NONE;
+ }
+ }
+ }
+
+ public static void main(String... args) throws Exception {
+
+ //create default shared JavaCompiler - reused across multiple compilations
+ JavaCompiler comp = ToolProvider.getSystemJavaCompiler();
+ StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null);
+
+ for (ImportOrder ord : ImportOrder.values()) {
+ for (ImportKind ik : ImportKind.values()) {
+ for (TypeRefKind tk : TypeRefKind.values()) {
+ for (MemberRefKind mk : MemberRefKind.values()) {
+ new TestLazyImportScope(ord, ik, tk, mk).run(comp, fm);
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ ImportOrder ord;
+ ImportKind ik;
+ TypeRefKind tk;
+ MemberRefKind mk;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ TestLazyImportScope(ImportOrder ord, ImportKind ik, TypeRefKind tk, MemberRefKind mk) {
+ this.ord = ord;
+ this.ik = ik;
+ this.tk = tk;
+ this.mk = mk;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String bodyTemplate = "package a;\n" +
+ "#I\n" +
+ "class A {\n" +
+ " static class B extends D {\n" +
+ " static class E { }\n" +
+ " static class F { }\n" +
+ " static Object bf;\n" +
+ " static void bm() { }\n" +
+ " }\n" +
+ "}\n" +
+ "class C {\n" +
+ " static class D { }\n" +
+ "}\n" +
+ "class Test {\n" +
+ " void test() {\n" +
+ " #T\n" +
+ " #M\n" +
+ " }\n" +
+ "}";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = bodyTemplate.replaceAll("#I", ord.getImportString(ik))
+ .replaceAll("#T", tk.typeRefStr)
+ .replaceAll("#M", mk.memberRefStr);
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ null, null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when compiling the following code:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ checkCount++;
+
+ boolean errorExpected = !tk.isImported(ik) || !mk.isImported(ik);
+
+ if (errorExpected != diagChecker.errorFound) {
+ throw new Error("invalid diagnostics for source:\n" +
+ source.getCharContent(true) +
+ "\nFound error: " + diagChecker.errorFound +
+ "\nExpected error: " + errorExpected);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/TypeParamCycle.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,38 @@
+/*
+ * 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 7101822
+ * @summary Verify that cycles between type parameter bounds and imports/class nesting
+ * are not a problem.
+ * @compile TypeParamCycle.java
+ */
+package pkg;
+
+import pkg.A.Outer.Inner;
+
+class A {
+ static class Outer<X extends Inner> { static class Inner {} }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/TypeParamCycle2.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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 7101822
+ * @summary Verify that cycles between type parameter bounds and imports/class nesting
+ * are not a problem.
+ * @compile TypeParamCycle2.java
+ */
+package pkg;
+
+import pkg.A.Outer.Inner;
+
+class B extends Inner {
+}
+
+class A {
+ static class Outer<X extends Inner> { static class Inner {} }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/TypeParamCycle3.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,42 @@
+/*
+ * 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 7101822
+ * @summary Verify that cycles between type parameter bounds and imports/class nesting
+ * are not a problem.
+ * @compile TypeParamCycle3.java
+ */
+package pkg;
+
+import static pkg.A.Outer.Inner;
+
+class A {
+ static class Outer<X extends Inner> extends B { }
+}
+
+class B {
+ static class Inner {}
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/DependenciesTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,366 @@
+/*
+ * 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 7101822
+ * @summary Verify that the processing of classes in TypeEnter runs in the correct order.
+ * @library /tools/lib
+ * @build annotations.TriggersComplete annotations.TriggersCompleteRepeat annotations.Phase
+ * @build DependenciesTest
+ * @run main DependenciesTest
+ */
+
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Set;
+import java.util.Stack;
+import java.util.stream.Stream;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.Name;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Elements;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
+import annotations.*;
+import com.sun.source.tree.AnnotationTree;
+
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.ImportTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.SourcePositions;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.api.JavacTrees;
+import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.tree.JCTree;
+import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.Context.Factory;
+import com.sun.tools.javac.util.Dependencies;
+
+
+public class DependenciesTest {
+ public static void main(String... args) throws IOException {
+ new DependenciesTest().run();
+ }
+
+ void run() throws IOException {
+ Path src = Paths.get(System.getProperty("test.src"), "tests");
+
+ try (Stream<Path> tests = Files.list(src)) {
+ tests.map(p -> Files.isRegularFile(p) ? Stream.of(p) : silentWalk(p))
+ .forEach(this :: runTest);
+ }
+ }
+
+ Stream<Path> silentWalk(Path src) {
+ try {
+ return Files.walk(src).filter(Files :: isRegularFile);
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }
+
+ void runTest(Stream<Path> inputs) {
+ JavacTool tool = JavacTool.create();
+ try (JavacFileManager fm = tool.getStandardFileManager(null, null, null)) {
+ Path classes = Paths.get(System.getProperty("test.classes"));
+ Iterable<? extends JavaFileObject> reconFiles =
+ fm.getJavaFileObjectsFromFiles(inputs.sorted().map(p -> p.toFile()) :: iterator);
+ List<String> options = Arrays.asList("-classpath", classes.toAbsolutePath().toString());
+ JavacTask reconTask = tool.getTask(null, fm, null, options, null, reconFiles);
+ Iterable<? extends CompilationUnitTree> reconUnits = reconTask.parse();
+ JavacTrees reconTrees = JavacTrees.instance(reconTask);
+ SearchAnnotations scanner = new SearchAnnotations(reconTrees,
+ reconTask.getElements());
+ List<JavaFileObject> validateFiles = new ArrayList<>();
+
+ reconTask.analyze();
+ scanner.scan(reconUnits, null);
+
+ for (CompilationUnitTree cut : reconUnits) {
+ validateFiles.add(ClearAnnotations.clearAnnotations(reconTrees, cut));
+ }
+
+ Context validateContext = new Context();
+ TestDependencies.preRegister(validateContext);
+ JavacTask validateTask =
+ tool.getTask(null, fm, null, options, null, validateFiles, validateContext);
+
+ validateTask.analyze();
+
+ TestDependencies deps = (TestDependencies) Dependencies.instance(validateContext);
+
+ if (!scanner.topLevel2Expected.equals(deps.topLevel2Completing)) {
+ throw new IllegalStateException( "expected=" + scanner.topLevel2Expected +
+ "; actual=" + deps.topLevel2Completing);
+ }
+ } catch (IOException ex) {
+ throw new IllegalStateException(ex);
+ } finally {
+ inputs.close();
+ }
+ }
+
+ static final class TestDependencies extends Dependencies {
+
+ public static void preRegister(Context context) {
+ context.put(dependenciesKey, (Factory<Dependencies>) TestDependencies :: new);
+ }
+
+ public TestDependencies(Context context) {
+ super(context);
+ }
+
+ final Stack<PhaseDescription> inProcess = new Stack<>();
+
+ String topLevelMemberEnter;
+ Map<String, Set<PhaseDescription>> topLevel2Completing = new HashMap<>();
+
+ @Override
+ public void push(ClassSymbol s, CompletionCause phase) {
+ String flatname = s.flatName().toString();
+ for (Phase p : Phase.values()) {
+ if (phase == p.cause) {
+ inProcess.push(new PhaseDescription(flatname, p));
+ return ;
+ }
+ }
+ if (phase == CompletionCause.MEMBER_ENTER) {
+ if (inProcess.isEmpty()) {
+ topLevelMemberEnter = flatname;
+ } else {
+ for (PhaseDescription running : inProcess) {
+ if (running == null)
+ continue;
+
+ Set<PhaseDescription> completing =
+ topLevel2Completing.computeIfAbsent(running.flatname, $ -> new HashSet<>());
+
+ completing.add(new PhaseDescription(flatname, running.phase));
+ }
+ }
+ }
+ inProcess.push(null);
+ }
+
+ @Override
+ public void push(AttributionKind ak, JCTree t) {
+ inProcess.push(null);
+ }
+
+ @Override
+ public void pop() {
+ inProcess.pop();
+ }
+
+ }
+
+ static final class SearchAnnotations extends TreePathScanner<Void, Void> {
+ final Trees trees;
+ final Elements elements;
+ final TypeElement triggersCompleteAnnotation;
+ final TypeElement triggersCompleteRepeatAnnotation;
+ final Map<String, Set<PhaseDescription>> topLevel2Expected =
+ new HashMap<>();
+
+ public SearchAnnotations(Trees trees, Elements elements) {
+ this.trees = trees;
+ this.elements = elements;
+ this.triggersCompleteAnnotation =
+ elements.getTypeElement(TriggersComplete.class.getName());
+ this.triggersCompleteRepeatAnnotation =
+ elements.getTypeElement(TriggersCompleteRepeat.class.getName());
+ }
+
+ @Override
+ public Void visitClass(ClassTree node, Void p) {
+ TypeElement te = (TypeElement) trees.getElement(getCurrentPath());
+ Set<PhaseDescription> expected = new HashSet<>();
+
+ for (AnnotationMirror am : getTriggersCompleteAnnotation(te)) {
+ TypeMirror of = (TypeMirror) findAttribute(am, "of").getValue();
+ Name ofName = elements.getBinaryName((TypeElement) ((DeclaredType) of).asElement());
+ Element at = (Element) findAttribute(am, "at").getValue();
+ Phase phase = Phase.valueOf(at.getSimpleName().toString());
+ expected.add(new PhaseDescription(ofName.toString(), phase));
+ }
+
+ if (!expected.isEmpty())
+ topLevel2Expected.put(elements.getBinaryName(te).toString(), expected);
+
+ return super.visitClass(node, p);
+ }
+
+ Collection<AnnotationMirror> getTriggersCompleteAnnotation(TypeElement te) {
+ for (AnnotationMirror am : te.getAnnotationMirrors()) {
+ if (triggersCompleteAnnotation.equals(am.getAnnotationType().asElement())) {
+ return Collections.singletonList(am);
+ }
+ if (triggersCompleteRepeatAnnotation.equals(am.getAnnotationType().asElement())) {
+ return (Collection<AnnotationMirror>) findAttribute(am, "value").getValue();
+ }
+ }
+ return Collections.emptyList();
+ }
+
+ AnnotationValue findAttribute(AnnotationMirror mirror, String name) {
+ for (Entry<? extends ExecutableElement, ? extends AnnotationValue> e :
+ mirror.getElementValues().entrySet()) {
+ if (e.getKey().getSimpleName().contentEquals(name)) {
+ return e.getValue();
+ }
+ }
+
+ throw new IllegalStateException("Could not find " + name + " in " + mirror);
+ }
+ }
+
+ static final class ClearAnnotations extends TreePathScanner<Void, Void> {
+ final SourcePositions positions;
+ final List<int[]> spans2Clear = new ArrayList<>();
+
+ ClearAnnotations(Trees trees) {
+ this.positions = trees.getSourcePositions();
+ }
+
+ @Override
+ public Void visitAnnotation(AnnotationTree node, Void p) {
+ removeCurrentNode();
+ return null;
+ }
+
+ @Override
+ public Void visitImport(ImportTree node, Void p) {
+ if (node.getQualifiedIdentifier().toString().startsWith("annotations.")) {
+ removeCurrentNode();
+ return null;
+ }
+ return super.visitImport(node, p);
+ }
+
+ void removeCurrentNode() {
+ CompilationUnitTree topLevel = getCurrentPath().getCompilationUnit();
+ Tree node = getCurrentPath().getLeaf();
+ spans2Clear.add(new int[] {(int) positions.getStartPosition(topLevel, node),
+ (int) positions.getEndPosition(topLevel, node)});
+ }
+
+ static JavaFileObject clearAnnotations(Trees trees, CompilationUnitTree cut)
+ throws IOException {
+ ClearAnnotations a = new ClearAnnotations(trees);
+ a.scan(cut, null);
+ Collections.sort(a.spans2Clear, (s1, s2) -> s2[0] - s1[0]);
+ StringBuilder result = new StringBuilder(cut.getSourceFile().getCharContent(true));
+ for (int[] toClear : a.spans2Clear) {
+ result.delete(toClear[0], toClear[1]);
+ }
+ return new TestJavaFileObject(cut.getSourceFile().toUri(), result.toString());
+ }
+
+ }
+
+ static final class PhaseDescription {
+ final String flatname;
+ final Phase phase;
+
+ public PhaseDescription(String flatname, Phase phase) {
+ this.flatname = flatname;
+ this.phase = phase;
+ }
+
+ @Override
+ public String toString() {
+ return "@annotations.TriggersComplete(of=" + flatname + ".class," +
+ "at=annotations.Phase." + phase + ')';
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 89 * hash + Objects.hashCode(this.flatname);
+ hash = 89 * hash + Objects.hashCode(this.phase);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final PhaseDescription other = (PhaseDescription) obj;
+ if (!Objects.equals(this.flatname, other.flatname)) {
+ return false;
+ }
+ if (this.phase != other.phase) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+
+ static final class TestJavaFileObject extends SimpleJavaFileObject {
+ private final String content;
+
+ public TestJavaFileObject(URI uri, String content) {
+ super(uri, Kind.SOURCE);
+ this.content = content;
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return content;
+ }
+
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/annotations/Phase.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package annotations;
+
+import com.sun.tools.javac.util.Dependencies.CompletionCause;
+
+public enum Phase {
+ IMPORTS(CompletionCause.IMPORTS_PHASE),
+ HIERARCHY(CompletionCause.HIERARCHY_PHASE),
+ HEADER(CompletionCause.HEADER_PHASE),
+ MEMBERS(CompletionCause.MEMBERS_PHASE);
+
+ public final CompletionCause cause;
+
+ private Phase(CompletionCause cause) {
+ this.cause = cause;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/annotations/TriggersComplete.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+package annotations;
+
+import java.lang.annotation.Repeatable;
+
+@Repeatable(TriggersCompleteRepeat.class)
+public @interface TriggersComplete {
+ public Class<?> of();
+ public Phase at();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/annotations/TriggersCompleteRepeat.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package annotations;
+
+public @interface TriggersCompleteRepeat {
+ TriggersComplete[] value();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/ImportResolvedTooSoon.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,41 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+import annotations.*;
+
+import static pkg.B.SubInner.Foo;
+
+@TriggersComplete(of=A.class, at=Phase.HIERARCHY)
+@TriggersComplete(of=B.SubInner.class, at=Phase.IMPORTS)
+class B extends A {
+ @TriggersComplete(of=A.Inner.class, at=Phase.HIERARCHY)
+ static class SubInner extends Inner { }
+}
+
+class A {
+ static class Inner {
+ static class Foo { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/Simple.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,33 @@
+/*
+ * 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 annotations.*;
+
+@TriggersComplete(of = Bar.class, at = Phase.HEADER)
+@TriggersComplete(of = Sup.class, at = Phase.HIERARCHY)
+class Foo<X extends Bar> extends Sup {
+}
+class Bar {
+}
+class Sup {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/T7101822/T7101822.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+package a;
+
+import annotations.*;
+
+import a.T7101822.B.C;
+import z.T7101822Aux;
+
+@TriggersComplete(of=T7101822.B.class, at=Phase.IMPORTS)
+public class T7101822 {
+
+ @TriggersComplete(of=z.T7101822Aux.class, at=Phase.HIERARCHY)
+ class B extends T7101822Aux {
+
+ class C {
+ }
+ }
+
+ class D {
+
+ Class foo() {
+ return C.class;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/T7101822/T7101822Aux.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ */
+
+package z;
+public class T7101822Aux {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/TypeParamCycle.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+import annotations.*;
+
+import pkg.A.Outer.Inner;
+
+@TriggersComplete(of=A.Outer.class, at=Phase.IMPORTS)
+class A {
+ @TriggersComplete(of=A.Outer.Inner.class, at=Phase.HEADER)
+ static class Outer<X extends Inner> { static class Inner {} }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/TypeParamCycle2.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+import pkg.A.Outer.Inner;
+
+@annotations.TriggersComplete(of=A.class, at=annotations.Phase.IMPORTS)
+@annotations.TriggersComplete(of=A.Outer.class, at=annotations.Phase.IMPORTS)
+@annotations.TriggersComplete(of=A.Outer.Inner.class, at=annotations.Phase.HIERARCHY)
+class B extends Inner {
+}
+
+class A {
+ static class Outer<X extends Inner> { static class Inner {} }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/importscope/dependencies/tests/TypeParamCycle3.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,37 @@
+/*
+ * 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.
+ */
+
+package pkg;
+
+import static pkg.A.Outer.Inner;
+
+@annotations.TriggersComplete(of=A.Outer.class, at=annotations.Phase.IMPORTS)
+class A {
+ @annotations.TriggersComplete(of=B.class, at=annotations.Phase.HIERARCHY)
+ @annotations.TriggersComplete(of=B.Inner.class, at=annotations.Phase.HEADER)
+ static class Outer<X extends Inner> extends B { }
+}
+
+class B {
+ static class Inner {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReference/MethodRef8.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8063052
+ * @summary Inference chokes on wildcard derived from method reference
+ * @compile MethodRef8.java
+ */
+
+public class MethodRef8 {
+ void test(Box<? extends Box<? extends Number>> b) {
+ Number n1 = b.map(Box::get).get();
+ Number n2 = b.<Number>map(Box::get).get();
+ }
+
+ interface Func<S,T> { T apply(S arg); }
+
+ interface Box<T> {
+ T get();
+ <R> Box<R> map(Func<T,R> f);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection1.java Thu Dec 04 15:22:53 2014 -0800
@@ -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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8058112
+ * @summary Invalid BootstrapMethod for constructor/method reference
+ */
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+public class MethodReferenceIntersection1 {
+
+ public static void main(String[] args) {
+ MethodReferenceIntersection1 main = new MethodReferenceIntersection1();
+ List<Info_MRI1> list = main.toInfoListError(Arrays.asList(new Base_MRI1()));
+ System.out.printf("result %d\n", list.size());
+ }
+
+ public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListError(List<H> list) {
+ Comparator<B_MRI1> byNameComparator =
+ (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB());
+ return list.stream().sorted(byNameComparator).map(Info_MRI1::new).collect(toList());
+ }
+
+ public <H extends B_MRI1 & A_MRI1> List<Info_MRI1> toInfoListWorks(List<H> list) {
+ Comparator<B_MRI1> byNameComparator =
+ (B_MRI1 b1, B_MRI1 b2) -> b1.getB().compareToIgnoreCase(b2.getB());
+ return list.stream().sorted(byNameComparator).map(s -> new Info_MRI1(s)).collect(toList());
+ }
+}
+
+interface B_MRI1 {
+ public String getB();
+}
+
+interface A_MRI1 {
+ public long getA();
+}
+
+class Info_MRI1 {
+ private final long a;
+ private final String b;
+
+ <H extends A_MRI1 & B_MRI1> Info_MRI1(H h) {
+ a = h.getA();
+ b = h.getB();
+ }
+}
+
+class Base_MRI1 implements A_MRI1, B_MRI1 {
+
+ @Override
+ public long getA() {
+ return 7L;
+ }
+
+ @Override
+ public String getB() {
+ return "hello";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection2.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,68 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8058112
+ * @summary Invalid BootstrapMethod for constructor/method reference
+ */
+
+import java.util.function.Function;
+
+public class MethodReferenceIntersection2 {
+
+ interface B { }
+
+ interface A { }
+
+ static class C implements A, B { }
+
+ static class Info {
+ <H extends A & B> Info(H h) { }
+
+ static <H extends A & B> Info info(H h) {
+ return new Info(h);
+ }
+ }
+
+ public static void main(String[] args) {
+ test();
+ }
+
+ // Note the switch in order compared to that on Info
+ static <H extends B & A> void test() {
+ Function<H, Info> f1L = _h -> new Info(_h);
+ Function<H, Info> f1 = Info::new;
+ Function<H, Info> f2L = _h -> Info.info(_h);
+ Function<H, Info> f2 = Info::info;
+ H c = (H) new C();
+ if(f1.apply(c) instanceof Info &&
+ f2.apply(c) instanceof Info) {
+ System.out.println("Passes.");
+ } else {
+ throw new AssertionError();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/methodReferenceExecution/MethodReferenceIntersection3.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,50 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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 8058112
+ * @summary Invalid BootstrapMethod for constructor/method reference
+ */
+
+/**
+ * @author Remi Forax
+ */
+
+public class MethodReferenceIntersection3 {
+ interface A {}
+
+ interface Foo {
+ <T extends Object & A> void foo(T t);
+ }
+
+ static <T extends A> void bar(T t) {
+ }
+
+ public static void main(String[] args) {
+ Foo foo = MethodReferenceIntersection3::bar;
+ foo.foo(new A(){});
+ }
+}
--- a/langtools/test/tools/javac/lib/DPrinter.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/lib/DPrinter.java Thu Dec 04 15:22:53 2014 -0800
@@ -398,8 +398,8 @@
}
out.println();
} else if (FILTER_SCOPE_CLASS.equals(scope.getClass().getName())) {
- printScope("delegate",
- (Scope) getField(scope, scope.getClass(), "delegate"), Details.FULL);
+ printScope("origin",
+ (Scope) getField(scope, scope.getClass(), "origin"), Details.FULL);
} else if (scope instanceof CompoundScope) {
printList("delegates", (List<?>) getField(scope, CompoundScope.class, "subScopes"));
} else {
--- a/langtools/test/tools/javac/links/LinksTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/links/LinksTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -30,6 +30,7 @@
* @run main LinksTest
*/
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
@@ -48,17 +49,24 @@
ToolBox tb = new ToolBox();
tb.writeFile("tmp/B.java", BSrc);
+ // Try to set up a symbolic link for the test.
try {
Files.createSymbolicLink(Paths.get("a"), Paths.get("tmp"));
+ System.err.println("Created symbolic link");
+ } catch (UnsupportedOperationException | IOException e) {
+ System.err.println("Problem creating symbolic link: " + e);
+ System.err.println("Test cannot continue; test passed by default");
+ return;
+ }
- tb.new JavacTask()
- .sourcepath(".")
- .outdir(".")
- .sources(TSrc)
- .run();
- } catch (UnsupportedOperationException e) {
- System.err.println("Symbolic links not supported on this system. The test can't finish");
- }
+ // If symbolic link was successfully created,
+ // try a compilation that will use it.
+ tb.new JavacTask()
+ .sourcepath(".")
+ .outdir(".")
+ .sources(TSrc)
+ .run()
+ .writeAll();
}
}
--- a/langtools/test/tools/javac/main/Option_J_At_Test.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/main/Option_J_At_Test.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,7 +1,3 @@
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-
/*
* Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -31,6 +27,9 @@
* @summary extra space in javac -help for -J and @ options
*/
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
public class Option_J_At_Test {
public static void main(String... args) throws Exception {
new Option_J_At_Test().run();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/main/T8058445.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,35 @@
+/*
+ * 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 8058445
+ * @summary javac throws exception when displaying info
+ */
+
+public class T8058445 {
+ public static void main(String... ignore) throws Exception {
+ String[] args = { };
+ com.sun.tools.javac.Main.compile(args);
+ }
+}
--- a/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -88,7 +88,7 @@
if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
JavacTool compiler = JavacTool.create();
JavacFileManager fm = compiler.getStandardFileManager(null, null, null);
- testContent = fm.getRegularFile(testFile).getCharContent(true).toString();
+ testContent = fm.getRegularFile(testFile.toPath()).getCharContent(true).toString();
JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent);
TestFM testFileManager = new TestFM(fm);
JavacTask task = compiler.getTask(null,
--- a/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/processing/errors/StopOnInapplicableAnnotations/Processor.java Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -71,7 +71,7 @@
File inp = new File(sp, args[0]);
if (inp.canRead()) {
- testContent = fm.getRegularFile(inp).getCharContent(true).toString();
+ testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
}
}
if (testContent == null) throw new IllegalStateException();
@@ -167,4 +167,4 @@
}
}
-}
\ No newline at end of file
+}
--- a/langtools/test/tools/javac/processing/model/util/elements/Foo.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/processing/model/util/elements/Foo.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
--- a/langtools/test/tools/javac/scope/HashCollisionTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/scope/HashCollisionTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -55,6 +55,7 @@
names = Names.instance(context); // Name.Table impls tied to an instance of Names
symtab = Symtab.instance(context);
trees = JavacTrees.instance(context);
+ types = Types.instance(context);
// determine hashMask for an empty scope
Scope emptyScope = WriteableScope.create(symtab.unnamedPackage); // any owner will do
@@ -121,12 +122,12 @@
return sym.kind == TYP;
}
};
- starImportScope.importAll(fromScope, fromScope, typeFilter, false);
+ starImportScope.importAll(types, fromScope, typeFilter, false);
dump("imported p", starImportScope);
// 7. Insert the class from 3.
- starImportScope.importAll(cc.members_field, cc.members_field, typeFilter, false);
+ starImportScope.importAll(types, cc.members_field, typeFilter, false);
dump("imported ce", starImportScope);
/*
@@ -196,4 +197,5 @@
Names names;
Symtab symtab;
Trees trees;
+ Types types;
}
--- a/langtools/test/tools/javac/scope/StarImportTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/scope/StarImportTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -135,6 +135,7 @@
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);
+ types = Types.instance(context);
int setupCount = rgen.nextInt(MAX_SETUP_COUNT);
for (int i = 0; i < setupCount; i++) {
switch (random(SetupKind.values())) {
@@ -204,7 +205,7 @@
}
/**
- * Create a star-import scope and a model therof, from the packages and
+ * Create a star-import scope and a model thereof, from the packages and
* classes created by setupPackages and setupClasses.
* @throws Exception for fatal errors, such as from reflection
*/
@@ -218,7 +219,7 @@
for (Symbol imp: imports) {
Scope members = imp.members();
// log("importAll", members);
- starImportScope.importAll(members, members, new ImportFilter() {
+ starImportScope.importAll(types, members, new ImportFilter() {
@Override
public boolean accepts(Scope origin, Symbol t) {
return t.kind == TYP;
@@ -292,6 +293,7 @@
Context context;
Symtab symtab;
Names names;
+ Types types;
int nextNameSerial;
List<PackageSymbol> packages = new ArrayList<PackageSymbol>();
int nextPackageSerial;
--- a/langtools/test/tools/javac/unicode/SupplementaryJavaID6.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/unicode/SupplementaryJavaID6.java Thu Dec 04 15:22:53 2014 -0800
@@ -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
@@ -26,7 +26,8 @@
* @bug 4914724 4973116 5014511
* @summary Ensure that a supplementary character can be used as part/whole of a
* class name on platforms that have Unicode aware filesystems.
- * @run main SupplementaryJavaID6
+ * @build Wrapper
+ * @run main Wrapper SupplementaryJavaID6
*/
public class SupplementaryJavaID6 {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/unicode/Wrapper.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,78 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.File;
+import java.lang.reflect.Method;
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+
+
+public class Wrapper {
+ public static void main(String... args) throws Exception {
+ if (!isSupplementaryCharactersSupported()) {
+ System.out.println("Unicode supplementary characters in filenames not supported: pass by default");
+ return;
+ }
+
+ String testClassName = args[0];
+ String[] testArgs = Arrays.copyOfRange(args, 1, args.length);
+
+ File srcDir = new File(System.getProperty("test.src"));
+ File clsDir = new File(System.getProperty("test.classes"));
+
+ File src = new File(srcDir, testClassName + ".java");
+ File cls = new File(clsDir, testClassName + ".class");
+
+ if (cls.lastModified() < src.lastModified()) {
+ System.err.println("Recompiling test class...");
+ String[] javacArgs = { "-d", clsDir.getPath(), src.getPath() };
+ int rc = com.sun.tools.javac.Main.compile(javacArgs);
+ if (rc != 0)
+ throw new Exception("compilation failed");
+ }
+
+ Class<?> mainClass = Class.forName(testClassName);
+ Method main = mainClass.getMethod("main", String[].class);
+ main.invoke(null, new Object[] { testArgs });
+ }
+
+ private static boolean isSupplementaryCharactersSupported() {
+ try {
+ String s = "p--\ud801\udc00--";
+ System.err.println("Trying: Paths.get(" + s + ")");
+ Path p1 = Paths.get(s);
+ System.err.println("Found: " + p1);
+ System.err.println("Trying: p1.resolve(" + s + ")");
+ Path p2 = p1.resolve(s);
+ System.err.println("Found: " + p2);
+ return p1.toString().equals(s) && p2.toString().equals(s + java.io.File.separator + s);
+ } catch (InvalidPathException e) {
+ System.err.println(e);
+ return false;
+ }
+ }
+}
--- a/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/6594914/ImplicitCompilation.java Thu Dec 04 15:22:53 2014 -0800
@@ -3,9 +3,9 @@
* @bug 8020586
* @summary Warnings in the imports section should be attributed to the correct source file
* @clean Auxiliary ImplicitCompilation
- * @compile/ref=ImplicitCompilation.out -XDrawDiagnostics -Xlint:deprecation -sourcepath . ImplicitCompilation.java
+ * @compile/ref=ImplicitCompilation.out -source 8 -XDrawDiagnostics -Xlint:deprecation,-options -sourcepath . ImplicitCompilation.java
* @clean Auxiliary ImplicitCompilation
- * @compile/ref=ExplicitCompilation.out -XDrawDiagnostics -Xlint:deprecation ImplicitCompilation.java Auxiliary.java
+ * @compile/ref=ExplicitCompilation.out -source 8 -XDrawDiagnostics -Xlint:deprecation,-options ImplicitCompilation.java Auxiliary.java
*/
public class ImplicitCompilation {
--- a/langtools/test/tools/javac/warnings/Deprecation.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/Deprecation.java Thu Dec 04 15:22:53 2014 -0800
@@ -1,11 +1,13 @@
/**
* @test /nodynamiccopyright/
- * @bug 4986256
- * @compile/ref=Deprecation.noLint.out -XDrawDiagnostics Deprecation.java
- * @compile/ref=Deprecation.lintDeprecation.out -Xlint:deprecation -XDrawDiagnostics Deprecation.java
- * @compile/ref=Deprecation.lintAll.out -Xlint:all,-path -XDrawDiagnostics Deprecation.java
+ * @bug 4986256 6598104 8032211
+ * @compile/ref=Deprecation.noLint.out -XDrawDiagnostics Deprecation.java
+ * @compile/ref=Deprecation.lintDeprecation.out -Xlint:deprecation -XDrawDiagnostics Deprecation.java
+ * @compile/ref=Deprecation.lintDeprecation8.out -Xlint:deprecation,-options -source 8 -XDrawDiagnostics Deprecation.java
*/
+import java.io.StringBufferInputStream;
+
@Deprecated
class Deprecation
{
--- a/langtools/test/tools/javac/warnings/Deprecation.lintAll.out Thu Dec 04 12:58:21 2014 -0800
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-Deprecation.java:18:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
-Deprecation.java:55:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
-2 warnings
--- a/langtools/test/tools/javac/warnings/Deprecation.lintDeprecation.out Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/Deprecation.lintDeprecation.out Thu Dec 04 15:22:53 2014 -0800
@@ -1,3 +1,3 @@
-Deprecation.java:18:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
-Deprecation.java:55:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
+Deprecation.java:20:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
+Deprecation.java:57:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/Deprecation.lintDeprecation8.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,4 @@
+Deprecation.java:9:15: compiler.warn.has.been.deprecated: java.io.StringBufferInputStream, java.io
+Deprecation.java:20:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
+Deprecation.java:57:24: compiler.warn.has.been.deprecated: Deprecation, compiler.misc.unnamed.package
+3 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/NestedDeprecation/NestedDeprecation.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,29 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 6598104 8032211
+ * @build p.Dep1 p.Dep2
+ * @compile/ref=NestedDeprecation.out -Xlint:deprecation -XDrawDiagnostics NestedDeprecation.java
+ */
+
+package p;
+
+import p.Dep1.A;
+import static p.Dep1.B;
+import static p.Dep1.method;
+import static p.Dep1.field;
+import p.Dep2.C;
+import p.Dep2.D;
+
+class NestedDeprecation {
+ Dep1 f1;
+ A f2;
+ Dep2 f3;
+ B f4;
+ C f5;
+ D f6;
+
+ static {
+ method();
+ String f = field;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/NestedDeprecation/NestedDeprecation.out Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,9 @@
+NestedDeprecation.java:14:9: compiler.warn.has.been.deprecated: p.Dep2, p
+NestedDeprecation.java:15:9: compiler.warn.has.been.deprecated: p.Dep2, p
+NestedDeprecation.java:19:5: compiler.warn.has.been.deprecated: p.Dep1.A, p.Dep1
+NestedDeprecation.java:20:5: compiler.warn.has.been.deprecated: p.Dep2, p
+NestedDeprecation.java:21:5: compiler.warn.has.been.deprecated: p.Dep1.B, p.Dep1
+NestedDeprecation.java:23:5: compiler.warn.has.been.deprecated: p.Dep2.D, p.Dep2
+NestedDeprecation.java:26:9: compiler.warn.has.been.deprecated: method(), p.Dep1
+NestedDeprecation.java:27:20: compiler.warn.has.been.deprecated: field, p.Dep1
+8 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/NestedDeprecation/p/Dep1.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,12 @@
+package p;
+
+class Dep1 {
+ @Deprecated
+ static class A { }
+ @Deprecated
+ static class B { }
+ @Deprecated
+ static void method() { }
+ @Deprecated
+ static String field;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/warnings/NestedDeprecation/p/Dep2.java Thu Dec 04 15:22:53 2014 -0800
@@ -0,0 +1,8 @@
+package p;
+
+@Deprecated
+class Dep2 {
+ class C { }
+ @Deprecated
+ class D { }
+}
--- a/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/suppress/ImplicitTest.java Thu Dec 04 15:22:53 2014 -0800
@@ -27,5 +27,5 @@
* @summary Verify that deprecated warning is printed correctly for import
* statement when processing a file on demand while attributing another file.
* @clean pack.ImplicitUse pack.ImplicitMain pack.Dep
- * @compile/ref=ImplicitTest.out -XDrawDiagnostics -Xlint:deprecation pack/ImplicitMain.java
+ * @compile/ref=ImplicitTest.out -source 8 -XDrawDiagnostics -Xlint:deprecation,-options pack/ImplicitMain.java
*/
--- a/langtools/test/tools/javac/warnings/suppress/PackageInfo.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/suppress/PackageInfo.java Thu Dec 04 15:22:53 2014 -0800
@@ -26,5 +26,5 @@
* @bug 8021112
* @summary Verify that deprecated warnings are printed correctly for package-info.java
* @clean pack.package-info pack.DeprecatedClass
- * @compile/ref=PackageInfo.out -XDrawDiagnostics -Xlint:deprecation pack/package-info.java pack/DeprecatedClass.java
+ * @compile/ref=PackageInfo.out -source 8 -XDrawDiagnostics -Xlint:deprecation,-options pack/package-info.java pack/DeprecatedClass.java
*/
--- a/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Thu Dec 04 12:58:21 2014 -0800
+++ b/langtools/test/tools/javac/warnings/suppress/VerifySuppressWarnings.java Thu Dec 04 15:22:53 2014 -0800
@@ -74,7 +74,7 @@
File inp = new File(sp, args[0]);
if (inp.canRead()) {
- testContent = fm.getRegularFile(inp).getCharContent(true).toString();
+ testContent = fm.getRegularFile(inp.toPath()).getCharContent(true).toString();
}
}
if (testContent == null) throw new IllegalStateException();