7192246: Add type-checking support for default methods
Summary: Add type-checking support for default methods as per Featherweight-Defender document
Reviewed-by: jjg, dlsmith
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Sun Nov 04 10:59:42 2012 +0000
@@ -67,7 +67,6 @@
if ((mask&NATIVE) != 0) flags.add(Flag.NATIVE);
if ((mask&INTERFACE) != 0) flags.add(Flag.INTERFACE);
if ((mask&ABSTRACT) != 0) flags.add(Flag.ABSTRACT);
- if ((mask&DEFAULT) != 0) flags.add(Flag.DEFAULT);
if ((mask&STRICTFP) != 0) flags.add(Flag.STRICTFP);
if ((mask&BRIDGE) != 0) flags.add(Flag.BRIDGE);
if ((mask&SYNTHETIC) != 0) flags.add(Flag.SYNTHETIC);
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Sun Nov 04 10:59:42 2012 +0000
@@ -206,6 +206,9 @@
public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0;
}
+ public boolean allowStrictMethodClashCheck() {
+ return compareTo(JDK1_8) >= 0;
+ }
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Sun Nov 04 10:59:42 2012 +0000
@@ -1192,9 +1192,9 @@
// check for an inherited implementation
if ((flags() & ABSTRACT) != 0 ||
- (other.flags() & ABSTRACT) == 0 ||
- !other.isOverridableIn(origin) ||
- !this.isMemberOf(origin, types))
+ (other.flags() & ABSTRACT) == 0 ||
+ !other.isOverridableIn(origin) ||
+ !this.isMemberOf(origin, types))
return false;
// assert types.asSuper(origin.type, other.owner) != null;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Sun Nov 04 10:59:42 2012 +0000
@@ -75,6 +75,7 @@
final boolean allowBoxing;
final boolean allowCovariantReturns;
final boolean allowObjectToPrimitiveCast;
+ final boolean allowDefaultMethods;
final ClassReader reader;
final Check chk;
JCDiagnostic.Factory diags;
@@ -98,6 +99,7 @@
allowBoxing = source.allowBoxing();
allowCovariantReturns = source.allowCovariantReturns();
allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
+ allowDefaultMethods = source.allowDefaultMethods();
reader = ClassReader.instance(context);
chk = Check.instance(context);
capturedName = names.fromString("<captured wildcard>");
@@ -2146,6 +2148,13 @@
return List.nil();
}
};
+
+ public boolean isDirectSuperInterface(Type t, TypeSymbol tsym) {
+ for (Type t2 : interfaces(tsym.type)) {
+ if (isSameType(t, t2)) return true;
+ }
+ return false;
+ }
// </editor-fold>
// <editor-fold defaultstate="collapsed" desc="isDerivedRaw">
@@ -2310,6 +2319,10 @@
return false;
}
+ public boolean overridesObjectMethod(Symbol msym) {
+ return ((MethodSymbol)msym).implementation(syms.objectType.tsym, this, true) != null;
+ }
+
// <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
class ImplementationCache {
@@ -2455,6 +2468,70 @@
}
// </editor-fold>
+
+ //where
+ public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms) {
+ return interfaceCandidates(site, ms, false);
+ }
+
+ public List<MethodSymbol> interfaceCandidates(Type site, MethodSymbol ms, boolean intfOnly) {
+ Filter<Symbol> filter = new MethodFilter(ms, site, intfOnly);
+ List<MethodSymbol> candidates = List.nil();
+ for (Symbol s : membersClosure(site, false).getElements(filter)) {
+ if (!site.tsym.isInterface() && !s.owner.isInterface()) {
+ return List.of((MethodSymbol)s);
+ } else if (!candidates.contains(s)) {
+ candidates = candidates.prepend((MethodSymbol)s);
+ }
+ }
+ return prune(candidates, ownerComparator);
+ }
+
+ public List<MethodSymbol> prune(List<MethodSymbol> methods, Comparator<MethodSymbol> cmp) {
+ ListBuffer<MethodSymbol> methodsMin = ListBuffer.lb();
+ for (MethodSymbol m1 : methods) {
+ boolean isMin_m1 = true;
+ for (MethodSymbol m2 : methods) {
+ if (m1 == m2) continue;
+ if (cmp.compare(m2, m1) < 0) {
+ isMin_m1 = false;
+ break;
+ }
+ }
+ if (isMin_m1)
+ methodsMin.append(m1);
+ }
+ return methodsMin.toList();
+ }
+
+ Comparator<MethodSymbol> ownerComparator = new Comparator<MethodSymbol>() {
+ public int compare(MethodSymbol s1, MethodSymbol s2) {
+ return s1.owner.isSubClass(s2.owner, Types.this) ? -1 : 1;
+ }
+ };
+ // where
+ private class MethodFilter implements Filter<Symbol> {
+
+ Symbol msym;
+ Type site;
+ boolean intfOnly;
+
+ MethodFilter(Symbol msym, Type site, boolean intfOnly) {
+ this.msym = msym;
+ this.site = site;
+ this.intfOnly = intfOnly;
+ }
+
+ public boolean accepts(Symbol s) {
+ return s.kind == Kinds.MTH &&
+ (!intfOnly || s.owner.isInterface()) &&
+ s.name == msym.name &&
+ s.isInheritedIn(site.tsym, Types.this) &&
+ overrideEquivalent(memberType(site, s), memberType(site, msym));
+ }
+ };
+ // </editor-fold>
+
/**
* Does t have the same arguments as s? It is assumed that both
* types are (possibly polymorphic) method types. Monomorphic
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Sun Nov 04 10:59:42 2012 +0000
@@ -135,6 +135,7 @@
allowStringsInSwitch = source.allowStringsInSwitch();
allowPoly = source.allowPoly() && options.isSet("allowPoly");
allowLambda = source.allowLambda();
+ allowDefaultMethods = source.allowDefaultMethods();
sourceName = source.name;
relax = (options.isSet("-retrofit") ||
options.isSet("-relax"));
@@ -178,6 +179,10 @@
*/
boolean allowCovariantReturns;
+ /** Switch: support default methods ?
+ */
+ boolean allowDefaultMethods;
+
/** Switch: support lambda expressions ?
*/
boolean allowLambda;
@@ -898,6 +903,10 @@
localEnv.info.lint = lint;
+ if (isDefaultMethod && types.overridesObjectMethod(m)) {
+ log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location());
+ }
+
// Enter all type parameters into the local method scope.
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail)
localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
@@ -961,10 +970,12 @@
log.error(tree.pos(),
"default.allowed.in.intf.annotation.member");
}
- } else if ((owner.flags() & INTERFACE) != 0 && !isDefaultMethod) {
- log.error(tree.body.pos(), "intf.meth.cant.have.body");
- } else if ((tree.mods.flags & ABSTRACT) != 0) {
- log.error(tree.pos(), "abstract.meth.cant.have.body");
+ } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) {
+ if ((owner.flags() & INTERFACE) != 0) {
+ log.error(tree.body.pos(), "intf.meth.cant.have.body");
+ } else {
+ log.error(tree.pos(), "abstract.meth.cant.have.body");
+ }
} else if ((tree.mods.flags & NATIVE) != 0) {
log.error(tree.pos(), "native.meth.cant.have.body");
} else {
@@ -3281,6 +3292,23 @@
}
}
+ if (env.info.defaultSuperCallSite != null &&
+ !types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true).contains(sym)) {
+ Symbol ovSym = null;
+ for (MethodSymbol msym : types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true)) {
+ if (msym.overrides(sym, msym.enclClass(), types, true)) {
+ for (Type i : types.interfaces(env.enclClass.type)) {
+ if (i.tsym.isSubClass(msym.owner, types)) {
+ ovSym = i.tsym;
+ break;
+ }
+ }
+ }
+ }
+ log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite,
+ diags.fragment("overridden.default", sym, ovSym));
+ }
+
// Compute the identifier's instantiated type.
// For methods, we need to compute the instance type by
// Resolve.instantiate from the symbol's type as well as
@@ -3700,6 +3728,9 @@
// are compatible (i.e. no two define methods with same arguments
// yet different return types). (JLS 8.4.6.3)
chk.checkCompatibleSupertypes(tree.pos(), c.type);
+ if (allowDefaultMethods) {
+ chk.checkDefaultMethodClashes(tree.pos(), c.type);
+ }
}
// Check that class does not import the same parameterized interface
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Sun Nov 04 10:59:42 2012 +0000
@@ -72,6 +72,10 @@
*/
Attr.ResultInfo returnResult = null;
+ /** Symbol corresponding to the site of a qualified default super call
+ */
+ Type defaultSuperCallSite = null;
+
/** Duplicate this context, replacing scope field and copying all others.
*/
AttrContext dup(Scope scope) {
@@ -84,6 +88,7 @@
info.lint = lint;
info.enclVar = enclVar;
info.returnResult = returnResult;
+ info.defaultSuperCallSite = defaultSuperCallSite;
return info;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Sun Nov 04 10:59:42 2012 +0000
@@ -119,6 +119,9 @@
allowAnnotations = source.allowAnnotations();
allowCovariantReturns = source.allowCovariantReturns();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
+ allowDefaultMethods = source.allowDefaultMethods();
+ allowStrictMethodClashCheck = source.allowStrictMethodClashCheck() &&
+ options.isSet("strictMethodClashCheck"); //pre-lambda guard
complexInference = options.isSet("complexinference");
warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts");
suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile");
@@ -162,6 +165,14 @@
*/
boolean allowSimplifiedVarargs;
+ /** Switch: default methods enabled?
+ */
+ boolean allowDefaultMethods;
+
+ /** Switch: should unrelated return types trigger a method clash?
+ */
+ boolean allowStrictMethodClashCheck;
+
/** Switch: -complexinference option set?
*/
boolean complexInference;
@@ -1114,7 +1125,7 @@
} else if ((sym.owner.flags_field & INTERFACE) != 0) {
if ((flags & DEFAULT) != 0) {
mask = InterfaceDefaultMethodMask;
- implicit = PUBLIC;
+ implicit = PUBLIC | ABSTRACT;
} else {
mask = implicit = InterfaceMethodFlags;
}
@@ -2047,11 +2058,21 @@
undef == null && e != null;
e = e.sibling) {
if (e.sym.kind == MTH &&
- (e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) {
+ (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) {
MethodSymbol absmeth = (MethodSymbol)e.sym;
MethodSymbol implmeth = absmeth.implementation(impl, types, true);
- if (implmeth == null || implmeth == absmeth)
+ if (implmeth == null || implmeth == absmeth) {
+ //look for default implementations
+ if (allowDefaultMethods) {
+ MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head;
+ if (prov != null && prov.overrides(absmeth, impl, types, true)) {
+ implmeth = prov;
+ }
+ }
+ }
+ if (implmeth == null || implmeth == absmeth) {
undef = absmeth;
+ }
}
}
if (undef == null) {
@@ -2354,7 +2375,7 @@
if (m2 == m1) continue;
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, m2), false) &&
+ if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) &&
types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
sym.flags_field |= CLASH;
String key = m1 == sym ?
@@ -2386,7 +2407,7 @@
for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) {
//if (i) the signature of 'sym' is not a subsignature of m1 (seen as
//a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error
- if (!types.isSubSignature(sym.type, types.memberType(site, s), false) &&
+ if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) &&
types.hasSameArgs(s.erasure(types), sym.erasure(types))) {
log.error(pos,
"name.clash.same.erasure.no.hide",
@@ -2420,6 +2441,62 @@
}
}
+ void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) {
+ DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site);
+ for (Symbol m : types.membersClosure(site, false).getElements(dcf)) {
+ Assert.check(m.kind == MTH);
+ List<MethodSymbol> prov = types.interfaceCandidates(site, (MethodSymbol)m);
+ if (prov.size() > 1) {
+ ListBuffer<Symbol> abstracts = ListBuffer.lb();
+ ListBuffer<Symbol> defaults = ListBuffer.lb();
+ for (MethodSymbol provSym : prov) {
+ if ((provSym.flags() & DEFAULT) != 0) {
+ defaults = defaults.append(provSym);
+ } else if ((provSym.flags() & ABSTRACT) != 0) {
+ abstracts = abstracts.append(provSym);
+ }
+ if (defaults.nonEmpty() && defaults.size() + abstracts.size() >= 2) {
+ //strong semantics - issue an error if two sibling interfaces
+ //have two override-equivalent defaults - or if one is abstract
+ //and the other is default
+ String errKey;
+ Symbol s1 = defaults.first();
+ Symbol s2;
+ if (defaults.size() > 1) {
+ errKey = "types.incompatible.unrelated.defaults";
+ s2 = defaults.toList().tail.head;
+ } else {
+ errKey = "types.incompatible.abstract.default";
+ s2 = abstracts.first();
+ }
+ log.error(pos, errKey,
+ Kinds.kindName(site.tsym), site,
+ m.name, types.memberType(site, m).getParameterTypes(),
+ s1.location(), s2.location());
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ //where
+ private class DefaultMethodClashFilter implements Filter<Symbol> {
+
+ Type site;
+
+ DefaultMethodClashFilter(Type site) {
+ this.site = site;
+ }
+
+ public boolean accepts(Symbol s) {
+ return s.kind == MTH &&
+ (s.flags() & DEFAULT) != 0 &&
+ s.isInheritedIn(site.tsym, types) &&
+ !s.isConstructor();
+ }
+ }
+
/** Report a conflict between a user symbol and a synthetic symbol.
*/
private void syntheticError(DiagnosticPosition pos, Symbol sym) {
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Sun Nov 04 10:59:42 2012 +0000
@@ -3631,15 +3631,26 @@
public void visitSelect(JCFieldAccess tree) {
// need to special case-access of the form C.super.x
- // these will always need an access method.
+ // these will always need an access method, unless C
+ // is a default interface subclassed by the current class.
boolean qualifiedSuperAccess =
tree.selected.hasTag(SELECT) &&
- TreeInfo.name(tree.selected) == names._super;
+ TreeInfo.name(tree.selected) == names._super &&
+ !types.isDirectSuperInterface(((JCFieldAccess)tree.selected).selected.type, currentClass);
tree.selected = translate(tree.selected);
- if (tree.name == names._class)
+ if (tree.name == names._class) {
result = classOf(tree.selected);
- else if (tree.name == names._this || tree.name == names._super)
+ }
+ else if (tree.name == names._super &&
+ types.isDirectSuperInterface(tree.selected.type, currentClass)) {
+ //default super call!! Not a classic qualified super call
+ TypeSymbol supSym = tree.selected.type.tsym;
+ Assert.checkNonNull(types.asSuper(currentClass.type, supSym));
+ result = tree;
+ }
+ else if (tree.name == names._this || tree.name == names._super) {
result = makeThis(tree.pos(), tree.selected.type.tsym);
+ }
else
result = access(tree.sym, tree, enclOp, qualifiedSuperAccess);
}
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Sun Nov 04 10:59:42 2012 +0000
@@ -560,6 +560,12 @@
MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner);
m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree);
tree.sym = m;
+
+ //if this is a default method, add the DEFAULT flag to the enclosing interface
+ if ((tree.mods.flags & DEFAULT) != 0) {
+ m.enclClass().flags_field |= DEFAULT;
+ }
+
Env<AttrContext> localEnv = methodEnv(tree, env);
DeferredLintHandler prevLintHandler =
@@ -677,7 +683,7 @@
localEnv.info.scope.owner = tree.sym;
}
if ((tree.mods.flags & STATIC) != 0 ||
- (env.enclClass.sym.flags() & INTERFACE) != 0)
+ ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null))
localEnv.info.staticLevel++;
return localEnv;
}
@@ -1001,20 +1007,19 @@
}
}
- // If this is a class, enter symbols for this and super into
- // current scope.
- if ((c.flags_field & INTERFACE) == 0) {
- VarSymbol thisSym =
- new VarSymbol(FINAL | HASINIT, names._this, c.type, c);
- thisSym.pos = Position.FIRSTPOS;
- env.info.scope.enter(thisSym);
- if (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);
- }
+ // 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,
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Sun Nov 04 10:59:42 2012 +0000
@@ -52,6 +52,7 @@
import java.util.EnumSet;
import java.util.Iterator;
import java.util.Map;
+import java.util.Set;
import javax.lang.model.element.ElementVisitor;
@@ -88,6 +89,7 @@
public final boolean boxingEnabled; // = source.allowBoxing();
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
+ public final boolean allowDefaultMethods;
private final boolean debugResolve;
final EnumSet<VerboseResolutionMode> verboseResolutionMode;
@@ -122,6 +124,7 @@
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
+ allowDefaultMethods = source.allowDefaultMethods();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@@ -1327,6 +1330,42 @@
}
}
+ Symbol lookupMethod(Env<AttrContext> env,
+ Type site,
+ Name name,
+ List<Type> argtypes,
+ List<Type> typeargtypes,
+ Scope sc,
+ Symbol bestSoFar,
+ boolean allowBoxing,
+ boolean useVarargs,
+ boolean operator,
+ boolean abstractok) {
+ for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
+ bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
+ bestSoFar, allowBoxing, useVarargs, operator);
+ }
+ return bestSoFar;
+ }
+ //where
+ class LookupFilter implements Filter<Symbol> {
+
+ boolean abstractOk;
+
+ LookupFilter(boolean abstractOk) {
+ this.abstractOk = abstractOk;
+ }
+
+ public boolean accepts(Symbol s) {
+ long flags = s.flags();
+ return s.kind == MTH &&
+ (flags & SYNTHETIC) == 0 &&
+ (abstractOk ||
+ (flags & DEFAULT) != 0 ||
+ (flags & ABSTRACT) == 0);
+ }
+ };
+
/** Find best qualified method matching given name, type and value
* arguments.
* @param env The current environment.
@@ -1371,49 +1410,76 @@
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
- boolean abstractOk = true;
- List<Type> itypes = List.nil();
+ @SuppressWarnings({"unchecked","rawtypes"})
+ List<Type>[] itypes = (List<Type>[])new List[] { List.<Type>nil(), List.<Type>nil() };
+ InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
for (TypeSymbol s : superclasses(intype)) {
bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- //We should not look for abstract methods if receiver is a concrete class
- //(as concrete classes are expected to implement all abstracts coming
- //from superinterfaces)
- abstractOk &= (s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0;
- if (abstractOk) {
+ if (name == names.init) return bestSoFar;
+ iphase = (iphase == null) ? null : iphase.update(s, this);
+ if (iphase != null) {
for (Type itype : types.interfaces(s.type)) {
- itypes = types.union(types.closure(itype), itypes);
+ itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
}
}
- if (name == names.init) break;
}
Symbol concrete = bestSoFar.kind < ERR &&
(bestSoFar.flags() & ABSTRACT) == 0 ?
bestSoFar : methodNotFound;
- if (name != names.init) {
+ for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break;
//keep searching for abstract methods
- for (Type itype : itypes) {
+ for (Type itype : itypes[iphase2.ordinal()]) {
if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
+ (itype.tsym.flags() & DEFAULT) == 0) continue;
bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
- itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- if (concrete != bestSoFar &&
- concrete.kind < ERR && bestSoFar.kind < ERR &&
- types.isSubSignature(concrete.type, bestSoFar.type)) {
- //this is an hack - as javac does not do full membership checks
- //most specific ends up comparing abstract methods that might have
- //been implemented by some concrete method in a subclass and,
- //because of raw override, it is possible for an abstract method
- //to be more specific than the concrete method - so we need
- //to explicitly call that out (see CR 6178365)
- bestSoFar = concrete;
- }
+ itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
+ if (concrete != bestSoFar &&
+ concrete.kind < ERR && bestSoFar.kind < ERR &&
+ types.isSubSignature(concrete.type, bestSoFar.type)) {
+ //this is an hack - as javac does not do full membership checks
+ //most specific ends up comparing abstract methods that might have
+ //been implemented by some concrete method in a subclass and,
+ //because of raw override, it is possible for an abstract method
+ //to be more specific than the concrete method - so we need
+ //to explicitly call that out (see CR 6178365)
+ bestSoFar = concrete;
+ }
}
}
return bestSoFar;
}
+ enum InterfaceLookupPhase {
+ ABSTRACT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ //We should not look for abstract methods if receiver is a concrete class
+ //(as concrete classes are expected to implement all abstracts coming
+ //from superinterfaces)
+ if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
+ return this;
+ } else if (rs.allowDefaultMethods) {
+ return DEFAULT_OK;
+ } else {
+ return null;
+ }
+ }
+ },
+ DEFAULT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ return this;
+ }
+ };
+
+ abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
+ }
+
/**
* Return an Iterable object to scan the superclasses of a given type.
* It's crucial that the scan is done lazily, as we don't want to accidentally
@@ -1467,34 +1533,6 @@
};
}
- /**
- * Lookup a method with given name and argument types in a given scope
- */
- Symbol lookupMethod(Env<AttrContext> env,
- Type site,
- Name name,
- List<Type> argtypes,
- List<Type> typeargtypes,
- Scope sc,
- Symbol bestSoFar,
- boolean allowBoxing,
- boolean useVarargs,
- boolean operator,
- boolean abstractok) {
- for (Symbol s : sc.getElementsByName(name, lookupFilter)) {
- bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
- bestSoFar, allowBoxing, useVarargs, operator);
- }
- return bestSoFar;
- }
- //where
- Filter<Symbol> lookupFilter = new Filter<Symbol>() {
- public boolean accepts(Symbol s) {
- return s.kind == MTH &&
- (s.flags() & SYNTHETIC) == 0;
- }
- };
-
/** Find unqualified method matching given name, type and value arguments.
* @param env The current environment.
* @param name The method's name.
@@ -1920,7 +1958,7 @@
/** Check that sym is not an abstract method.
*/
void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
- if ((sym.flags() & ABSTRACT) != 0)
+ if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
log.error(pos, "abstract.cant.be.accessed.directly",
kindName(sym), sym, sym.location());
}
@@ -2744,9 +2782,47 @@
if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
env1 = env1.outer;
}
+ if (allowDefaultMethods && c.isInterface() &&
+ name == names._super && !isStatic(env) &&
+ types.isDirectSuperInterface(c.type, env.enclClass.sym)) {
+ //this might be a default super call if one of the superinterfaces is 'c'
+ for (Type t : pruneInterfaces(env.enclClass.type)) {
+ if (t.tsym == c) {
+ env.info.defaultSuperCallSite = t;
+ return new VarSymbol(0, names._super,
+ types.asSuper(env.enclClass.type, c), env.enclClass.sym);
+ }
+ }
+ //find a direct superinterface that is a subtype of 'c'
+ for (Type i : types.interfaces(env.enclClass.type)) {
+ if (i.tsym.isSubClass(c, types) && i.tsym != c) {
+ log.error(pos, "illegal.default.super.call", c,
+ diags.fragment("redundant.supertype", c, i));
+ return syms.errSymbol;
+ }
+ }
+ Assert.error();
+ }
log.error(pos, "not.encl.class", c);
return syms.errSymbol;
}
+ //where
+ private List<Type> pruneInterfaces(Type t) {
+ ListBuffer<Type> result = ListBuffer.lb();
+ for (Type t1 : types.interfaces(t)) {
+ boolean shouldAdd = true;
+ for (Type t2 : types.interfaces(t)) {
+ if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
+ shouldAdd = false;
+ }
+ }
+ if (shouldAdd) {
+ result.append(t1);
+ }
+ }
+ return result.toList();
+ }
+
/**
* Resolve `c.this' for an enclosing class c that contains the
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Sun Nov 04 10:59:42 2012 +0000
@@ -115,6 +115,9 @@
*/
boolean lintClassfile;
+ /** Switch: allow default methods
+ */
+ boolean allowDefaultMethods;
/** Switch: preserve parameter names from the variable table.
*/
@@ -279,6 +282,7 @@
allowVarargs = source.allowVarargs();
allowAnnotations = source.allowAnnotations();
allowSimplifiedVarargs = source.allowSimplifiedVarargs();
+ allowDefaultMethods = source.allowDefaultMethods();
saveParameterNames = options.isSet("save-parameter-names");
cacheCompletionFailure = options.isUnset("dev");
preferSource = "source".equals(options.get("-Xprefer"));
@@ -937,6 +941,18 @@
new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) {
protected void read(Symbol sym, int attrLen) {
+ if (currentOwner.isInterface() &&
+ (sym.flags_field & ABSTRACT) == 0 && !name.equals(names.clinit)) {
+ if (majorVersion > Target.JDK1_8.majorVersion ||
+ //todo replace with Target.Version when available
+ (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) {
+ currentOwner.flags_field |= DEFAULT;
+ sym.flags_field |= DEFAULT | ABSTRACT;
+ } else {
+ //protect against ill-formed classfiles
+ throw new CompletionFailure(currentOwner, "default method found in pre JDK 8 classfile");
+ }
+ }
if (readAllOfClassFile || saveParameterNames)
((MethodSymbol)sym).code = readCode(sym);
else
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Sun Nov 04 10:59:42 2012 +0000
@@ -1540,7 +1540,7 @@
List<Type> interfaces = types.interfaces(c.type);
List<Type> typarams = c.type.getTypeArguments();
- int flags = adjustFlags(c.flags());
+ int flags = adjustFlags(c.flags() & ~DEFAULT);
if ((flags & PROTECTED) != 0) flags |= PUBLIC;
flags = flags & ClassFlags & ~STRICTFP;
if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
@@ -1676,6 +1676,8 @@
result |= ACC_BRIDGE;
if ((flags & VARARGS) != 0 && target.useVarargsFlag())
result |= ACC_VARARGS;
+ if ((flags & DEFAULT) != 0)
+ result &= ~ABSTRACT;
return result;
}
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Sun Nov 04 10:59:42 2012 +0000
@@ -523,7 +523,7 @@
Item invoke() {
MethodType mtype = (MethodType)member.externalType(types);
int rescode = Code.typecode(mtype.restype);
- if ((member.owner.flags() & Flags.INTERFACE) != 0) {
+ if ((member.owner.flags() & Flags.INTERFACE) != 0 && !nonvirtual) {
code.emitInvokeinterface(pool.put(member), mtype);
} else if (nonvirtual) {
code.emitInvokespecial(pool.put(member), mtype);
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Sun Nov 04 10:59:42 2012 +0000
@@ -574,7 +574,7 @@
interface expected here
compiler.err.intf.meth.cant.have.body=\
- interface methods cannot have body
+ interface abstract methods cannot have body
compiler.err.invalid.annotation.member.type=\
invalid type for annotation member
@@ -941,6 +941,31 @@
compiler.err.types.incompatible.diff.ret=\
types {0} and {1} are incompatible; both define {2}, but with unrelated return types
+# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol
+compiler.err.types.incompatible.unrelated.defaults=\
+ {0} {1} inherits unrelated defaults for {2}({3}) from types {4} and {5}
+
+# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol
+compiler.err.types.incompatible.abstract.default=\
+ {0} {1} inherits abstract and default for {2}({3}) from types {4} and {5}
+
+# 0: name, 1: kind, 2: symbol
+compiler.err.default.overrides.object.member=\
+ default method {0} in {1} {2} overrides a member of java.lang.Object
+
+# 0: type, 1: message segment
+compiler.err.illegal.default.super.call=\
+ bad type qualifier {0} in default super call\n\
+ {1}
+
+# 0: symbol, 1: type
+compiler.misc.overridden.default=\
+ method {0} is overridden in {2}
+
+# 0: symbol, 1: symbol
+compiler.misc.redundant.supertype=\
+ redundant interface {0} is extended by {1}
+
compiler.err.unclosed.char.lit=\
unclosed character literal
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @summary check that default methods don't cause ClassReader to complete classes recursively
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods pkg/Foo.java
+ * @compile ClassReaderTest.java
+ */
+
+abstract class ClassReaderTest implements pkg.Foo {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package pkg;
+
+public interface Foo {
+ default void m1() { Impl.m1(this); }
+ default void m2() { Impl.m2(this); }
+}
+
+class Impl {
+ static void m1(Foo f) { }
+ static void m2(Foo f) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary negative test for ambiguous defaults
+ * @compile/fail/ref=Neg01.out -XDallowDefaultMethods -XDrawDiagnostics Neg01.java
+ */
+
+class Neg01 {
+ interface IA { default int m() { return Neg01.m1(this); } }
+ interface IB { default int m() { return Neg01.m2(this); } }
+
+ static class A implements IA {}
+ static class B implements IB {}
+
+ static class AB implements IA, IB {}
+
+ static int m1(IA a) { return 0; }
+ static int m2(IB b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg01.java:14:12: compiler.err.types.incompatible.unrelated.defaults: kindname.class, Neg01.AB, m, , Neg01.IA, Neg01.IB
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that ill-formed MI hierarchies do not compile
+ * @compile/fail/ref=Neg02.out -XDallowDefaultMethods -XDrawDiagnostics Neg02.java
+ */
+
+class Neg02 {
+ interface A {
+ default void m() { Neg02.impl(this); }
+ }
+
+ interface B {
+ default void m() { Neg02.impl(this); }
+ }
+
+ static class X implements A, B { } //error
+
+ void test(X x) {
+ x.m();
+ ((A)x).m();
+ ((B)x).m();
+ }
+
+ static void impl(A a) { }
+ static void impl(B b) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg02.java:16:13: compiler.err.types.incompatible.unrelated.defaults: kindname.class, Neg02.X, m, , Neg02.A, Neg02.B
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,38 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that re-abstraction works properly
+ * @compile/fail/ref=Neg03.out -XDallowDefaultMethods -XDrawDiagnostics Neg03.java
+ */
+
+class Neg03 {
+ interface A {
+ default void m() { Neg03.one(this); }
+ }
+
+ interface B {
+ default void m() { Neg03.two(this); }
+ }
+
+ interface C extends A, B {
+ default void m() { Neg03.one(this); }
+ }
+
+ static class X implements C, A { } //ok - ignore extraneous remix of A
+
+ interface D extends A, B {
+ void m(); // ok - m() is not reabstracted!
+ }
+
+ static class Y implements D, A { } // invalid - abstract D.m()
+
+ interface E extends A {
+ void m(); // reabstraction of m()
+ }
+
+ static class W implements D, E { } // invalid - abstracts D.m()/E.m()
+
+ static class Z implements D, A, B { } // invalid - abstract D.m()
+
+ static void one(Object a) { }
+ static void two(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,4 @@
+Neg03.java:26:12: compiler.err.does.not.override.abstract: Neg03.Y, m(), Neg03.D
+Neg03.java:32:12: compiler.err.does.not.override.abstract: Neg03.W, m(), Neg03.D
+Neg03.java:34:12: compiler.err.does.not.override.abstract: Neg03.Z, m(), Neg03.D
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default method must have most specific return type
+ * @compile/fail/ref=Neg04.out -XDallowDefaultMethods -XDrawDiagnostics Neg04.java
+ */
+
+class Neg04 {
+ interface IA1 { Integer m(); }
+ interface IA2 extends IA1 { default Number m() { return Neg04.m(this); } } //error
+
+ abstract class C implements IA1, IA2 {}
+
+ static int m(IA2 a) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg04.java:9:48: compiler.err.override.incompatible.ret: (compiler.misc.clashes.with: m(), Neg04.IA2, m(), Neg04.IA1), java.lang.Number, java.lang.Integer
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that abstract methods are compatible with inherited defaults
+ * @compile/fail/ref=Neg05.out -XDallowDefaultMethods -XDrawDiagnostics Neg05.java
+ */
+
+class Neg05 {
+ interface IA1 { default Number m() { return Neg05.m1(this); } }
+ interface IA2 extends IA1 { default Integer m() { return Neg05.m2(this); } }
+ interface IA3 extends IA2 { Number m(); } //error
+
+ static class C implements IA3{}
+
+ static int m1(IA1 a) { return 0; }
+ static int m2(IA2 b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,3 @@
+Neg05.java:10:40: compiler.err.override.incompatible.ret: (compiler.misc.clashes.with: m(), Neg05.IA3, m(), Neg05.IA2), java.lang.Number, java.lang.Integer
+Neg05.java:12:12: compiler.err.does.not.override.abstract: Neg05.C, m(), Neg05.IA3
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary flow analysis is not run on inlined default bodies
+ * @compile/fail/ref=Neg06.out -XDallowDefaultMethods -XDrawDiagnostics Neg06.java
+ */
+
+class Neg06 {
+
+ interface A {
+ default String m() { C.m(); }
+ }
+
+ static class C {
+ static String m() { return ""; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg06.java:10:37: compiler.err.missing.ret.stmt
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg07.out -XDallowDefaultMethods -XDrawDiagnostics Neg07.java
+ */
+
+class Neg07 {
+ interface I {
+ default int m() { return 1; }
+ }
+
+ static class C1 {
+ public void m() { } //incompatible return
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public void m() { } //incompatible return
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,3 @@
+Neg07.java:16:12: compiler.err.override.incompatible.ret: (compiler.misc.cant.implement: m(), Neg07.C1, m(), Neg07.I), void, int
+Neg07.java:19:21: compiler.err.override.incompatible.ret: (compiler.misc.cant.implement: m(), Neg07.C3, m(), Neg07.I), void, int
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg08.out -XDallowDefaultMethods -XDrawDiagnostics Neg08.java
+ */
+class Neg08 {
+ interface I {
+ default void m() { }
+ }
+
+ static class C1 {
+ void m() { } //weaker modifier
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ void m() { } //weaker modifier
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,3 @@
+Neg08.java:15:12: compiler.err.override.weaker.access: (compiler.misc.cant.implement: m(), Neg08.C1, m(), Neg08.I), public
+Neg08.java:18:14: compiler.err.override.weaker.access: (compiler.misc.cant.implement: m(), Neg08.C3, m(), Neg08.I), public
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,22 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg09.out -Werror -Xlint:unchecked -XDallowDefaultMethods -XDrawDiagnostics Neg09.java
+ */
+import java.util.List;
+
+class Neg09 {
+ interface I {
+ default List<String> m() { return null; }
+ }
+
+ static class C1 {
+ public List m() { return null; } //unchecked (return) override
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public List m() { return null; } //unchecked (return) override
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,5 @@
+Neg09.java:17:12: compiler.warn.override.unchecked.ret: (compiler.misc.unchecked.implement: m(), Neg09.C1, m(), Neg09.I), java.util.List, java.util.List<java.lang.String>
+Neg09.java:20:21: compiler.warn.override.unchecked.ret: (compiler.misc.unchecked.implement: m(), Neg09.C3, m(), Neg09.I), java.util.List, java.util.List<java.lang.String>
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg10.out -Werror -Xlint:unchecked -XDallowDefaultMethods -XDrawDiagnostics Neg10.java
+ */
+class Neg10 {
+ interface I<X extends Exception> {
+ default void m() throws X { }
+ }
+
+ static class C1 {
+ public void m() throws Exception { } //unchecked (throws) override
+ }
+
+ static class C2<Z extends Exception> extends C1 implements I<Z> { }
+
+ static class C3<Z extends Exception> implements I<Z> {
+ public void m() throws Exception { } //unchecked (throws) override
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,5 @@
+Neg10.java:15:12: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C1, m(), Neg10.I), java.lang.Exception
+Neg10.java:18:21: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C3, m(), Neg10.I), java.lang.Exception
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default overrides are properly type-checked
+ * @compile/fail/ref=Neg11.out -XDallowDefaultMethods -XDrawDiagnostics Neg11.java
+ */
+class Neg11 {
+ interface I {
+ default void m() { }
+ }
+
+ static class C1 {
+ public void m() throws Exception { } //bad throws
+ }
+
+ static class C2 extends C1 implements I { }
+
+ static class C3 implements I {
+ public void m() throws Exception { } //bad throws
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg11.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,3 @@
+Neg11.java:15:12: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C1, m(), Neg11.I), java.lang.Exception
+Neg11.java:18:21: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C3, m(), Neg11.I), java.lang.Exception
+2 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,27 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that abstract methods are discarded in overload resolution diags
+ * @compile/fail/ref=Neg12.out -XDallowDefaultMethods -XDrawDiagnostics Neg12.java
+ */
+class Neg12 {
+
+ interface I1 {
+ default void m(String s) {};
+ }
+
+ interface I2 {
+ void m(String s);
+ }
+
+ static class B {
+ void m(Integer i) { }
+ }
+
+ static class C extends B implements I1 { }
+ static class D extends B implements I2 { }
+
+ void test(C c, D d) {
+ c.m();
+ d.m();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg12.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,4 @@
+Neg12.java:21:12: compiler.err.does.not.override.abstract: Neg12.D, m(java.lang.String), Neg12.I2
+Neg12.java:24:10: compiler.err.cant.apply.symbols: kindname.method, m, ,{(compiler.misc.inapplicable.method: kindname.method, Neg12.B, m(java.lang.Integer), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, Neg12.I1, m(java.lang.String), (compiler.misc.arg.length.mismatch))}
+Neg12.java:25:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Integer, compiler.misc.no.args, kindname.class, Neg12.B, (compiler.misc.arg.length.mismatch)
+3 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that default method overriding object members are flagged as error
+ * @compile/fail/ref=Neg13.out -XDallowDefaultMethods -XDrawDiagnostics Neg13.java
+ */
+interface Neg13 {
+ default protected Object clone() { return null; } //protected not allowed here
+ default boolean equals(Object obj) { return false; }
+ default protected void finalize() { } //protected not allowed here
+ default Class<?> getClass() { return null; }
+ default int hashCode() { return 0; }
+ default void notify() { }
+ default void notifyAll() { }
+ default String toString() { return null; }
+ default void wait() { }
+ default void wait(long timeout) { }
+ default void wait(long timeout, int nanos) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg13.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,12 @@
+Neg13.java:7:30: compiler.err.mod.not.allowed.here: protected
+Neg13.java:9:28: compiler.err.mod.not.allowed.here: protected
+Neg13.java:8:21: compiler.err.default.overrides.object.member: equals, kindname.interface, Neg13
+Neg13.java:10:22: compiler.err.override.meth: (compiler.misc.cant.override: getClass(), Neg13, getClass(), java.lang.Object), final
+Neg13.java:11:17: compiler.err.default.overrides.object.member: hashCode, kindname.interface, Neg13
+Neg13.java:12:18: compiler.err.override.meth: (compiler.misc.cant.override: notify(), Neg13, notify(), java.lang.Object), final
+Neg13.java:13:18: compiler.err.override.meth: (compiler.misc.cant.override: notifyAll(), Neg13, notifyAll(), java.lang.Object), final
+Neg13.java:14:20: compiler.err.default.overrides.object.member: toString, kindname.interface, Neg13
+Neg13.java:15:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(), Neg13, wait(), java.lang.Object), final
+Neg13.java:16:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long), Neg13, wait(long), java.lang.Object), final
+Neg13.java:17:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long,int), Neg13, wait(long,int), java.lang.Object), final
+11 errors
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that a class cannot have two sibling interfaces with a default and abstract method
+ * @compile/fail/ref=Neg14.out -XDallowDefaultMethods -XDrawDiagnostics Neg14.java
+ */
+class Neg14 {
+ interface IA { int m(); }
+ interface IB { default int m() { return 1; } }
+
+ abstract class AB implements IA, IB {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg14.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg14.java:10:14: compiler.err.types.incompatible.abstract.default: kindname.class, Neg14.AB, m, , Neg14.IB, Neg14.IA
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that level skipping in default super calls is correctly rejected
+ * @compile/fail/ref=Neg15.out -XDallowDefaultMethods -XDrawDiagnostics Neg15.java
+ */
+class Neg15 {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+ interface K extends I {}
+
+ static class C implements J, K {
+ void foo() { K.super.m(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg15.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg15.java:12:31: compiler.err.illegal.default.super.call: Neg15.K, (compiler.misc.overridden.default: m(), Neg15.J)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,13 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary check that level skipping in default super calls is correctly rejected
+ * @compile/fail/ref=Neg16.out -XDallowDefaultMethods -XDrawDiagnostics Neg16.java
+ */
+class Neg16 {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+
+ static class C implements I, J {
+ void foo() { I.super.m(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Neg16.out Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,2 @@
+Neg16.java:11:23: compiler.err.illegal.default.super.call: Neg16.I, (compiler.misc.redundant.supertype: Neg16.I, Neg16.J)
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos01.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 2012, 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
+ * @summary basic test for default methods
+ * @ignore awaits lambda support
+ * @author Maurizio Cimadamore
+ * @compile -XDallowLambda -XDallowPoly -XDallowDefaultMethods Pos01.java
+ */
+
+import java.util.*;
+
+class Pos01 {
+
+ interface Mapper<T> {
+ T map(T in);
+ }
+
+ interface ExtendedList<T> extends List<T> {
+ default List<T> testMap(Mapper<T> r) {
+ return Pos01.<T>listMapper(this, r);
+ }
+ }
+
+ static class MyList<E> extends ArrayList<E> implements ExtendedList<E> {}
+
+ public static void main(String[] args) {
+ MyList<Integer> l = new MyList<Integer>();
+ l.add(1); l.add(2); l.add(3);
+ l.testMap((Integer x) -> x * x );
+ }
+
+ static <T> List<T> listMapper(List<T> l, Mapper<T> mapper) {
+ MyList<T> new_list = new MyList<T>();
+ for (T el : l) {
+ new_list.add(mapper.map(el));
+ }
+ return new_list;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos02.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary test for explicit resolution of ambiguous default methods
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos02.java
+ */
+
+class Pos02 {
+ interface IA { default int m() { return Pos02.m1(this); } }
+ interface IB { default int m() { return Pos02.m2(this); } }
+
+ static class A implements IA {}
+ static class B implements IB {}
+
+ static class AB implements IA, IB {
+ public int m() { return 0; }
+ void test() {
+ AB.this.m();
+ IA.super.m();
+ }
+ }
+
+ static int m1(IA a) { return 0; }
+ static int m2(IB b) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos04.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary test for overriding with default method
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos04.java
+ */
+
+class Pos04 {
+ interface A { default int m() { return Pos04.m(this); } }
+ static abstract class B { public int m() { return 0; } }
+
+ static class C extends B implements A {
+ void test() {
+ C.this.m();
+ A.super.m();
+ }
+ }
+
+ static int m(A a) { return 0; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos05.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary check that indirectly inherited default methods are discovered during resolution
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos05.java
+ */
+
+class Pos05 {
+ interface A {
+ default void m() { Pos05.impl(this); }
+ }
+
+ interface B extends A { }
+
+ static class E implements B { }
+
+ void test(E e) {
+ e.m();
+ }
+
+ static void impl(A a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos06.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities)
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos06.java
+ */
+
+class Pos06 {
+ interface A {
+ default void m() { Pos06.impl(this); }
+ }
+
+ interface B extends A {
+ default void m() { Pos06.impl(this); }
+ }
+
+ static class X implements A, B { }
+
+ void test(X x) {
+ x.m();
+ ((A)x).m();
+ ((B)x).m();
+ }
+
+ static void impl(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos07.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary check that compilation order does not matter
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos07.java
+ */
+
+class Pos07 {
+ interface A {
+ default void foo() { Pos07.impl(this); }
+ default void bar() { Pos07.impl(this); }
+ }
+
+ static class C implements B, A {}
+
+ interface B extends A {
+ default void foo() { Pos07.impl(this); }
+ }
+
+ static void impl(A a) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos08.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary check that common overrider solves default method conflicts
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos08.java
+ */
+
+class Pos08 {
+ interface A {
+ default void m() { Pos08.a(this); }
+ }
+
+ interface B {
+ default void m() { Pos08.b(this); }
+ }
+
+ interface C extends A, B {
+ default void m() { Pos08.b(this); }
+ }
+
+ static void a(A o) { }
+ static void b(B o) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos10.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary check that type-variables in generic extension decl can be accessed from default impl
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods Pos10.java
+ */
+
+class Pos10 {
+ interface Function<X,Y> {
+ Y apply(X x);
+ }
+
+ interface A<T> {
+ default <R> void m(Function<T,R> f) { Impl.<T,R>m(this, f); }
+ }
+
+ static class Impl {
+ static <T,R> void m(A<T> a, Function<T,R> f) { }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos11.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary complex test with conflict resolution via overriding
+ * @author Brian Goetz
+ * @compile -XDallowDefaultMethods Pos11.java
+ */
+
+class Pos11 {
+ interface A {
+ default void get() { Pos11.one(this); }
+ }
+
+ interface B {
+ default void get() { Pos11.two(this); }
+ }
+
+ interface C extends A {
+ default void get() { Pos11.two(this); }
+ }
+
+ interface D extends A, B {
+ default void get() { Pos11.two(this); }
+ }
+
+ static class X implements C { }
+
+ static class Y implements C, A { }
+
+ static class Z implements D, A, B { }
+
+ static void one(Object a) { }
+ static void two(Object a) { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos12.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary check that 'this' can be used from within an extension method
+ * @compile -XDallowDefaultMethods Pos12.java
+ */
+
+interface Pos12 {
+
+ default Object m() {
+ Object o = this;
+ f(this);
+ return this;
+ }
+
+ void f(Object o);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos13.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary qualified 'this' inside default method causes StackOverflowException
+ * @compile -XDallowDefaultMethods Pos13.java
+ */
+
+public class Pos13 {
+
+ static int assertionCount = 0;
+
+ static void assertTrue(boolean cond) {
+ assertionCount++;
+ if (!cond)
+ throw new AssertionError();
+ }
+
+ interface Outer {
+ abstract void doSomething();
+
+ default void m() {
+ new SubOuter() {
+ public void doSomething() {
+ Outer.this.doSomething();
+ }
+ }.doSomething();
+ }
+ }
+
+ interface SubOuter extends Outer { }
+
+ static class E implements Outer {
+ public void doSomething() { assertTrue(true); }
+ }
+
+ public static void main(String[] args) {
+ new E().m();
+ assertTrue(assertionCount == 1);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos14.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary check that overload resolution selects most specific signature
+ * @compile -XDallowDefaultMethods Pos14.java
+ */
+
+class Pos14 {
+ interface A { default Object m() { return null; } }
+ static abstract class B { abstract public String m(); }
+
+ static abstract class C extends B implements A {
+ void test() {
+ m().length();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos15.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary check that overload resolution selects most specific signature
+ * @compile -XDallowDefaultMethods Pos15.java
+ */
+
+class Pos15 {
+ interface A { default String m() { return null; } }
+ static abstract class B { abstract public Object m(); }
+
+ static abstract class C extends B implements A {
+ void test() {
+ m().length();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/Pos16.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary 'class wins' should not short-circuit overload resolution
+ * @compile -XDallowDefaultMethods Pos16.java
+ */
+
+class Pos16 {
+ interface I {
+ default String m(Integer i) { return ""; }
+ }
+
+ class C implements I {
+ Integer m(Object o) { return 1; }
+ }
+
+ void test(C c) {
+ c.m(1).length();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @ignore awaits for VM support
+ * @summary check that code attributed for default methods is correctly generated
+ * @compile -XDallowDefaultMethods TestDefaultBody.java
+ * @run main TestDefaultBody
+ */
+
+import com.sun.tools.classfile.AccessFlags;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.Instruction;
+import com.sun.tools.classfile.Method;
+
+import com.sun.tools.classfile.Opcode;
+import java.io.*;
+
+public class TestDefaultBody {
+
+ interface TestInterface {
+ int no_default(int i);
+ default int yes_default(int i) { return impl(this, i); }
+ }
+
+ static int impl(TestInterface ti, int i) { return 0; }
+
+ static final String TARGET_CLASS_NAME = "TestDefaultBody";
+ static final String TARGET_NAME = "impl";
+ static final String TARGET_TYPE = "(LTestDefaultBody$TestInterface;I)I";
+ static final String SUBTEST_NAME = TestInterface.class.getName() + ".class";
+ static final String TEST_METHOD_NAME = "yes_default";
+
+ public static void main(String... args) throws Exception {
+ new TestDefaultBody().run();
+ }
+
+ public void run() throws Exception {
+ String workDir = System.getProperty("test.classes");
+ File compiledTest = new File(workDir, SUBTEST_NAME);
+ verifyDefaultBody(compiledTest);
+ }
+
+ void verifyDefaultBody(File f) {
+ System.err.println("verify: " + f);
+ try {
+ ClassFile cf = ClassFile.read(f);
+ Method testMethod = null;
+ Code_attribute codeAttr = null;
+ for (Method m : cf.methods) {
+ codeAttr = (Code_attribute)m.attributes.get(Attribute.Code);
+ String mname = m.getName(cf.constant_pool);
+ if (mname.equals(TEST_METHOD_NAME)) {
+ testMethod = m;
+ break;
+ } else {
+ codeAttr = null;
+ }
+ }
+ if (testMethod == null) {
+ throw new Error("Test method not found");
+ }
+ if (testMethod.access_flags.is(AccessFlags.ACC_ABSTRACT)) {
+ throw new Error("Test method is abstract");
+ }
+ if (codeAttr == null) {
+ throw new Error("Code attribute in test method not found");
+ }
+
+ boolean found = false;
+ for (Instruction instr : codeAttr.getInstructions()) {
+ if (instr.getOpcode() == Opcode.INVOKESTATIC) {
+ found = true;
+ int pc_index = instr.getShort(1);
+ CONSTANT_Methodref_info mref = (CONSTANT_Methodref_info)cf.constant_pool.get(pc_index);
+ String className = mref.getClassName();
+ String targetName = mref.getNameAndTypeInfo().getName();
+ String targetType = mref.getNameAndTypeInfo().getType();
+
+ if (!className.equals(TARGET_CLASS_NAME)) {
+ throw new Error("unexpected class in default method body " + className);
+ }
+ if (!targetName.equals(TARGET_NAME)) {
+ throw new Error("unexpected method name in default method body " + targetName);
+ }
+ if (!targetType.equals(TARGET_TYPE)) {
+ throw new Error("unexpected method type in default method body " + targetType);
+ }
+ break;
+ }
+ }
+
+ if (!found) {
+ throw new Error("no invokestatic found in default method body");
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Error("error reading " + f +": " + e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @ignore awaits for VM support
+ * @summary check that javac does not generate bridge methods for defaults
+ * @compile -XDallowDefaultMethods TestNoBridgeOnDefaults.java
+ * @run main TestNoBridgeOnDefaults
+ */
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Method;
+
+import java.io.*;
+
+public class TestNoBridgeOnDefaults {
+
+ interface A<X> {
+ default <Y> A<X> m(X x, Y y) { return Impl.<X,Y>m1(this, x, y); }
+ }
+
+ static abstract class B<X> implements A<X> { }
+
+ interface C<X> extends A<X> {
+ default <Y> C<X> m(X x, Y y) { return Impl.<X,Y>m2(this, x, y); }
+ }
+
+ static abstract class D<X> extends B<X> implements C<X> { }
+
+ static class Impl {
+ static <X, Y> A<X> m1(A<X> rec, X x, Y y) { return null; }
+ static <X, Y> C<X> m2(C<X> rec, X x, Y y) { return null; }
+ }
+
+ static final String[] SUBTEST_NAMES = { B.class.getName() + ".class", D.class.getName() + ".class" };
+ static final String TEST_METHOD_NAME = "m";
+
+ public static void main(String... args) throws Exception {
+ new TestNoBridgeOnDefaults().run();
+ }
+
+ public void run() throws Exception {
+ String workDir = System.getProperty("test.classes");
+ for (int i = 0 ; i < SUBTEST_NAMES.length ; i ++) {
+ File compiledTest = new File(workDir, SUBTEST_NAMES[i]);
+ checkNoBridgeOnDefaults(compiledTest);
+ }
+ }
+
+ void checkNoBridgeOnDefaults(File f) {
+ System.err.println("check: " + f);
+ try {
+ ClassFile cf = ClassFile.read(f);
+ for (Method m : cf.methods) {
+ String mname = m.getName(cf.constant_pool);
+ if (mname.equals(TEST_METHOD_NAME)) {
+ throw new Error("unexpected bridge method found " + m);
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new Error("error reading " + f +": " + e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/Clinit.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+interface Clinit {
+ String s = Inner.m();
+
+ static class Inner {
+ static String m() { return ""; }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary check that clinit in interface doesn't cause spurious default method diagnostics
+ * @compile -source 1.4 -target 1.4 Clinit.java
+ * @compile CrossCompile.java
+ */
+class CrossCompile {
+ void test() {
+ String s = Clinit.s;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/FDTest.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary Automatic test for checking correctness of default resolution
+ */
+
+import shapegen.*;
+
+import com.sun.source.util.JavacTask;
+
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+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 FDTest {
+
+ enum TestKind {
+ POSITIVE,
+ NEGATIVE;
+
+ Collection<Hierarchy> getHierarchy(HierarchyGenerator hg) {
+ return this == POSITIVE ?
+ hg.getOK() : hg.getErr();
+ }
+ }
+
+ 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);
+
+ HierarchyGenerator hg = new HierarchyGenerator();
+ for (TestKind tk : TestKind.values()) {
+ for (Hierarchy hs : tk.getHierarchy(hg)) {
+ new FDTest(tk, hs).run(comp, fm);
+ }
+ }
+ }
+
+ TestKind tk;
+ Hierarchy hs;
+ DefenderTestSource source;
+ DiagnosticChecker diagChecker;
+
+ FDTest(TestKind tk, Hierarchy hs) {
+ this.tk = tk;
+ this.hs = hs;
+ this.source = new DefenderTestSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ Arrays.asList("-XDallowDefaultMethods"), null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected = tk == TestKind.NEGATIVE;
+ if (errorExpected != diagChecker.errorFound) {
+ throw new AssertionError("problem in source: \n" +
+ "\nerror found = " + diagChecker.errorFound +
+ "\nerror expected = " + errorExpected +
+ "\n" + dumpHierarchy() +
+ "\n" + source.getCharContent(true));
+ }
+ }
+
+ String dumpHierarchy() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("root = " + hs.root + "\n");
+ for (ClassCase cc : hs.all) {
+ buf.append(" class name = " + cc.getName() + "\n");
+ buf.append(" class OK = " + cc.get_OK() + "\n");
+ buf.append(" prov = " + cc.get_mprov() + "\n");
+
+ }
+ return buf.toString();
+ }
+
+ class DefenderTestSource extends SimpleJavaFileObject {
+
+ String source;
+
+ public DefenderTestSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ StringBuilder buf = new StringBuilder();
+ List<ClassCase> defaultRef = new ArrayList<>();
+ for (ClassCase cc : hs.all) {
+ hs.genClassDef(buf, cc, null, defaultRef);
+ }
+ source = buf.toString();
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ 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/defaultMethods/fd/shapegen/ClassCase.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class ClassCase {
+
+ public enum Kind {
+ IVAC (true, "v"),
+ IPRESENT (true, "p"),
+ IDEFAULT (true, "d"),
+ CNONE (false, "n"),
+ CABSTRACT (false, "a"),
+ CCONCRETE (false, "c");
+
+ private final String prefix;
+ public final boolean isInterface;
+
+ Kind(boolean isInterface, String prefix) {
+ this.isInterface = isInterface;
+ this.prefix = prefix;
+ }
+ }
+
+ public final Kind kind;
+ private final ClassCase superclass;
+ private final List<ClassCase> supertypes;
+
+ private String name;
+ private boolean _OK;
+ private boolean _HasClassMethod;
+ private Set<ClassCase> _mprov;
+ private boolean _IsConcrete;
+ private boolean _HasDefault;
+ private ClassCase _mres;
+ private ClassCase _mdefend;
+
+ private Set<RuleGroup> executed = new HashSet<RuleGroup>() {};
+
+ public ClassCase(Kind kind, ClassCase superclass, List<ClassCase> interfaces) {
+ this.kind = kind;
+ this.superclass = superclass;
+
+ // Set supertypes from superclass (if any) and interfaces
+ List<ClassCase> lc;
+ if (superclass == null) {
+ lc = interfaces;
+ } else {
+ lc = new ArrayList<>();
+ lc.add(superclass);
+ lc.addAll(interfaces);
+ }
+ this.supertypes = lc;
+ }
+
+ public final boolean isInterface() { return kind.isInterface; }
+ public final boolean isClass() { return !kind.isInterface; }
+
+ public Set<ClassCase> get_mprov() {
+ exec(RuleGroup.PROVENENCE);
+ return _mprov;
+ }
+
+ public void set_mprov(ClassCase cc) {
+ Set<ClassCase> s = new HashSet<>();
+ s.add(cc);
+ _mprov = s;
+ }
+
+ public void set_mprov(Set<ClassCase> s) {
+ _mprov = s;
+ }
+
+ public ClassCase get_mres() {
+ exec(RuleGroup.RESOLUTION);
+ return _mres;
+ }
+
+ public void set_mres(ClassCase cc) {
+ _mres = cc;
+ }
+
+ public ClassCase get_mdefend() {
+ exec(RuleGroup.DEFENDER);
+ return _mdefend;
+ }
+
+ public void set_mdefend(ClassCase cc) {
+ _mdefend = cc;
+ }
+
+ public boolean get_HasClassMethod() {
+ exec(RuleGroup.PROVENENCE);
+ return _HasClassMethod;
+ }
+
+ public void set_HasClassMethod(boolean bool) {
+ _HasClassMethod = bool;
+ }
+
+ public boolean get_HasDefault() {
+ exec(RuleGroup.MARKER);
+ return _HasDefault;
+ }
+
+ public void set_HasDefault(boolean bool) {
+ _HasDefault = bool;
+ }
+
+ public boolean get_IsConcrete() {
+ exec(RuleGroup.MARKER);
+ return _IsConcrete;
+ }
+
+ public void set_IsConcrete(boolean bool) {
+ _IsConcrete = bool;
+ }
+
+ public boolean get_OK() {
+ exec(RuleGroup.CHECKING);
+ return _OK;
+ }
+
+ public void set_OK(boolean bool) {
+ _OK = bool;
+ }
+
+ public boolean isMethodDefined() {
+ for (ClassCase cc : supertypes) {
+ if (cc.isMethodDefined()) {
+ return true;
+ }
+ }
+ switch (kind) {
+ case CCONCRETE:
+ case CABSTRACT:
+ case IPRESENT:
+ case IDEFAULT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ public boolean isAbstract() {
+ return isMethodDefined() && (get_mres()==null);
+ }
+
+ public boolean hasSuperclass() {
+ return superclass != null;
+ }
+
+ public ClassCase getSuperclass() {
+ return superclass;
+ }
+
+ public List<ClassCase> getSupertypes() {
+ return supertypes;
+ }
+
+ public List<ClassCase> getInterfaces() {
+ if (superclass != null) {
+ if (supertypes.get(0) != superclass) {
+ throw new AssertionError("superclass missing from supertypes");
+ }
+ return supertypes.subList(1, supertypes.size());
+ } else {
+ return supertypes;
+ }
+ }
+
+ public boolean isSubtypeOf(ClassCase cc) {
+ // S-Refl
+ if (cc.equals(this)) {
+ return true;
+ }
+
+ // S-Def
+ for (ClassCase sp : getSupertypes()) {
+ if (cc.equals(sp)) {
+ return true;
+ }
+ }
+
+ // _S-Trans
+ for (ClassCase sp : getSupertypes()) {
+ if (sp.isSubtypeOf(cc)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public void init(Map<String, Integer> namingContext) {
+ if (name != null) {
+ return; // Already inited
+ }
+
+ for (ClassCase sup : supertypes) {
+ sup.init(namingContext);
+ }
+
+ // Build name
+ StringBuilder sb = new StringBuilder();
+ if (!supertypes.isEmpty()) {
+ sb.append(isInterface() ? "I" : "C");
+ for (ClassCase cc : supertypes) {
+ sb.append(cc.getName());
+ }
+ sb.append(kind.isInterface ? "i" : "c");
+ }
+ sb.append(kind.prefix);
+ String pname = sb.toString();
+ Integer icnt = namingContext.get(pname);
+ int cnt = icnt == null ? 0 : icnt;
+ ++cnt;
+ namingContext.put(pname, cnt);
+ if (cnt > 1) {
+ sb.append(cnt);
+ }
+ this.name = sb.toString();
+ }
+
+ public boolean isa(Kind... kinds) {
+ for (Kind k : kinds) {
+ if (kind == k) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void exec(RuleGroup rg ) {
+ if (!executed.contains(rg)) {
+ rg.exec(this);
+ executed.add(rg);
+ }
+ }
+
+ public void collectClasses(Set<ClassCase> seen) {
+ seen.add(this);
+ for (ClassCase cc : supertypes) {
+ cc.collectClasses(seen);
+ }
+ }
+
+ public String getID() {
+ if (name == null) {
+ throw new Error("Access to uninitialized ClassCase");
+ } else {
+ return name;
+ }
+ }
+
+ public final String getName() {
+ if (name == null) {
+ return "ClassCase uninited@" + hashCode();
+ } else {
+ return name;
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/Hierarchy.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import java.util.List;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class Hierarchy {
+
+ public final ClassCase root;
+ public final Set<ClassCase> all;
+
+ public Hierarchy(ClassCase root) {
+ this.root = root;
+ root.init(new HashMap<String,Integer>());
+ Set<ClassCase> allClasses = new HashSet<>();
+ root.collectClasses(allClasses);
+ this.all = allClasses;
+ }
+
+ public boolean anyDefaults() {
+ for (ClassCase cc : all) {
+ if (cc.kind == IDEFAULT) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public boolean get_OK() {
+ return root.get_OK();
+ }
+
+ public String testName() {
+ return root + "Test";
+ }
+
+ private static void genInterfaceList(StringBuilder buf, String prefix, List<ClassCase> interfaces) {
+ if (!interfaces.isEmpty()) {
+ buf.append(" ");
+ buf.append(prefix);
+ buf.append(" ");
+ buf.append(interfaces.get(0));
+ for (int i = 1; i < interfaces.size(); ++i) {
+ buf.append(", " + interfaces.get(i));
+ }
+ }
+ }
+
+ public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List<ClassCase> defaultRef) {
+ if (cc.isInterface()) {
+ buf.append("interface ");
+ buf.append(cc.getName() + " ");
+ genInterfaceList(buf, "extends", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case IDEFAULT:
+ buf.append(" default String m() { return \"\"; }\n");
+ defaultRef.add(cc);
+ break;
+ case IPRESENT:
+ buf.append(" String m();\n");
+ break;
+ case IVAC:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ } else {
+ buf.append((cc.isAbstract()? "abstract " : ""));
+ buf.append(" class " + cc.getName());
+ if (cc.getSuperclass() != null) {
+ buf.append(" extends " + cc.getSuperclass());
+ }
+
+ genInterfaceList(buf, "implements", cc.getInterfaces());
+ buf.append(" {\n");
+
+ switch (cc.kind) {
+ case CCONCRETE:
+ buf.append(" public String m() { return \"\"; }\n");
+ break;
+ case CABSTRACT:
+ buf.append(" public abstract String m();\n");
+ break;
+ case CNONE:
+ break;
+ default:
+ throw new AssertionError("Unexpected kind");
+ }
+ buf.append("}\n\n");
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID());
+ }
+
+ @Override
+ public int hashCode() {
+ return root.getID().hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return root.getName();
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/HierarchyGenerator.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import shapegen.ClassCase.Kind;
+
+import java.util.Collection;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Collections;
+import java.util.ArrayList;
+import java.util.List;
+
+import static shapegen.ClassCase.Kind.*;
+
+import static java.lang.Math.pow;
+
+/**
+ *
+ * @author Robert Field
+ */
+public final class HierarchyGenerator {
+
+ private static int okcnt = 0;
+ private static int errcnt = 0;
+ private static Set<Hierarchy> uniqueOK = new HashSet<>();
+ private static Set<Hierarchy> uniqueErr = new HashSet<>();
+
+ /**
+ * @param args the command line arguments
+ */
+ public HierarchyGenerator() {
+ organize("exhaustive interface", iExhaustive(2));
+ organize("exhaustive class", cExhaustive());
+ organize("shapes interface", iShapes());
+ organize("shapes class/interface", ciShapes());
+
+ System.out.printf("\nExpect OK: %d -- unique %d", okcnt, uniqueOK.size());
+ System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size());
+ }
+
+ public Collection<Hierarchy> getOK() {
+ return uniqueOK;
+ }
+
+ public Collection<Hierarchy> getErr() {
+ return uniqueErr;
+ }
+
+ private void organize(String tname, List<Hierarchy> totest) {
+ System.out.printf("\nTesting %s....\n", tname);
+ int nodefault = 0;
+ List<Hierarchy> ok = new ArrayList<>();
+ List<Hierarchy> err = new ArrayList<>();
+ for (Hierarchy cc : totest) {
+ if (cc.anyDefaults()) {
+ //System.out.printf(" %s\n", cc);
+ if (cc.get_OK()) {
+ ok.add(cc);
+ } else {
+ err.add(cc);
+ }
+ } else {
+ ++nodefault;
+ }
+ }
+
+ errcnt += err.size();
+ okcnt += ok.size();
+ uniqueErr.addAll(err);
+ uniqueOK.addAll(ok);
+
+ System.out.printf(" %5d No default\n %5d Error\n %5d OK\n %5d Total\n",
+ nodefault, err.size(), ok.size(), totest.size());
+ }
+
+ public List<Hierarchy> iExhaustive(int idepth) {
+ List<ClassCase> current = new ArrayList<>();
+ for (int i = 0; i < idepth; ++i) {
+ current = ilayer(current);
+ }
+ return wrapInClassAndHierarchy(current);
+ }
+
+ private List<ClassCase> ilayer(List<ClassCase> srcLayer) {
+ List<ClassCase> lay = new ArrayList<>();
+ for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) {
+ List<ClassCase> itfs = new ArrayList<>();
+ for (int b = srcLayer.size() - 1; b >= 0; --b) {
+ if ((i & (1<<b)) != 0) {
+ itfs.add(srcLayer.get(b));
+ }
+ }
+ lay.add(new ClassCase(IVAC, null, itfs));
+ lay.add(new ClassCase(IPRESENT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ lay.add(new ClassCase(IDEFAULT, null, itfs));
+ }
+ return lay;
+ }
+
+ public List<Hierarchy> cExhaustive() {
+ final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null};
+ final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE};
+ List<Hierarchy> totest = new ArrayList<>();
+ for (int i1 = 0; i1 < iKinds.length; ++i1) {
+ for (int i2 = 0; i2 < iKinds.length; ++i2) {
+ for (int i3 = 0; i3 < iKinds.length; ++i3) {
+ for (int c1 = 0; c1 < cKinds.length; ++c1) {
+ for (int c2 = 0; c2 < cKinds.length; ++c2) {
+ for (int c3 = 0; c3 < cKinds.length; ++c3) {
+ totest.add( new Hierarchy(
+ new ClassCase(cKinds[c1],
+ new ClassCase(cKinds[c2],
+ new ClassCase(cKinds[c3],
+ null,
+ iList(iKinds[i1])
+ ),
+ iList(iKinds[i2])
+ ),
+ iList(iKinds[i3])
+ )));
+ }
+ }
+ }
+ }
+ }
+ }
+ return totest;
+ }
+
+ private List<ClassCase> iList(Kind kind) {
+ if (kind == null) {
+ return Collections.EMPTY_LIST;
+ } else {
+ List<ClassCase> itfs = new ArrayList<>();
+ itfs.add(new ClassCase(kind, null, Collections.EMPTY_LIST));
+ return itfs;
+ }
+ }
+
+ public List<Hierarchy> ciShapes() {
+ return wrapInHierarchy(TTShape.allCases(true));
+ }
+
+ public List<Hierarchy> iShapes() {
+ return wrapInClassAndHierarchy(TTShape.allCases(false));
+ }
+
+ public List<Hierarchy> wrapInClassAndHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ List<ClassCase> interfaces = new ArrayList<>();
+ interfaces.add(cc);
+ totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces)));
+ }
+ return totest;
+ }
+
+ public List<Hierarchy> wrapInHierarchy(List<ClassCase> ihs) {
+ List<Hierarchy> totest = new ArrayList<>();
+ for (ClassCase cc : ihs) {
+ totest.add(new Hierarchy(cc));
+ }
+ return totest;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/Rule.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+/**
+ *
+ * @author Robert Field
+ */
+public abstract class Rule {
+
+ public final String name;
+
+ public Rule(String name) {
+ this.name = name;
+ }
+
+ abstract boolean guard(ClassCase cc);
+
+ abstract void eval(ClassCase cc);
+
+ @Override
+ public String toString() {
+ return name;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/RuleGroup.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class RuleGroup {
+
+ final String name;
+ private final Rule[] rules;
+
+ public RuleGroup(String name, Rule[] rules) {
+ this.name = name;
+ this.rules = rules;
+ }
+
+ public boolean exec(ClassCase cc) {
+ boolean found = false;
+ for (Rule rule : rules) {
+ if (rule.guard(cc)) {
+ if (found) {
+ throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc);
+ } else {
+ rule.eval(cc);
+ found = true;
+ }
+ }
+ }
+ return found;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] {
+ new Rule("P-CDeclare") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CCONCRETE, CABSTRACT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc);
+ cc.set_HasClassMethod(true);
+ }
+ },
+
+ new Rule("P-IDeclare") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IDEFAULT, IPRESENT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc);
+ }
+ },
+
+ new Rule("P-IntfInh") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+ }
+
+ void eval(ClassCase cc) {
+ Set<ClassCase> _S = new HashSet<>();
+ for (ClassCase t : cc.getSupertypes()) {
+ _S.addAll(t.get_mprov());
+ }
+ Set<ClassCase> tops = new HashSet<>();
+ for (ClassCase _W : _S) {
+ for (ClassCase _V : _S) {
+ if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) {
+ tops.add(_W);
+ }
+ }
+ }
+ cc.set_mprov(tops);
+ }
+ },
+
+ new Rule("P-ClassInh") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod());
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mprov(cc.getSuperclass());
+ cc.set_HasClassMethod(true);
+ }
+ },
+
+ });
+
+ public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] {
+ new Rule("M-Default") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(IDEFAULT);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_HasDefault(true);
+ }
+ },
+
+ new Rule("M-Conc") {
+ boolean guard(ClassCase cc) {
+ return cc.isa(CCONCRETE);
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_IsConcrete(true);
+ }
+ },
+
+ });
+
+ public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] {
+ new Rule("R-Resolve") {
+ boolean guard(ClassCase cc) {
+ if (!(cc.isClass() && cc.get_mprov().size() == 1)) {
+ return false;
+ }
+ ClassCase _V = cc.get_mprov().iterator().next();
+ return _V.get_IsConcrete() || _V.get_HasDefault();
+ }
+
+ void eval(ClassCase cc) {
+ ClassCase _V = cc.get_mprov().iterator().next();
+ cc.set_mres(_V);
+ }
+ },
+
+ });
+
+ public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] {
+ new Rule("D-Defend") {
+ boolean guard(ClassCase cc) {
+ ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null;
+ boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper);
+ return cc.isa(CNONE) && !eq;
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_mdefend(cc.get_mres());
+ }
+ },
+
+ });
+
+ public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] {
+ new Rule("C-Check") {
+ boolean guard(ClassCase cc) {
+ for (ClassCase t : cc.getSupertypes()) {
+ if (! t.get_OK()) {
+ return false;
+ }
+ }
+ int defenderCount = 0;
+ int provCount = 0;
+ for (ClassCase prov : cc.get_mprov()) {
+ if (prov.get_HasDefault()) {
+ defenderCount++;
+ }
+ provCount++;
+ }
+ return provCount <= 1 || defenderCount == 0;
+ }
+
+ void eval(ClassCase cc) {
+ cc.set_OK(true);
+ }
+ },
+
+ });
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTNode.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import shapegen.ClassCase.Kind;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+import static shapegen.ClassCase.Kind.*;
+
+/**
+ * Type Template Node
+ *
+ * @author Robert Field
+ */
+public class TTNode {
+
+ final List<TTNode> supertypes;
+ final boolean canBeClass;
+
+ private int currentKindIndex;
+ private Kind[] kinds;
+
+ public TTNode(List<TTNode> subtypes, boolean canBeClass) {
+ this.supertypes = subtypes;
+ this.canBeClass = canBeClass;
+ }
+
+ public void start(boolean includeClasses) {
+ kinds =
+ supertypes.isEmpty()?
+ (new Kind[]{IDEFAULT, IPRESENT})
+ : ((includeClasses && canBeClass)?
+ new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT}
+ : new Kind[]{IVAC, IDEFAULT, IPRESENT});
+ currentKindIndex = 0;
+
+ for (TTNode sub : supertypes) {
+ sub.start(includeClasses);
+ }
+ }
+
+ public boolean next() {
+ ++currentKindIndex;
+ if (currentKindIndex >= kinds.length) {
+ currentKindIndex = 0;
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ public void collectAllSubtypes(Set<TTNode> subs) {
+ subs.add(this);
+ for (TTNode n : supertypes) {
+ n.collectAllSubtypes(subs);
+ }
+ }
+
+ private Kind getKind() {
+ return kinds[currentKindIndex];
+ }
+
+ boolean isInterface() {
+ return getKind().isInterface;
+ }
+
+ boolean isClass() {
+ return !isInterface();
+ }
+
+ boolean hasDefault() {
+ return getKind() == IDEFAULT;
+ }
+
+ public boolean isValid() {
+ for (TTNode n : supertypes) {
+ if (!n.isValid() || (isInterface() && n.isClass())) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public ClassCase genCase() {
+ ClassCase subclass;
+ List<TTNode> ttintfs;
+ if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) {
+ subclass = supertypes.get(0).genCase();
+ ttintfs = supertypes.subList(1, supertypes.size());
+ } else {
+ subclass = null;
+ ttintfs = supertypes;
+ }
+ List<ClassCase> intfs = new ArrayList<>();
+ for (TTNode node : ttintfs) {
+ intfs.add(node.genCase());
+ }
+ return new ClassCase(getKind(), subclass, intfs);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTParser.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.io.IOException;
+import java.io.StringReader;
+
+import static java.lang.Character.isLetter;
+import static java.lang.Character.isUpperCase;
+import static java.lang.Character.isWhitespace;
+
+/**
+ * Parse a type template definition string
+ *
+ * input :: classDef
+ * classDef :: letter [ ( classDef* ) ]
+ *
+ * @author Robert Field
+ */
+public class TTParser extends StringReader {
+
+ private Map<Character, TTNode> letterMap = new HashMap<>();
+ private char ch;
+
+ private final String def;
+
+ public TTParser(String s) {
+ super(s);
+ this.def = s;
+ }
+
+ private void advance() throws IOException {
+ do {
+ ch = (char)read();
+ } while (isWhitespace(ch));
+ }
+
+ public TTNode parse() {
+ try {
+ advance();
+ return classDef();
+ } catch (IOException t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ private TTNode classDef() throws IOException {
+ if (!isLetter(ch)) {
+ if (ch == (char)-1) {
+ throw new IOException("Unexpected end of type template in " + def);
+ } else {
+ throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def);
+ }
+ }
+ char nodeCh = ch;
+ TTNode node = letterMap.get(nodeCh);
+ boolean canBeClass = isUpperCase(nodeCh);
+ advance();
+ if (node == null) {
+ List<TTNode> subtypes = new ArrayList<>();
+ if (ch == '(') {
+ advance();
+ while (ch != ')') {
+ subtypes.add(classDef());
+ }
+ advance();
+ }
+ node = new TTNode(subtypes, canBeClass);
+ letterMap.put(nodeCh, node);
+ }
+ return node;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTShape.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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 shapegen;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Robert Field
+ */
+public class TTShape {
+
+ private final TTNode root;
+ private final TTNode[] nodes;
+
+ TTShape(TTNode root) {
+ this.root = root;
+ Set<TTNode> subs = new HashSet<>();
+ root.collectAllSubtypes(subs);
+ nodes = subs.toArray(new TTNode[subs.size()]);
+ }
+
+ private List<ClassCase> toCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ root.start(includeClasses);
+ int i;
+ outer:
+ while (true) {
+ if (root.isValid()) {
+ ClassCase cc = root.genCase();
+ //System.out.println(cc);
+ ccs.add(cc);
+ }
+
+ i = 0;
+ do {
+ if (i >= nodes.length) {
+ break outer;
+ }
+ } while(!nodes[i++].next());
+ }
+ return ccs;
+ }
+
+ public static List<ClassCase> allCases(boolean includeClasses) {
+ List<ClassCase> ccs = new ArrayList<>();
+ for (TTShape shape : SHAPES) {
+ ccs.addAll(shape.toCases(includeClasses));
+ }
+ return ccs;
+ }
+
+ public static TTShape parse(String s) {
+ return new TTShape(new TTParser(s).parse());
+ }
+
+ public static final TTShape[] SHAPES = new TTShape[] {
+ parse("a"),
+ parse("a(b)"),
+ parse("A(bb)"),
+ parse("A(B(d)c(d))"),
+ parse("A(b(c))"),
+ parse("A(B(cd)d)"),
+ parse("A(B(c)c)"),
+ parse("A(B(Ce)d(e))"),
+ parse("A(B(C)d(e))"),
+ parse("A(Bc(d))"),
+ parse("A(B(d)dc)"),
+ parse("A(B(dc)dc)"),
+ parse("A(B(c(d))d)"),
+ parse("A(B(C(d))d)"),
+ parse("A(B(C(e)d(e))e)"),
+ parse("A(B(c(d))c)"),
+ parse("A(B(dc(d))c)"),
+ parse("A(B(C(d))d)"),
+ };
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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
+ * @summary smoke test for separate compilation of default methods
+ * @author Maurizio Cimadamore
+ * @compile -XDallowDefaultMethods pkg1/A.java
+ * @compile -XDallowDefaultMethods Separate.java
+ */
+
+import pkg1.A;
+
+class Separate {
+ interface B extends A.I {
+ default void m() { A.m(this); }
+ }
+
+ interface C extends A.I, B { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/separate/pkg1/A.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * 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 pkg1;
+
+public class A {
+ public interface I {
+ default void m() { A.m(this); }
+ }
+
+ public static void m(Object o) {}
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,406 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary Automatic test for checking correctness of default super/this resolution
+ */
+
+import com.sun.source.util.JavacTask;
+import java.net.URI;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+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 TestDefaultSuperCall {
+
+ static int checkCount = 0;
+
+ enum InterfaceKind {
+ DEFAULT("interface A extends B { default void m() { } }"),
+ ABSTRACT("interface A extends B { void m(); }"),
+ NONE("interface A extends B { }");
+
+ String interfaceStr;
+
+ InterfaceKind(String interfaceStr) {
+ this.interfaceStr = interfaceStr;
+ }
+
+ boolean methodDefined() {
+ return this == DEFAULT;
+ }
+ }
+
+ enum PruneKind {
+ NO_PRUNE("interface C { }"),
+ PRUNE("interface C extends A { }");
+
+ boolean methodDefined(InterfaceKind ik) {
+ return this == PRUNE &&
+ ik.methodDefined();
+ }
+
+ String interfaceStr;
+
+ PruneKind(String interfaceStr) {
+ this.interfaceStr = interfaceStr;
+ }
+ }
+
+ enum QualifierKind {
+ DIRECT_1("C"),
+ DIRECT_2("A"),
+ INDIRECT("B"),
+ UNRELATED("E"),
+ ENCLOSING_1(null),
+ ENCLOSING_2(null);
+
+ String qualifierStr;
+
+ QualifierKind(String qualifierStr) {
+ this.qualifierStr = qualifierStr;
+ }
+
+ String getQualifier(Shape sh) {
+ switch (this) {
+ case ENCLOSING_1: return sh.enclosingAt(0);
+ case ENCLOSING_2: return sh.enclosingAt(1);
+ default:
+ return qualifierStr;
+ }
+ }
+
+ boolean isEnclosing() {
+ return this == ENCLOSING_1 ||
+ this == ENCLOSING_2;
+ }
+
+ boolean allowSuperCall(InterfaceKind ik, PruneKind pk) {
+ switch (this) {
+ case DIRECT_1:
+ return pk.methodDefined(ik);
+ case DIRECT_2:
+ return ik.methodDefined() && pk == PruneKind.NO_PRUNE;
+ default:
+ return false;
+ }
+ }
+ }
+
+ enum ExprKind {
+ THIS("this"),
+ SUPER("super");
+
+ String exprStr;
+
+ ExprKind(String exprStr) {
+ this.exprStr = exprStr;
+ }
+ }
+
+ enum ElementKind {
+ INTERFACE("interface #N { #B }", true),
+ INTERFACE_EXTENDS("interface #N extends A, C { #B }", true),
+ CLASS("class #N { #B }", false),
+ CLASS_EXTENDS("abstract class #N implements A, C { #B }", false),
+ STATIC_CLASS("static class #N { #B }", true),
+ STATIC_CLASS_EXTENDS("abstract static class #N implements A, C { #B }", true),
+ ANON_CLASS("new Object() { #B };", false),
+ METHOD("void test() { #B }", false),
+ STATIC_METHOD("static void test() { #B }", true),
+ DEFAULT_METHOD("default void test() { #B }", false);
+
+ String templateDecl;
+ boolean isStatic;
+
+ ElementKind(String templateDecl, boolean isStatic) {
+ this.templateDecl = templateDecl;
+ this.isStatic = isStatic;
+ }
+
+ boolean isClassDecl() {
+ switch(this) {
+ case METHOD:
+ case STATIC_METHOD:
+ case DEFAULT_METHOD:
+ return false;
+ default:
+ return true;
+ }
+ }
+
+ boolean isAllowedEnclosing(ElementKind ek, boolean isTop) {
+ switch (this) {
+ case CLASS:
+ case CLASS_EXTENDS:
+ //class is implicitly static inside interface, so skip this combo
+ return ek.isClassDecl() &&
+ ek != INTERFACE && ek != INTERFACE_EXTENDS;
+ case ANON_CLASS:
+ return !ek.isClassDecl();
+ case METHOD:
+ return ek == CLASS || ek == CLASS_EXTENDS ||
+ ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS ||
+ ek == ANON_CLASS;
+ case INTERFACE:
+ case INTERFACE_EXTENDS:
+ case STATIC_CLASS:
+ case STATIC_CLASS_EXTENDS:
+ case STATIC_METHOD:
+ return (isTop && (ek == CLASS || ek == CLASS_EXTENDS)) ||
+ ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS;
+ case DEFAULT_METHOD:
+ return ek == INTERFACE || ek == INTERFACE_EXTENDS;
+ default:
+ throw new AssertionError("Bad enclosing element kind" + this);
+ }
+ }
+
+ boolean isAllowedTop() {
+ switch (this) {
+ case CLASS:
+ case CLASS_EXTENDS:
+ case INTERFACE:
+ case INTERFACE_EXTENDS:
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ boolean hasSuper() {
+ return this == INTERFACE_EXTENDS ||
+ this == STATIC_CLASS_EXTENDS ||
+ this == CLASS_EXTENDS;
+ }
+ }
+
+ static class Shape {
+
+ String shapeStr;
+ List<ElementKind> enclosingElements;
+ List<String> enclosingNames;
+ List<String> elementsWithMethod;
+
+ Shape(ElementKind... elements) {
+ System.err.println("elements = " + Arrays.toString(elements));
+ enclosingElements = new ArrayList<>();
+ enclosingNames = new ArrayList<>();
+ elementsWithMethod = new ArrayList<>();
+ int count = 0;
+ String prevName = null;
+ for (ElementKind ek : elements) {
+ String name = "name"+count++;
+ if (ek.isStatic) {
+ enclosingElements = new ArrayList<>();
+ enclosingNames = new ArrayList<>();
+ }
+ if (ek.isClassDecl()) {
+ enclosingElements.add(ek);
+ enclosingNames.add(name);
+ } else {
+ elementsWithMethod.add(prevName);
+ }
+ String element = ek.templateDecl.replaceAll("#N", name);
+ shapeStr = shapeStr == null ? element : shapeStr.replaceAll("#B", element);
+ prevName = name;
+ }
+ }
+
+ String getShape(QualifierKind qk, ExprKind ek) {
+ String methName = ek == ExprKind.THIS ? "test" : "m";
+ String call = qk.getQualifier(this) + "." + ek.exprStr + "." + methName + "();";
+ return shapeStr.replaceAll("#B", call);
+ }
+
+ String enclosingAt(int index) {
+ return index < enclosingNames.size() ? enclosingNames.get(index) : "BAD";
+ }
+ }
+
+ 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 (InterfaceKind ik : InterfaceKind.values()) {
+ for (PruneKind pk : PruneKind.values()) {
+ for (ElementKind ek1 : ElementKind.values()) {
+ if (!ek1.isAllowedTop()) continue;
+ for (ElementKind ek2 : ElementKind.values()) {
+ if (!ek2.isAllowedEnclosing(ek1, true)) continue;
+ for (ElementKind ek3 : ElementKind.values()) {
+ if (!ek3.isAllowedEnclosing(ek2, false)) continue;
+ for (ElementKind ek4 : ElementKind.values()) {
+ if (!ek4.isAllowedEnclosing(ek3, false)) continue;
+ for (ElementKind ek5 : ElementKind.values()) {
+ if (!ek5.isAllowedEnclosing(ek4, false) || ek5.isClassDecl()) continue;
+ for (QualifierKind qk : QualifierKind.values()) {
+ for (ExprKind ek : ExprKind.values()) {
+ new TestDefaultSuperCall(ik, pk, new Shape(ek1, ek2, ek3, ek4, ek5), qk, ek).run(comp, fm);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ System.out.println("Total check executed: " + checkCount);
+ }
+
+ InterfaceKind ik;
+ PruneKind pk;
+ Shape sh;
+ QualifierKind qk;
+ ExprKind ek;
+ JavaSource source;
+ DiagnosticChecker diagChecker;
+
+ TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh, QualifierKind qk, ExprKind ek) {
+ this.ik = ik;
+ this.pk = pk;
+ this.sh = sh;
+ this.qk = qk;
+ this.ek = ek;
+ this.source = new JavaSource();
+ this.diagChecker = new DiagnosticChecker();
+ }
+
+ class JavaSource extends SimpleJavaFileObject {
+
+ String template = "interface E {}\n" +
+ "interface B { }\n" +
+ "#I\n" +
+ "#P\n" +
+ "#C";
+
+ String source;
+
+ public JavaSource() {
+ super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+ source = template.replaceAll("#I", ik.interfaceStr)
+ .replaceAll("#P", pk.interfaceStr)
+ .replaceAll("#C", sh.getShape(qk, ek));
+ }
+
+ @Override
+ public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+ return source;
+ }
+ }
+
+ void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception {
+ JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker,
+ Arrays.asList("-XDallowDefaultMethods"), null, Arrays.asList(source));
+ try {
+ ct.analyze();
+ } catch (Throwable ex) {
+ throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true));
+ }
+ check();
+ }
+
+ void check() {
+ boolean errorExpected = false;
+
+ boolean badEnclosing = false;
+ boolean badThis = false;
+ boolean badSuper = false;
+
+ if (qk == QualifierKind.ENCLOSING_1 &&
+ sh.enclosingNames.size() < 1) {
+ errorExpected |= true;
+ badEnclosing = true;
+ }
+
+ if (qk == QualifierKind.ENCLOSING_2 &&
+ sh.enclosingNames.size() < 2) {
+ errorExpected |= true;
+ badEnclosing = true;
+ }
+
+ if (ek == ExprKind.THIS) {
+ boolean found = false;
+ for (int i = 0; i < sh.enclosingElements.size(); i++) {
+ if (sh.enclosingElements.get(i) == ElementKind.ANON_CLASS) continue;
+ if (sh.enclosingNames.get(i).equals(qk.getQualifier(sh))) {
+ found = sh.elementsWithMethod.contains(sh.enclosingNames.get(i));
+ break;
+ }
+ }
+ errorExpected |= !found;
+ if (!found) {
+ badThis = true;
+ }
+ }
+
+ if (ek == ExprKind.SUPER) {
+
+ int lastIdx = sh.enclosingElements.size() - 1;
+ boolean found = lastIdx == -1 ? false :
+ sh.enclosingElements.get(lastIdx).hasSuper() && qk.allowSuperCall(ik, pk);
+
+ errorExpected |= !found;
+ if (!found) {
+ badSuper = true;
+ }
+ }
+
+ checkCount++;
+ if (diagChecker.errorFound != errorExpected) {
+ throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) +
+ "\nenclosingElems: " + sh.enclosingElements +
+ "\nenclosingNames: " + sh.enclosingNames +
+ "\nelementsWithMethod: " + sh.elementsWithMethod +
+ "\nbad encl: " + badEnclosing +
+ "\nbad this: " + badThis +
+ "\nbad super: " + badSuper +
+ "\nqual kind: " + qk +
+ "\nfound error: " + diagChecker.errorFound);
+ }
+ }
+
+ static class DiagnosticChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
+
+ boolean errorFound;
+
+ public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ System.err.println(diagnostic.getMessage(Locale.getDefault()));
+ errorFound = true;
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/DefaultOverridesObjectMember.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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.default.overrides.object.member
+// options: -XDallowDefaultMethods
+
+interface DefaultOverridesObjectMember {
+ default String toString() { return ""; }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/OverriddenDefault.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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.illegal.default.super.call
+// key: compiler.misc.overridden.default
+// options: -XDallowDefaultMethods
+
+class OverriddenDefault {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+ interface K extends I {}
+
+ static class C implements J, K {
+ void foo() { K.super.m(); }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/RedundantSupertype.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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.illegal.default.super.call
+// key: compiler.misc.redundant.supertype
+// options: -XDallowDefaultMethods
+
+class RedundantSupertype {
+ interface I { default void m() { } }
+ interface J extends I { default void m() { } }
+
+ static class C implements I, J {
+ void foo() { I.super.m(); }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleAbstractDefault.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 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.types.incompatible.abstract.default
+// options: -XDallowDefaultMethods
+
+class TypesIncompatibleAbstractDefault {
+ interface A {
+ default void m() { }
+ }
+
+ interface B {
+ void m();
+ }
+
+ interface AB extends A, B { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleUnrelatedDefaults.java Sun Nov 04 10:59:42 2012 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 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.types.incompatible.unrelated.defaults
+// options: -XDallowDefaultMethods
+
+class TypesIncompatibleUnrelatedDefaults {
+ interface A {
+ default void m() { }
+ }
+
+ interface B {
+ default void m() { }
+ }
+
+ interface AB extends A, B { }
+}
--- a/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Sun Nov 04 10:59:42 2012 +0000
@@ -26,7 +26,8 @@
* @bug 7022054
*
* @summary Invalid compiler error on covariant overriding methods with the same erasure
- * @compile T7022054pos1.java
+ * @compile -source 7 T7022054pos1.java
+ * @compile/fail -XDstrictMethodClashCheck T7022054pos1.java
*
*/
--- a/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Sun Nov 04 10:59:42 2012 +0000
@@ -26,8 +26,8 @@
* @bug 7022054
*
* @summary Invalid compiler error on covariant overriding methods with the same erasure
- * @compile T7022054pos2.java
- *
+ * @compile -source 7 T7022054pos2.java
+ * @compile/fail -XDstrictMethodClashCheck T7022054pos2.java
*/
class T7022054pos2 {
--- a/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Sat Nov 03 21:09:57 2012 -0700
+++ b/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Sun Nov 04 10:59:42 2012 +0000
@@ -30,6 +30,7 @@
import java.io.File;
import java.net.URI;
import java.util.Arrays;
+import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
@@ -43,13 +44,15 @@
JavaCompiler javacTool;
File testDir;
+ VersionKind versionKind;
HierarchyKind hierarchyKind;
TestKind testKind;
ActionKind actionKind;
- EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir,
+ EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir, VersionKind versionKind,
HierarchyKind hierarchyKind, TestKind testKind, ActionKind actionKind) {
this.javacTool = javacTool;
+ this.versionKind = versionKind;
this.hierarchyKind = hierarchyKind;
this.testDir = testDir;
this.testKind = testKind;
@@ -62,7 +65,7 @@
actionKind.doAction(this);
DiagnosticChecker dc = new DiagnosticChecker();
compile(dc, testKind.source);
- if (testKind.completionFailure(actionKind, hierarchyKind) != dc.errorFound) {
+ if (testKind.completionFailure(versionKind, actionKind, hierarchyKind) != dc.errorFound) {
if (dc.errorFound) {
error("Unexpected completion failure" +
"\nhierarhcyKind " + hierarchyKind +
@@ -80,7 +83,8 @@
void compile(DiagnosticChecker dc, JavaSource... sources) {
try {
CompilationTask ct = javacTool.getTask(null, null, dc,
- Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", testDir.getAbsolutePath()),
+ Arrays.asList("-d", testDir.getAbsolutePath(), "-cp",
+ testDir.getAbsolutePath(), versionKind.optsArr[0], versionKind.optsArr[1]),
null, Arrays.asList(sources));
ct.call();
}
@@ -108,12 +112,25 @@
boolean errorFound = false;
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
- errorFound = true;
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ errorFound = true;
+ }
}
}
//global declarations
+ enum VersionKind {
+ PRE_LAMBDA("-source", "7"),
+ LAMBDA("-source", "8");
+
+ String[] optsArr;
+
+ VersionKind(String... optsArr) {
+ this.optsArr = optsArr;
+ }
+ }
+
enum HierarchyKind {
INTERFACE("interface A { boolean f = false; void m(); }\n" +
"class B implements A { public void m() {} }"),
@@ -157,13 +174,14 @@
this.source = new JavaSource("Test2.java", code);
}
- boolean completionFailure(ActionKind ak, HierarchyKind hk) {
+ boolean completionFailure(VersionKind vk, ActionKind ak, HierarchyKind hk) {
switch (this) {
case ACCESS_ONLY:
case CONSTR: return ak == ActionKind.REMOVE_B;
case FIELD:
case SUPER: return true;
- case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B;
+ case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B ||
+ (hk == HierarchyKind.INTERFACE && ak == ActionKind.REMOVE_A && vk == VersionKind.LAMBDA);
default: throw new AssertionError("Unexpected test kind " + this);
}
}
@@ -173,12 +191,15 @@
String SCRATCH_DIR = System.getProperty("user.dir");
JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler();
int n = 0;
- for (HierarchyKind hierarchyKind : HierarchyKind.values()) {
- for (TestKind testKind : TestKind.values()) {
- for (ActionKind actionKind : ActionKind.values()) {
- File testDir = new File(SCRATCH_DIR, "test"+n);
- new EagerInterfaceCompletionTest(javacTool, testDir, hierarchyKind, testKind, actionKind).test();
- n++;
+ for (VersionKind versionKind : VersionKind.values()) {
+ for (HierarchyKind hierarchyKind : HierarchyKind.values()) {
+ for (TestKind testKind : TestKind.values()) {
+ for (ActionKind actionKind : ActionKind.values()) {
+ File testDir = new File(SCRATCH_DIR, "test"+n);
+ new EagerInterfaceCompletionTest(javacTool, testDir, versionKind,
+ hierarchyKind, testKind, actionKind).test();
+ n++;
+ }
}
}
}