This commit is contained in:
Lana Steuck 2012-11-09 14:47:22 -08:00
commit 36f6ab1d87
119 changed files with 5773 additions and 825 deletions

View File

@ -41,32 +41,21 @@ doclet.Window_Split_Index={0}-Index
doclet.Help=Help
doclet.Skip_navigation_links=Skip navigation links
doclet.New_Page=NewPage
doclet.None=None
doclet.Factory_Method_Detail=Static Factory Method Detail
doclet.navDeprecated=Deprecated
doclet.Deprecated_List=Deprecated List
doclet.Window_Deprecated_List=Deprecated List
doclet.Note_0_is_deprecated=Note: {0} is deprecated.
doclet.Overrides=Overrides:
doclet.in_class=in class
doclet.0_Fields_and_Methods="{0}" Fields and Methods
doclet.Index_of_Fields_and_Methods=Index of Fields and Methods
doclet.Static_variable_in=Static variable in {0}
doclet.Variable_in=Variable in {0}
doclet.Constructor_for=Constructor for {0}
doclet.Static_method_in=Static method in {0}
doclet.Method_in=Method in {0}
doclet.throws=throws
doclet.package=package
doclet.MalformedURL=Malformed URL: {0}
doclet.File_error=Error reading file: {0}
doclet.URL_error=Error fetching URL: {0}
doclet.No_Package_Comment_File=For Package {0} Package.Comment file not found
doclet.No_Source_For_Class=Source information for class {0} not available.
doclet.see.class_or_package_not_found=Tag {0}: reference not found: {1}
doclet.see.class_or_package_not_accessible=Tag {0}: reference not accessible: {1}
doclet.see.malformed_tag=Tag {0}: Malformed: {1}
doclet.Inherited_API_Summary=Inherited API Summary
doclet.Deprecated_API=Deprecated API
doclet.Deprecated_Packages=Deprecated Packages
doclet.Deprecated_Classes=Deprecated Classes
@ -92,10 +81,7 @@ doclet.deprecated_constructors=deprecated constructors
doclet.deprecated_methods=deprecated methods
doclet.deprecated_enum_constants=deprecated enum constants
doclet.deprecated_annotation_type_members=deprecated annotation type elements
doclet.Frame_Output=Frame Output
doclet.Docs_generated_by_Javadoc=Documentation generated by Javadoc.
doclet.Generated_Docs_Untitled=Generated Documentation (Untitled)
doclet.Blank=Blank
doclet.Other_Packages=Other Packages
doclet.Package_Description=Package {0} Description
doclet.Description=Description
@ -105,32 +91,22 @@ doclet.Subclasses=Direct Known Subclasses:
doclet.Subinterfaces=All Known Subinterfaces:
doclet.Implementing_Classes=All Known Implementing Classes:
doclet.also=also
doclet.Option=Option
doclet.Or=Or
doclet.Frames=Frames
doclet.No_Frames=No Frames
doclet.Package_Hierarchies=Package Hierarchies:
doclet.Hierarchy_For_Package=Hierarchy For Package {0}
doclet.Source_Code=Source Code:
doclet.Hierarchy_For_All_Packages=Hierarchy For All Packages
doclet.Cannot_handle_no_packages=Cannot handle no packages.
doclet.Frame_Alert=Frame Alert
doclet.Overview-Member-Frame=Overview Member Frame
doclet.Frame_Warning_Message=This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to {0}.
doclet.No_Script_Message=JavaScript is disabled on your browser.
doclet.Non_Frame_Version=Non-frame version
doclet.Frame_Version=Frame version
doclet.Following_From_Class=Following copied from class: {0}
doclet.Following_From_Interface=Following copied from interface: {0}
doclet.Description_From_Interface=Description copied from interface:
doclet.Description_From_Class=Description copied from class:
doclet.Standard_doclet_invoked=Standard doclet invoked...
doclet.No_Non_Deprecated_Classes_To_Document=No non-deprecated classes found to document.
doclet.Interfaces_Italic=Interfaces (italic)
doclet.Enclosing_Class=Enclosing class:
doclet.Enclosing_Interface=Enclosing interface:
doclet.Window_Source_title=Source code
doclet.Help_title=API Help
doclet.Window_Help_title=API Help
doclet.Help_line_1=How This API Document Is Organized
doclet.Help_line_2=This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
@ -168,19 +144,6 @@ doclet.Help_enum_line_3=Enum description
doclet.Help_annotation_type_line_1=Each annotation type has its own separate page with the following sections:
doclet.Help_annotation_type_line_2=Annotation Type declaration
doclet.Help_annotation_type_line_3=Annotation Type description
doclet.Style_line_1=Javadoc style sheet
doclet.Style_line_2=Define colors, fonts and other style attributes here to override the defaults
doclet.Style_line_3=Page background color
doclet.Style_Headings=Headings
doclet.Style_line_4=Table colors
doclet.Style_line_5=Dark mauve
doclet.Style_line_6=Light mauve
doclet.Style_line_7=White
doclet.Style_line_8=Font used in left-hand frame lists
doclet.Style_line_9=Example of smaller, sans-serif font in frames
doclet.Style_line_10=Navigation bar fonts and colors
doclet.Style_line_11=Dark Blue
doclet.Style_line_12=Table caption style
doclet.ClassUse_Packages.that.use.0=Packages that use {0}
doclet.ClassUse_Uses.of.0.in.1=Uses of {0} in {1}
doclet.ClassUse_Classes.in.0.used.by.1=Classes in {0} used by {1}
@ -210,12 +173,9 @@ doclet.ClassUse_No.usage.of.0=No usage of {0}
doclet.Window_ClassUse_Header=Uses of {0} {1}
doclet.ClassUse_Title=Uses of {0}<br>{1}
doclet.navClassUse=Use
doclet.link_option_twice=Extern URL link option (link or linkoffline) used twice.
doclet.Error_in_packagelist=Error in using -group option: {0} {1}
doclet.Groupname_already_used=In -group option, groupname already used: {0}
doclet.Same_package_name_used=Package name format used twice: {0}
doclet.Serialization.Excluded_Class=Non-transient field {1} uses excluded class {0}.
doclet.Serialization.Nonexcluded_Class=Non-transient field {1} uses hidden, non-included class {0}.
doclet.exception_encountered=Exception encountered while processing {1}\n{0}
doclet.usage=Provided by Standard doclet:\n\
-d <directory> Destination directory for output files\n\

View File

@ -21,10 +21,8 @@ doclet.Copying_File_0_To_Dir_1=Copying file {0} to directory {1}...
doclet.Copying_File_0_To_File_1=Copying file {0} to file {1}...
doclet.No_Public_Classes_To_Document=No public or protected classes found to document.
doclet.Unable_to_create_directory_0=Unable to create directory {0}
doclet.destination_directory_not_found_0=Destination directory not found {0}
doclet.destination_directory_not_directory_0=Destination directory is not a directory {0}
doclet.destination_directory_not_writable_0=Destination directory not writable {0}
doclet.Error_creating_tmp_file=Error creating temporary file, using default platform encoding.
doclet.Encoding_not_supported=Encoding not supported: {0}
doclet.Building_Tree=Building tree for all the packages and classes...
doclet.Building_Index=Building index for all the packages and classes...
@ -74,7 +72,6 @@ doclet.Field_Summary=Field Summary
doclet.Enum_Constant_Summary=Enum Constant Summary
doclet.Constructor_Summary=Constructor Summary
doclet.Method_Summary=Method Summary
doclet.Factory_Method_Summary=Static Factory Method Summary
doclet.Interfaces=Interfaces
doclet.Enums=Enums
doclet.AnnotationTypes=Annotation Types
@ -88,7 +85,6 @@ doclet.All_Superinterfaces=All Superinterfaces:
doclet.All_Implemented_Interfaces=All Implemented Interfaces:
doclet.All_classes_and_interfaces=All classes and interfaces (except non-static nested types)
doclet.Package_class_and_interface_descriptions=Package, class and interface descriptions
doclet.Members=Members
doclet.Interface=Interface
doclet.Class=Class
doclet.AnnotationType=Annotation Type
@ -107,18 +103,13 @@ doclet.errors=errors
doclet.Exception=Exception
doclet.exception=exception
doclet.exceptions=exceptions
doclet.extended_by=extended by
doclet.extends=extends
doclet.Package_private=(package private)
doclet.implements=implementsdoclet.Same_package_name_used=Package name format used twice: {0}
doclet.Nested_Classes_Interfaces_Inherited_From_Class=Nested classes/interfaces inherited from class
doclet.Nested_Classes_Interface_Inherited_From_Interface=Nested classes/interfaces inherited from interface
doclet.Methods_Inherited_From_Class=Methods inherited from class
doclet.Methods_Inherited_From_Interface=Methods inherited from interface
doclet.Fields_Inherited_From_Class=Fields inherited from class
doclet.Fields_Inherited_From_Interface=Fields inherited from interface
doclet.Serializable=Serializable
doclet.Externalizable=Externalizable
doclet.Annotation_Type_Member_Detail=Element Detail
doclet.Enum_Constant_Detail=Enum Constant Detail
doclet.Constants_Summary=Constant Field Values
@ -126,7 +117,6 @@ doclet.Field_Detail=Field Detail
doclet.Method_Detail=Method Detail
doclet.Constructor_Detail=Constructor Detail
doclet.Deprecated=Deprecated.
doclet.Deprecated_class=This class is deprecated.
doclet.Groupname_already_used=In -group option, groupname already used: {0}
doclet.value_tag_invalid_reference={0} (referenced by @value tag) is an unknown reference.
doclet.value_tag_invalid_constant=@value tag (which references {0}) can only be used in constants.

View File

@ -555,7 +555,7 @@ public class Util {
*
* @param cd the ClassDoc to check.
* @param lowerCaseOnly true if you want the name returned in lower case.
* If false, the first letter of the name is capatilized.
* If false, the first letter of the name is capitalized.
* @return
*/
public static String getTypeName(Configuration config,

View File

@ -67,7 +67,6 @@ public class Flags {
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);

View File

@ -206,6 +206,9 @@ public enum Source {
public boolean allowDefaultMethods() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowStrictMethodClashCheck() {
return compareTo(JDK1_8) >= 0;
}
public boolean allowEffectivelyFinalInInnerClasses() {
return compareTo(JDK1_8) >= 0;
}

View File

@ -1192,9 +1192,9 @@ public abstract class Symbol implements Element {
// 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;

View File

@ -75,6 +75,7 @@ public class Types {
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 @@ public class Types {
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 @@ public class Types {
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 @@ public class Types {
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 @@ public class Types {
}
// </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

View File

@ -135,6 +135,7 @@ public class Attr extends JCTree.Visitor {
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 @@ public class Attr extends JCTree.Visitor {
*/
boolean allowCovariantReturns;
/** Switch: support default methods ?
*/
boolean allowDefaultMethods;
/** Switch: support lambda expressions ?
*/
boolean allowLambda;
@ -898,6 +903,10 @@ public class Attr extends JCTree.Visitor {
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 @@ public class Attr extends JCTree.Visitor {
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 @@ public class Attr extends JCTree.Visitor {
}
}
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 @@ public class Attr extends JCTree.Visitor {
// 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

View File

@ -72,6 +72,10 @@ public class AttrContext {
*/
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 @@ public class AttrContext {
info.lint = lint;
info.enclVar = enclVar;
info.returnResult = returnResult;
info.defaultSuperCallSite = defaultSuperCallSite;
return info;
}

View File

@ -119,6 +119,9 @@ public class Check {
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 @@ public class Check {
*/
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 @@ public class Check {
} 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 @@ public class Check {
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 @@ public class Check {
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 @@ public class Check {
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 @@ public class Check {
}
}
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) {

View File

@ -502,7 +502,7 @@ public class Lower extends TreeTranslator {
JCNewClass tree = make.NewClass(null,
null, make.QualIdent(ctype.tsym), args, null);
tree.constructor = rs.resolveConstructor(
make_pos, attrEnv, ctype, TreeInfo.types(args), null, false, false);
make_pos, attrEnv, ctype, TreeInfo.types(args), List.<Type>nil());
tree.type = ctype;
return tree;
}
@ -3631,15 +3631,26 @@ public class Lower extends TreeTranslator {
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);
}

View File

@ -560,6 +560,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
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 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
}
}
// 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,

View File

@ -503,6 +503,14 @@ implements CRTFlags {
result = sr;
}
@Override
public void visitLetExpr(LetExpr tree) {
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
sr.mergeWith(csp(tree.defs));
sr.mergeWith(csp(tree.expr));
result = sr;
}
public void visitTypeParameter(JCTypeParameter tree) {
SourceRange sr = new SourceRange(startPos(tree), endPos(tree));
sr.mergeWith(csp(tree.bounds));
@ -525,7 +533,7 @@ implements CRTFlags {
*/
public int startPos(JCTree tree) {
if (tree == null) return Position.NOPOS;
return tree.pos;
return TreeInfo.getStartPos(tree);
}
/** The end position of given tree, if it has
@ -533,9 +541,7 @@ implements CRTFlags {
*/
public int endPos(JCTree tree) {
if (tree == null) return Position.NOPOS;
if (tree.hasTag(JCTree.Tag.BLOCK))
return ((JCBlock) tree).endpos;
return endPosTable.getEndPos(tree);
return TreeInfo.getEndPos(tree, endPosTable);
}
}

View File

@ -115,6 +115,9 @@ public class ClassReader implements Completer {
*/
boolean lintClassfile;
/** Switch: allow default methods
*/
boolean allowDefaultMethods;
/** Switch: preserve parameter names from the variable table.
*/
@ -279,6 +282,7 @@ public class ClassReader implements Completer {
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 @@ public class ClassReader implements Completer {
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

View File

@ -1540,7 +1540,7 @@ public class ClassWriter extends ClassFile {
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 @@ public class ClassWriter extends ClassFile {
result |= ACC_BRIDGE;
if ((flags & VARARGS) != 0 && target.useVarargsFlag())
result |= ACC_VARARGS;
if ((flags & DEFAULT) != 0)
result &= ~ABSTRACT;
return result;
}

View File

@ -523,7 +523,7 @@ public class Items {
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);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 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
@ -68,8 +68,8 @@ public enum Target {
/** JDK 7. */
JDK1_7("1.7", 51, 0),
/** JDK 8. */ // For now, a clone of 7
JDK1_8("1.8", 51, 0);
/** JDK 8. */
JDK1_8("1.8", 52, 0);
private static final Context.Key<Target> targetKey =
new Context.Key<Target>();

View File

@ -533,7 +533,7 @@ public class Main {
* annotation processor.
*/
void apMessage(AnnotationProcessingError ex) {
log.printLines("msg.proc.annotation.uncaught.exception");
log.printLines(PrefixKind.JAVAC, "msg.proc.annotation.uncaught.exception");
ex.getCause().printStackTrace(log.getWriter(WriterKind.NOTICE));
}

View File

@ -88,6 +88,15 @@ public class JavacParser implements Parser {
/** End position mappings container */
private final AbstractEndPosTable endPosTable;
interface ErrorRecoveryAction {
JCTree doRecover(JavacParser parser);
}
enum BasicErrorRecoveryAction implements ErrorRecoveryAction {
BLOCK_STMT {public JCTree doRecover(JavacParser parser) { return parser.parseStatementAsBlock(); }},
CATCH_CLAUSE {public JCTree doRecover(JavacParser parser) { return parser.catchClause(); }}
}
/** Construct a parser from a given scanner, tree factory and log.
*/
protected JavacParser(ParserFactory fac,
@ -2102,11 +2111,15 @@ public class JavacParser implements Parser {
nextToken();
return toP(F.at(pos).Skip());
case ELSE:
return toP(F.Exec(syntaxError("else.without.if")));
int elsePos = token.pos;
nextToken();
return doRecover(elsePos, BasicErrorRecoveryAction.BLOCK_STMT, "else.without.if");
case FINALLY:
return toP(F.Exec(syntaxError("finally.without.try")));
int finallyPos = token.pos;
nextToken();
return doRecover(finallyPos, BasicErrorRecoveryAction.BLOCK_STMT, "finally.without.try");
case CATCH:
return toP(F.Exec(syntaxError("catch.without.try")));
return doRecover(token.pos, BasicErrorRecoveryAction.CATCH_CLAUSE, "catch.without.try");
case ASSERT: {
if (allowAsserts && token.kind == ASSERT) {
nextToken();
@ -2139,6 +2152,13 @@ public class JavacParser implements Parser {
}
}
private JCStatement doRecover(int startPos, ErrorRecoveryAction action, String key) {
int errPos = S.errPos();
JCTree stm = action.doRecover(this);
S.errPos(errPos);
return toP(F.Exec(syntaxError(startPos, List.<JCTree>of(stm), key)));
}
/** CatchClause = CATCH "(" FormalParameter ")" Block
*/
protected JCCatch catchClause() {

View File

@ -574,7 +574,7 @@ compiler.err.intf.expected.here=\
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.type.var.more.than.once.in.result=\
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

View File

@ -81,6 +81,9 @@ public class JavadocMemberEnter extends MemberEnter {
docenv.makeAnnotationTypeElementDoc(meth, docComment, tree, lineMap);
else
docenv.makeMethodDoc(meth, docComment, tree, lineMap);
// release resources
tree.body = null;
}
@Override

View File

@ -267,8 +267,6 @@ class SeeTagImpl extends TagImpl implements SeeTag, LayoutCharacters {
}
if (referencedClass == null) { /* may just not be in this run */
// docenv().warning(holder, "tag.see.class_not_found",
// where, text);
// check if it's a package name
referencedPackage = docenv().lookupPackage(where);
return;

View File

@ -54,6 +54,8 @@ import static com.sun.tools.javac.code.Flags.*;
* @author Neal Gafter (rewrite)
*/
class Start {
/** Context for this invocation. */
private final Context context;
private final String defaultDocletClassName;
private final ClassLoader docletParentClassLoader;
@ -69,7 +71,7 @@ class Start {
private long defaultFilter = PUBLIC | PROTECTED;
private Messager messager;
private final Messager messager;
String docLocale = "";
@ -96,8 +98,8 @@ class Start {
PrintWriter noticeWriter,
String defaultDocletClassName,
ClassLoader docletParentClassLoader) {
Context tempContext = new Context(); // interim context until option decoding completed
messager = new Messager(tempContext, programName, errWriter, warnWriter, noticeWriter);
context = new Context();
messager = new Messager(context, programName, errWriter, warnWriter, noticeWriter);
this.defaultDocletClassName = defaultDocletClassName;
this.docletParentClassLoader = docletParentClassLoader;
}
@ -108,8 +110,8 @@ class Start {
Start(String programName, String defaultDocletClassName,
ClassLoader docletParentClassLoader) {
Context tempContext = new Context(); // interim context until option decoding completed
messager = new Messager(tempContext, programName);
context = new Context();
messager = new Messager(context, programName);
this.defaultDocletClassName = defaultDocletClassName;
this.docletParentClassLoader = docletParentClassLoader;
}
@ -219,16 +221,6 @@ class Start {
ListBuffer<String> subPackages = new ListBuffer<String>();
ListBuffer<String> excludedPackages = new ListBuffer<String>();
Context context = new Context();
// Setup a new Messager, using the same initial parameters as the
// existing Messager, except that this one will be able to use any
// options that may be set up below.
Messager.preRegister(context,
messager.programName,
messager.getWriter(Log.WriterKind.ERROR),
messager.getWriter(Log.WriterKind.WARNING),
messager.getWriter(Log.WriterKind.NOTICE));
Options compOpts = Options.instance(context);
boolean docClasses = false;
@ -368,6 +360,7 @@ class Start {
javaNames.append(arg);
}
}
compOpts.notifyListeners();
if (javaNames.isEmpty() && subPackages.isEmpty()) {
usageError("main.No_packages_or_classes_specified");
@ -394,14 +387,13 @@ class Start {
// legacy?
languageVersion == null || languageVersion == LanguageVersion.JAVA_1_1, quiet);
// release resources
comp = null;
// pass off control to the doclet
boolean ok = root != null;
if (ok) ok = docletInvoker.start(root);
Messager docletMessager = Messager.instance0(context);
messager.nwarnings += docletMessager.nwarnings;
messager.nerrors += docletMessager.nerrors;
// We're done.
if (compOpts.get("-verbose") != null) {
tm = System.currentTimeMillis() - tm;

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 1997, 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
@ -64,7 +64,6 @@ main.No_packages_or_classes_specified=No packages or classes specified.
main.incompatible.access.flags=More than one of -public, -private, -package, or -protected specified.
main.cant.read=cannot read {0}
main.Loading_source_files_for_package=Loading source files for package {0}...
main.Loading_source_file_for_class=Loading source file for class {0}...
main.Loading_source_file=Loading source file {0}...
main.Building_tree=Constructing Javadoc information...
main.no_source_files_for_package=No source files for package {0}
@ -96,13 +95,12 @@ tag.see.missing_sharp=Tag {0}: missing ''#'': "{1}"
tag.see.can_not_find_member=Tag {0}: can''t find {1} in {2}
tag.see.no_close_bracket_on_url=Tag {0}: missing final ''>'': "{1}"
tag.see.no_close_quote=Tag {0}: no final close quote: "{1}"
tag.see.class_not_found=class {0} not found for @see tag: "{1}"
tag.see.class_not_specified=Tag {0}: class not specified: "{1}"
tag.see.illegal_character=Tag {0}:illegal character: "{1}" in "{2}"
tag.see.malformed_see_tag=Tag {0}: malformed: "{1}"
tag.throws.exception_not_found={0} tag, class {1} not found.
tag.End_delimiter_missing_for_possible_SeeTag=End Delimiter } missing for possible See Tag in comment string: "{0}"
tag.Improper_Use_Of_Link_Tag=Missing closing ''}'' character for inline tag: "{0}"
tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.
javadoc.File_Read_Error=Error while reading file {0}
javadoc.Body_missing_from_html_file=Body tag missing from HTML file
javadoc.End_body_missing_from_html_file=Close body tag missing from HTML file
@ -110,4 +108,3 @@ javadoc.Multiple_package_comments=Multiple sources of package comments found for
javadoc.class_not_found=Class {0} not found.
javadoc.error=error
javadoc.warning=warning
tag.serialField.illegal_character=illegal character {0} in @serialField tag: {1}.

View File

@ -1,4 +1,4 @@
T7132880.java:23:12: compiler.err.cant.apply.symbol: kindname.method, m1, java.lang.Integer, java.lang.String, kindname.class, Outer.Inner1, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))
T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Double))),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer)))}
T7132880.java:33:12: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Integer), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))),(compiler.misc.inapplicable.method: kindname.method, Outer.Inner2, m1(java.lang.Double), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Double)))}
T7132880.java:43:12: compiler.err.ref.ambiguous: m2, kindname.method, m2(java.lang.Object,int), Outer.Inner3, kindname.method, m2(int,java.lang.Object), Outer.Inner3
3 errors

View File

@ -0,0 +1,12 @@
/*
* @test /nodynamiccopyright/
* @bug 8002286
* @summary Resolve should support nested resolution contexts
* @compile/fail/ref=T8002286.out -XDrawDiagnostics T8002286.java
*/
class T8002286 {
@Anno(nonExistent())
static class Test { }
@interface Anno { }
}

View File

@ -0,0 +1,3 @@
T8002286.java:8:22: compiler.err.cant.resolve.location.args: kindname.method, value, , , (compiler.misc.location: kindname.annotation, T8002286.Anno, null)
T8002286.java:8:11: compiler.err.cant.resolve.location.args: kindname.method, nonExistent, , , (compiler.misc.location: kindname.class, T8002286, null)
2 errors

View File

@ -1,4 +1,4 @@
T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>))}
T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605<compiler.misc.type.captureof: 1, ?>)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 2, ?, compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T))}
T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605<compiler.misc.type.captureof: 1, ?>,T6799605<compiler.misc.type.captureof: 2, ?>,T6799605<compiler.misc.type.captureof: 3, ?>,{(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, <T>m(T6799605<T>,T6799605<T>,T6799605<T>), (compiler.misc.inferred.do.not.conform.to.eq.bounds: compiler.misc.type.captureof: 3, ?, compiler.misc.type.captureof: 3, ?,compiler.misc.type.captureof: 2, ?,compiler.misc.type.captureof: 1, ?))}
3 errors

View File

@ -0,0 +1,209 @@
/*
* 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
* @bug 8002157
* @author sogoel
* @summary Basic Syntax test for repeating annotations on all elements
* @build Helper
* @compile BasicSyntaxCombo.java
* @run main BasicSyntaxCombo
*/
import java.util.Arrays;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.Diagnostic;
/*
* Generate test src for element kinds with repeating annotations.
* The test uses Helper.java to get the template to create test src and
* compile the test src.
* The test passes if valid test src compile as expected and
* and invalid test src fail as expected.
*/
public class BasicSyntaxCombo extends Helper{
static int errors = 0;
static boolean exitMode = false;
static String TESTPKG = "testpkg";
static String srcContent = "";
static String pkgInfoContent = "";
static {
// If EXIT_ON_FAIL is set, the combo test will exit at the first error
String exitOnFail = System.getenv("EXIT_ON_FAIL");
if (exitOnFail == null || exitOnFail == "" ) {
exitMode = false;
}
else {
if (exitOnFail.equalsIgnoreCase("YES") ||
exitOnFail.equalsIgnoreCase("Y") ||
exitOnFail.equalsIgnoreCase("TRUE") ||
exitOnFail.equalsIgnoreCase("T")) {
exitMode = true;
}
}
}
enum TestElem {
ANNOTATION_TYPE(true),
PACKAGE(true),
CONSTRUCTOR(true),
FIELD(true),
LOCAL_VARIABLE(true),
METHOD(true),
TYPE(true),
PARAMETER(true),
INNER_CLASS(true),
STATIC_INI(false),
INSTANCE_INI(false);
TestElem(boolean compile) {
this.compile = compile;
}
boolean compile;
boolean shouldCompile() {
return compile;
}
}
public static void main(String[] args) throws Exception {
new BasicSyntaxCombo().runTest();
}
public void runTest() throws Exception {
boolean result = false;
Iterable<? extends JavaFileObject> files = null;
int testCtr = 0;
for (TestElem type : TestElem.values()) {
testCtr++;
String className = "BasicCombo_"+type;
files = getFileList(className, type);
boolean shouldCompile = type.shouldCompile();
result = getCompileResult(className, shouldCompile,files);
if (shouldCompile && !result) {
error(className + " did not compile as expected", srcContent);
if(!pkgInfoContent.isEmpty()) {
System.out.println("package-info.java contents: " + pkgInfoContent);
}
}
if (!shouldCompile && !result) {
error(className + " compiled unexpectedly", srcContent);
if(!pkgInfoContent.isEmpty()) {
System.out.println("package-info.java contents: " + pkgInfoContent);
}
}
}
System.out.println("Total number of tests run: " + testCtr);
System.out.println("Total number of errors: " + errors);
if (errors > 0)
throw new Exception(errors + " errors found");
}
private boolean getCompileResult(String className, boolean shouldCompile,
Iterable<? extends JavaFileObject> files) throws Exception {
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
boolean ok = Helper.compileCode(diagnostics,files);
if (!shouldCompile && !ok) {
checkErrorKeys(className, diagnostics);
}
return (shouldCompile == ok);
}
private void checkErrorKeys (
String className, DiagnosticCollector<JavaFileObject> diagnostics) throws Exception {
String expectedErrKey = "compiler.err.illegal.start.of.type";
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
if ((d.getKind() == Diagnostic.Kind.ERROR) &&
d.getCode().contains(expectedErrKey)) {
break; // Found the expected error
} else {
error("Incorrect error key, expected = "
+ expectedErrKey + ", Actual = " + d.getCode()
+ " for className = " + className, srcContent);
}
}
}
private Iterable<? extends JavaFileObject> getFileList(String className,
TestElem type ) {
String template = Helper.template;
String replaceStr = "/*"+type+"*/";
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
JavaFileObject pkgInfoFile = null;
if (type.equals("PACKAGE")) {
srcContent = template.replace(replaceStr, "package testpkg;")
.replace("#ClassName", className);
String pkgInfoName = TESTPKG+"."+"package-info";
pkgInfoContent = Helper.ContentVars.REPEATABLEANNO.getVal()
+ "package " + TESTPKG + ";"
+ annoData;
pkgInfoFile = getFile(pkgInfoName, pkgInfoContent);
} else {
template = template.replace(replaceStr, Helper.ContentVars.REPEATABLEANNO.getVal())
.replace("#ClassName", className);
srcContent = annoData + template;
}
JavaFileObject srcFile = getFile(className, srcContent);
Iterable<? extends JavaFileObject> files = null;
if (pkgInfoFile != null) {
files = Arrays.asList(pkgInfoFile,srcFile);
}
else {
files = Arrays.asList(srcFile);
}
return files;
}
private void error(String msg, String... contents) throws Exception {
System.out.println("error: " + msg);
errors++;
if (contents.length == 1) {
System.out.println("Contents = " + contents[0]);
}
// Test exits as soon as it gets a failure
if (exitMode) throw new Exception();
}
}

View File

@ -0,0 +1,155 @@
/*
* 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
* @bug 8002157
* @author sogoel
* @summary Combo test to check for usage of Deprecated
* @build Helper
* @compile DeprecatedAnnoCombo.java
* @run main DeprecatedAnnoCombo
*/
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
/*
* Generate test src for use of @Deprecated on base anno
* or container anno or on both. In all cases, test src should compile and a
* warning should be generated. Repeating annotations used only on class for
* these generated test src.
*/
public class DeprecatedAnnoCombo extends Helper {
static int errors = 0;
enum TestCases {
DeprecatedonBoth,
DeprecatedonContainer,
DeprecatedonBase;
}
public static void main(String[] args) throws Exception {
new DeprecatedAnnoCombo().runTest();
}
public void runTest() throws Exception {
boolean ok = false;
int testCtr = 0;
for (TestCases clName : TestCases.values()) {
testCtr++;
// Create test source content
String contents = getContent(clName.toString());
// Compile the generated source file
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
ok = compileCode(clName.toString(), contents, diagnostics);
String errorKey1 = "compiler.note.deprecated.filename";
String errorKey2 = "compiler.note.deprecated.recompile";
List<Diagnostic<? extends JavaFileObject>> diags = diagnostics.getDiagnostics();
//Check for deprecated warnings
if (ok) {
if (diags.size() == 0) {
error("Did not get any warnings for @Deprecated usage");
} else {
for (Diagnostic<?> d : diags) {
if (d.getKind() == Diagnostic.Kind.NOTE) {
if (d.getCode().contains(errorKey1)
|| d.getCode().contains(errorKey2)) {
System.out.println("TestCase =" + clName + " passed as expected");
} else {
error("TestCase =" + clName + " did not give correct warnings" +
"Expected warning keys: " +
"errorKey1 = " + errorKey1 +
"errorKey2 = " + errorKey2 +
"actualErrorKey = " + d.getCode(), contents);
}
} else {
error("Diagnostic Kind is incorrect, expected = " +
Diagnostic.Kind.NOTE + "actual = " + d.getKind(), contents);
}
}
}
} else {
error("TestCase =" + clName + " did not compile as expected", contents);
}
}
System.out.println("Total number of tests run: " + testCtr);
System.out.println("Total number of errors: " + errors);
if (errors > 0)
throw new Exception(errors + " errors found");
}
private String getContent(String className) {
StringBuilder annoData = new StringBuilder();
switch(className) {
case "DeprecatedonBoth":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonBase":
annoData.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DEPRECATED.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DeprecatedonContainer":
annoData.append(Helper.ContentVars.DEPRECATED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ Helper.ContentVars.IMPORTDEPRECATED.getVal()
+ annoData
+ Helper.ContentVars.REPEATABLEANNO.getVal()
+ "\nclass "+ className + "{}";
return contents;
}
private void error(String msg, String... contents) {
System.out.println("error: " + msg);
errors++;
if (contents.length == 1) {
System.out.println("Contents = " + contents[0]);
}
}
}

View File

@ -0,0 +1,127 @@
/*
* 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
* @bug 8002157
* @author sogoel
* @summary Positive combo test for use of Documented on baseAnno/containerAnno
* @build Helper
* @compile DocumentedAnnoCombo.java
* @run main DocumentedAnnoCombo
*/
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
/*
* Generate valid test src for the use of @Documented on container anno
* or on both base anno and container anno. Both test src should compile.
* Repeating annotations used only on class for these generated test src.
*/
public class DocumentedAnnoCombo extends Helper {
static int errors = 0;
enum TestCases {
DocumentedonBothAnno(true),
DocumentedonContainer(true);
TestCases(boolean compile) {
this.compile = compile;
}
boolean compile;
boolean shouldCompile() {
return compile;
}
}
public static void main(String[] args) throws Exception {
new DocumentedAnnoCombo().runTest();
}
public void runTest() throws Exception {
boolean ok = false;
int testCtr = 0;
// Create test source content
for (TestCases className : TestCases.values()) {
testCtr++;
String contents = getContent(className.toString());
// Compile the generated source file
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
ok = compileCode(className.toString(), contents, diagnostics);
if (!ok) {
error("Class="+ className +" did not compile as expected", contents);
} else {
System.out.println("Test passed for className: " + className);
}
}
System.out.println("Total number of tests run: " + testCtr);
System.out.println("Total number of errors: " + errors);
if (errors > 0)
throw new Exception(errors + " errors found");
}
private String getContent(String className) {
StringBuilder annoData = new StringBuilder();
switch(className) {
case "DocumentedonBothAnno":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.DOCUMENTED.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "DocumentedonContainer":
annoData.append(Helper.ContentVars.DOCUMENTED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ Helper.ContentVars.IMPORTDOCUMENTED.getVal()
+ annoData
+ Helper.ContentVars.REPEATABLEANNO.getVal()
+ "\nclass "+ className + "{}";
return contents;
}
private void error(String msg, String... contents) {
System.out.println("error: " + msg);
errors++;
if (contents.length == 1) {
System.out.println("Contents = " + contents[0]);
}
}
}

View File

@ -0,0 +1,154 @@
/*
* 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.
*/
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Arrays;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask;
public class Helper {
enum ContentVars {
IMPORTCONTAINERSTMTS("\nimport java.lang.annotation.ContainedBy;\n" +
"\nimport java.lang.annotation.ContainerFor;\n"),
IMPORTDEPRECATED("import java.lang.Deprecated;\n"),
IMPORTDOCUMENTED("import java.lang.annotation.Documented;\n"),
IMPORTINHERITED("import java.lang.annotation.Inherited;\n"),
IMPORTRETENTION("import java.lang.annotation.Retention;\n" +
"\nimport java.lang.annotation.RetentionPolicy;\n"),
CONTAINEDBY("\n@ContainedBy(FooContainer.class)\n"),
CONTAINERFOR("@ContainerFor(Foo.class)\n"),
CONTAINER("@interface FooContainer {\n" +" Foo[] value();\n}\n"),
BASE("@interface Foo {}\n"),
REPEATABLEANNO("\n@Foo() @Foo()"),
DEPRECATED("\n@Deprecated"),
DOCUMENTED("\n@Documented"),
INHERITED("\n@Inherited"),
RETENTION("@Retention(RetentionPolicy.#VAL)\n");
private String val;
private ContentVars(String val) {
this.val = val;
}
public String getVal() {
return val;
}
}
/* String template where /*<TYPE>*/ /*gets replaced by repeating anno
* Used to generate test src for combo tests
* - BasicSyntaxCombo.java
* - TargetAnnoCombo.java
*/
public static final String template =
"/*PACKAGE*/\n" +
"//pkg test;\n\n" +
"/*TYPE*/ //class\n" +
"class #ClassName {\n" +
" /*FIELD*/ //instance var\n" +
" public int x = 0;\n\n" +
" /*FIELD*/ //Enum constants\n" +
" TestEnum testEnum;\n\n" +
" /*FIELD*/ // Static field\n" +
" public static int num;\n\n" +
" /*STATIC_INI*/\n" +
" static { \n" + "num = 10; \n }\n\n" +
" /*CONSTRUCTOR*/\n" +
" #ClassName() {}\n\n" +
" /*INSTANCE_INI*/\n" +
" { \n x = 10; \n }" +
" /*INNER_CLASS*/\n" +
" class innerClass {}\n" +
" /*METHOD*/\n" +
" void bar(/*PARAMETER*/ int baz) {\n" +
" /*LOCAL_VARIABLE*/\n" +
" int y = 0;\n" +
" }\n" +
"}\n\n" +
"/*TYPE*/ //Enum\n" +
"enum TestEnum {}\n\n" +
"/*TYPE*/ //Interface\n" +
"interface TestInterface {}\n\n" +
"/*TYPE*/\n" +
"/*ANNOTATION_TYPE*/\n" +
"@interface TestAnnotationType{}\n";
// Create and compile FileObject using values for className and contents
public static boolean compileCode(String className, String contents,
DiagnosticCollector<JavaFileObject> diagnostics) {
boolean ok = false;
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new RuntimeException("can't get javax.tools.JavaCompiler!");
}
JavaFileObject file = getFile(className, contents);
Iterable<? extends JavaFileObject> compilationUnit = Arrays.asList(file);
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, compilationUnit);
ok = task.call();
return ok;
}
// Compile a list of FileObjects
public static boolean compileCode(DiagnosticCollector<JavaFileObject> diagnostics, Iterable<? extends JavaFileObject> files) {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
throw new RuntimeException("can't get javax.tools.JavaCompiler!");
}
CompilationTask task = compiler.getTask(null, null, diagnostics, null, null, files);
boolean ok = task.call();
return ok;
}
static JavaFileObject getFile(String name, String code) {
JavaFileObject o = null;
try {
o = new JavaStringFileObject(name, code);
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
return o;
}
static class JavaStringFileObject extends SimpleJavaFileObject {
final String theCode;
public JavaStringFileObject(String fileName, String theCode) throws URISyntaxException {
super(new URI("string:///" + fileName.replace('.','/') + ".java"), Kind.SOURCE);
this.theCode = theCode;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return theCode;
}
}
}

View File

@ -0,0 +1,128 @@
/*
* 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
* @bug 8002157
* @author sogoel
* @summary Positive combo test for use of Inherited on baseAnno/containerAnno
* @build Helper
* @compile InheritedAnnoCombo.java
* @run main InheritedAnnoCombo
*/
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
/*
* Generate valid test src for the use of @Inherited on container anno
* or on both base anno and container anno. Both test src should compile.
* Repeating annotations used only on class for these generated test src.
*/
public class InheritedAnnoCombo extends Helper {
static int errors = 0;
enum TestCases {
InheritedonBothAnno(true),
InheritedonBase(true);
TestCases(boolean compile) {
this.compile = compile;
}
boolean compile;
boolean shouldCompile() {
return compile;
}
}
public static void main(String[] args) throws Exception {
new InheritedAnnoCombo().runTest();
}
public void runTest() throws Exception {
int testCtr = 0;
boolean ok = false;
// Create test source content
for (TestCases className : TestCases.values()) {
testCtr++;
String contents = getContent(className.toString());
// Compile the generated code
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
ok = compileCode(className.toString(), contents, diagnostics);
if (!ok) {
error("Class="+ className +" did not compile as expected", contents);
} else {
System.out.println("Test passed for className: " + className);
}
}
System.out.println("Total number of tests run: " + testCtr);
System.out.println("Total number of errors: " + errors);
if (errors > 0)
throw new Exception(errors + " errors found");
}
private String getContent(String className) {
StringBuilder annoData = new StringBuilder();
switch(className) {
case "InheritedonBothAnno":
annoData.append(Helper.ContentVars.INHERITED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.INHERITED.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
case "InheritedonBase":
annoData.append(Helper.ContentVars.INHERITED.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(Helper.ContentVars.BASE.getVal());
break;
}
String contents = Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal()
+ Helper.ContentVars.IMPORTINHERITED.getVal()
+ annoData
+ Helper.ContentVars.REPEATABLEANNO.getVal()
+ "\nclass "+ className + "{}";
return contents;
}
private void error(String msg, String... contents) {
System.out.println("error: " + msg);
errors++;
if (contents.length == 1) {
System.out.println("Contents = " + contents[0]);
}
}
}

View File

@ -0,0 +1,201 @@
/*
* 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
* @bug 8002157
* @author sogoel
* @summary Combo test for all possible combinations for Retention Values
* @build Helper
* @compile RetentionAnnoCombo.java
* @run main RetentionAnnoCombo
*/
import java.util.HashMap;
import java.util.Map;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import javax.tools.Diagnostic;
/*
* Generate all combinations for the use of @Retention on base anno or container
* anno or both. The test passes if valid test src compile as expected and
* and invalid test src fail as expected.
* Repeating annotations used only on class for these generated test src.
*/
public class RetentionAnnoCombo extends Helper {
static int errors = 0;
static boolean exitMode = false;
static {
String exitOnFail = System.getenv("EXIT_ON_FAIL");
if (exitOnFail == null || exitOnFail == "" ) {
exitMode = false;
}
else {
if (exitOnFail.equalsIgnoreCase("YES") ||
exitOnFail.equalsIgnoreCase("Y") ||
exitOnFail.equalsIgnoreCase("TRUE") ||
exitOnFail.equalsIgnoreCase("T")) {
exitMode = true;
}
}
}
public static void main(String args[]) throws Exception {
new RetentionAnnoCombo().runTest();
}
public void runTest() throws Exception {
/* 4x4 matrix for Retention values SOURCE, DEFAULT, CLASS, RUNTIME
* i -> Retention value on ContainerAnno
* j -> Retention value on BaseAnno
* 1 -> retention value combo should compile
*/
int[][] retention = { {1, 0, 0, 0},
{1, 1, 1, 0},
{1, 1, 1, 0},
{1, 1, 1, 1} };
Map<Integer, String> retMap = setRetentionValMatrix();
String contents = "";
boolean result = false;
int testCtr = 0;
for (int i = 0; i < 4 ; i ++) {
for (int j = 0; j < 4; j++ ) {
testCtr++;
String className = "RetentionTest_"+i+"_"+j;
contents = getContent(className, retMap, i, j);
if (retention[i][j] == 1) {
// Code generated should compile
result = getCompileResult(contents,className, true);
if (!result) {
error("FAIL: " + className + " did not compile as expected!", contents);
}
} else {
result = getCompileResult(contents,className, false);
if (!result) {
error("FAIL: " + className + " compiled unexpectedly!", contents);
}
}
if (result) {
System.out.println("Test passed for className = " + className);
}
}
}
System.out.println("Total number of tests run: " + testCtr);
System.out.println("Total number of errors: " + errors);
if (errors > 0)
throw new Exception(errors + " errors found");
}
private boolean getCompileResult(String contents, String className,
boolean shouldCompile) throws Exception{
DiagnosticCollector<JavaFileObject> diagnostics =
new DiagnosticCollector<JavaFileObject>();
boolean ok = compileCode(className, contents, diagnostics);
String expectedErrKey = "compiler.err.invalid.containedby" +
".annotation.retention";
if (!shouldCompile && !ok) {
for (Diagnostic<?> d : diagnostics.getDiagnostics()) {
if (!((d.getKind() == Diagnostic.Kind.ERROR) &&
d.getCode().contains(expectedErrKey))) {
error("FAIL: Incorrect error given, expected = "
+ expectedErrKey + ", Actual = " + d.getCode()
+ " for className = " + className, contents);
}
}
}
return (shouldCompile == ok);
}
private Map<Integer,String> setRetentionValMatrix() {
HashMap<Integer,String> hm = new HashMap<>();
hm.put(0,"SOURCE");
hm.put(1,"DEFAULT");
hm.put(2,"CLASS");
hm.put(3,"RUNTIME");
return hm;
}
private String getContent(String className, Map<Integer, String> retMap,
int i, int j) {
String retContainerVal = retMap.get(i).toString();
String retBaseVal = retMap.get(j).toString();
String replacedRetBaseVal = "", replacedRetCAVal = "";
String retention = Helper.ContentVars.RETENTION.getVal();
// @Retention is available as default for both base and container anno
if (retContainerVal.equalsIgnoreCase("DEFAULT")
&& retBaseVal.equalsIgnoreCase("DEFAULT")) {
replacedRetBaseVal = "";
replacedRetCAVal = "";
// @Retention is available as default for container anno
} else if (retContainerVal.equalsIgnoreCase("DEFAULT")) {
replacedRetBaseVal = retention.replace("#VAL", retBaseVal);
replacedRetCAVal = "";
// @Retention is available as default for base anno
} else if (retBaseVal.equalsIgnoreCase("DEFAULT")) {
replacedRetBaseVal = "";
replacedRetCAVal = retention.replace("#VAL", retContainerVal);
// @Retention is not available as default for both base and container anno
} else {
replacedRetBaseVal = retention.replace("#VAL", retBaseVal);
replacedRetCAVal = retention.replace("#VAL", retContainerVal);
}
StringBuilder annoData = new StringBuilder();
annoData.append(Helper.ContentVars.IMPORTCONTAINERSTMTS.getVal())
.append(Helper.ContentVars.IMPORTRETENTION.getVal())
.append(Helper.ContentVars.CONTAINERFOR.getVal())
.append(replacedRetCAVal)
.append(Helper.ContentVars.CONTAINER.getVal())
.append(Helper.ContentVars.CONTAINEDBY.getVal())
.append(replacedRetBaseVal)
.append(Helper.ContentVars.BASE.getVal());
String contents = annoData
+ Helper.ContentVars.REPEATABLEANNO.getVal()
+ "\nclass "+ className + "{}";
return contents;
}
private void error(String msg,String... contents) throws Exception {
System.out.println("error: " + msg);
errors++;
if (contents.length == 1) {
System.out.println("Contents = " + contents[0]);
}
// Test exits as soon as it gets a failure
if (exitMode) throw new Exception();
}
}

View File

@ -23,7 +23,7 @@
/*
* @test
* @bug 7157626
* @bug 7157626 8001112
* @summary Test major version for all legal combinations for -source and -target
* @author sgoel
*
@ -57,14 +57,14 @@ public class ClassVersionChecker {
* -1 => invalid combinations
*/
int[][] ver =
{{51, -1, -1, -1, -1, -1, -1, -1},
{48, 46, 47, 48, 49, 50, 51, 51},
{48, 46, 47, 48, 49, 50, 51, 51},
{48, -1, -1, 48, 49, 50, 51, 51},
{51, -1, -1, -1, 49, 50, 51, 51},
{51, -1, -1, -1, -1, 50, 51, 51},
{51, -1, -1, -1, -1, -1, 51, 51},
{51, -1, -1, -1, -1, -1, -1, 51}};
{{52, -1, -1, -1, -1, -1, -1, -1},
{48, 46, 47, 48, 49, 50, 51, 52},
{48, 46, 47, 48, 49, 50, 51, 52},
{48, -1, -1, 48, 49, 50, 51, 52},
{52, -1, -1, -1, 49, 50, 51, 52},
{52, -1, -1, -1, -1, 50, 51, 52},
{52, -1, -1, -1, -1, -1, 51, 52},
{52, -1, -1, -1, -1, -1, -1, 52}};
// Loop to run all possible combinations of source/target values
for (int i = 0; i< ver.length; i++) {

View File

@ -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 {}

View File

@ -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) { }
}

View File

@ -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; }
}

View File

@ -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

View File

@ -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) { }
}

View File

@ -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

View File

@ -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) { }
}

View File

@ -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

View File

@ -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; }
}

View File

@ -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

View File

@ -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; }
}

View File

@ -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

View File

@ -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 ""; }
}
}

View File

@ -0,0 +1,2 @@
Neg06.java:10:37: compiler.err.missing.ret.stmt
1 error

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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();
}
}

View File

@ -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.I1, m(java.lang.String), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, Neg12.B, m(java.lang.Integer), (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

View File

@ -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) { }
}

View File

@ -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

View File

@ -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 {}
}

View File

@ -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

View File

@ -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(); }
}
}

View File

@ -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

View File

@ -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(); }
}
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -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) { }
}

View File

@ -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) { }
}

View File

@ -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) {}
}

View File

@ -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) { }
}

View File

@ -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) { }
}
}

View File

@ -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) { }
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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 ""; }
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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);
}
},
});
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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)"),
};
}

View File

@ -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 { }
}

View File

@ -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) {}
}

View File

@ -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;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More