Merge
This commit is contained in:
commit
36f6ab1d87
@ -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\
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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>();
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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}.
|
||||
|
@ -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
|
||||
|
12
langtools/test/tools/javac/8002286/T8002286.java
Normal file
12
langtools/test/tools/javac/8002286/T8002286.java
Normal 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 { }
|
||||
}
|
3
langtools/test/tools/javac/8002286/T8002286.out
Normal file
3
langtools/test/tools/javac/8002286/T8002286.out
Normal 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
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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++) {
|
||||
|
@ -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 {}
|
@ -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) { }
|
||||
}
|
18
langtools/test/tools/javac/defaultMethods/Neg01.java
Normal file
18
langtools/test/tools/javac/defaultMethods/Neg01.java
Normal 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; }
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg01.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg01.out
Normal 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
|
26
langtools/test/tools/javac/defaultMethods/Neg02.java
Normal file
26
langtools/test/tools/javac/defaultMethods/Neg02.java
Normal 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) { }
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg02.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg02.out
Normal 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
|
38
langtools/test/tools/javac/defaultMethods/Neg03.java
Normal file
38
langtools/test/tools/javac/defaultMethods/Neg03.java
Normal 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) { }
|
||||
}
|
4
langtools/test/tools/javac/defaultMethods/Neg03.out
Normal file
4
langtools/test/tools/javac/defaultMethods/Neg03.out
Normal 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
|
14
langtools/test/tools/javac/defaultMethods/Neg04.java
Normal file
14
langtools/test/tools/javac/defaultMethods/Neg04.java
Normal 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; }
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg04.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg04.out
Normal 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
|
16
langtools/test/tools/javac/defaultMethods/Neg05.java
Normal file
16
langtools/test/tools/javac/defaultMethods/Neg05.java
Normal 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; }
|
||||
}
|
3
langtools/test/tools/javac/defaultMethods/Neg05.out
Normal file
3
langtools/test/tools/javac/defaultMethods/Neg05.out
Normal 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
|
16
langtools/test/tools/javac/defaultMethods/Neg06.java
Normal file
16
langtools/test/tools/javac/defaultMethods/Neg06.java
Normal 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 ""; }
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg06.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg06.out
Normal file
@ -0,0 +1,2 @@
|
||||
Neg06.java:10:37: compiler.err.missing.ret.stmt
|
||||
1 error
|
21
langtools/test/tools/javac/defaultMethods/Neg07.java
Normal file
21
langtools/test/tools/javac/defaultMethods/Neg07.java
Normal 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
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/defaultMethods/Neg07.out
Normal file
3
langtools/test/tools/javac/defaultMethods/Neg07.out
Normal 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
|
20
langtools/test/tools/javac/defaultMethods/Neg08.java
Normal file
20
langtools/test/tools/javac/defaultMethods/Neg08.java
Normal 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
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/defaultMethods/Neg08.out
Normal file
3
langtools/test/tools/javac/defaultMethods/Neg08.out
Normal 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
|
22
langtools/test/tools/javac/defaultMethods/Neg09.java
Normal file
22
langtools/test/tools/javac/defaultMethods/Neg09.java
Normal 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
|
||||
}
|
||||
}
|
5
langtools/test/tools/javac/defaultMethods/Neg09.out
Normal file
5
langtools/test/tools/javac/defaultMethods/Neg09.out
Normal 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
|
20
langtools/test/tools/javac/defaultMethods/Neg10.java
Normal file
20
langtools/test/tools/javac/defaultMethods/Neg10.java
Normal 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
|
||||
}
|
||||
}
|
5
langtools/test/tools/javac/defaultMethods/Neg10.out
Normal file
5
langtools/test/tools/javac/defaultMethods/Neg10.out
Normal 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
|
20
langtools/test/tools/javac/defaultMethods/Neg11.java
Normal file
20
langtools/test/tools/javac/defaultMethods/Neg11.java
Normal 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
|
||||
}
|
||||
}
|
3
langtools/test/tools/javac/defaultMethods/Neg11.out
Normal file
3
langtools/test/tools/javac/defaultMethods/Neg11.out
Normal 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
|
27
langtools/test/tools/javac/defaultMethods/Neg12.java
Normal file
27
langtools/test/tools/javac/defaultMethods/Neg12.java
Normal 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();
|
||||
}
|
||||
}
|
4
langtools/test/tools/javac/defaultMethods/Neg12.out
Normal file
4
langtools/test/tools/javac/defaultMethods/Neg12.out
Normal 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
|
18
langtools/test/tools/javac/defaultMethods/Neg13.java
Normal file
18
langtools/test/tools/javac/defaultMethods/Neg13.java
Normal 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) { }
|
||||
}
|
12
langtools/test/tools/javac/defaultMethods/Neg13.out
Normal file
12
langtools/test/tools/javac/defaultMethods/Neg13.out
Normal 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
|
11
langtools/test/tools/javac/defaultMethods/Neg14.java
Normal file
11
langtools/test/tools/javac/defaultMethods/Neg14.java
Normal 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 {}
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg14.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg14.out
Normal 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
|
14
langtools/test/tools/javac/defaultMethods/Neg15.java
Normal file
14
langtools/test/tools/javac/defaultMethods/Neg15.java
Normal 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(); }
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg15.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg15.out
Normal 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
|
13
langtools/test/tools/javac/defaultMethods/Neg16.java
Normal file
13
langtools/test/tools/javac/defaultMethods/Neg16.java
Normal 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(); }
|
||||
}
|
||||
}
|
2
langtools/test/tools/javac/defaultMethods/Neg16.out
Normal file
2
langtools/test/tools/javac/defaultMethods/Neg16.out
Normal 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
|
61
langtools/test/tools/javac/defaultMethods/Pos01.java
Normal file
61
langtools/test/tools/javac/defaultMethods/Pos01.java
Normal 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;
|
||||
}
|
||||
}
|
48
langtools/test/tools/javac/defaultMethods/Pos02.java
Normal file
48
langtools/test/tools/javac/defaultMethods/Pos02.java
Normal 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; }
|
||||
}
|
43
langtools/test/tools/javac/defaultMethods/Pos04.java
Normal file
43
langtools/test/tools/javac/defaultMethods/Pos04.java
Normal 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; }
|
||||
}
|
45
langtools/test/tools/javac/defaultMethods/Pos05.java
Normal file
45
langtools/test/tools/javac/defaultMethods/Pos05.java
Normal 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) { }
|
||||
}
|
49
langtools/test/tools/javac/defaultMethods/Pos06.java
Normal file
49
langtools/test/tools/javac/defaultMethods/Pos06.java
Normal 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) { }
|
||||
}
|
44
langtools/test/tools/javac/defaultMethods/Pos07.java
Normal file
44
langtools/test/tools/javac/defaultMethods/Pos07.java
Normal 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) {}
|
||||
}
|
46
langtools/test/tools/javac/defaultMethods/Pos08.java
Normal file
46
langtools/test/tools/javac/defaultMethods/Pos08.java
Normal 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) { }
|
||||
}
|
43
langtools/test/tools/javac/defaultMethods/Pos10.java
Normal file
43
langtools/test/tools/javac/defaultMethods/Pos10.java
Normal 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) { }
|
||||
}
|
||||
}
|
56
langtools/test/tools/javac/defaultMethods/Pos11.java
Normal file
56
langtools/test/tools/javac/defaultMethods/Pos11.java
Normal 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) { }
|
||||
}
|
39
langtools/test/tools/javac/defaultMethods/Pos12.java
Normal file
39
langtools/test/tools/javac/defaultMethods/Pos12.java
Normal 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);
|
||||
}
|
62
langtools/test/tools/javac/defaultMethods/Pos13.java
Normal file
62
langtools/test/tools/javac/defaultMethods/Pos13.java
Normal 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);
|
||||
}
|
||||
}
|
39
langtools/test/tools/javac/defaultMethods/Pos14.java
Normal file
39
langtools/test/tools/javac/defaultMethods/Pos14.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
39
langtools/test/tools/javac/defaultMethods/Pos15.java
Normal file
39
langtools/test/tools/javac/defaultMethods/Pos15.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
42
langtools/test/tools/javac/defaultMethods/Pos16.java
Normal file
42
langtools/test/tools/javac/defaultMethods/Pos16.java
Normal 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();
|
||||
}
|
||||
}
|
125
langtools/test/tools/javac/defaultMethods/TestDefaultBody.java
Normal file
125
langtools/test/tools/javac/defaultMethods/TestDefaultBody.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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 ""; }
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
147
langtools/test/tools/javac/defaultMethods/fd/FDTest.java
Normal file
147
langtools/test/tools/javac/defaultMethods/fd/FDTest.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
@ -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)"),
|
||||
};
|
||||
|
||||
}
|
@ -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 { }
|
||||
}
|
@ -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) {}
|
||||
}
|
@ -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
Loading…
Reference in New Issue
Block a user