diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
index e38bb2bf9ea..9dedf79fc52 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties
@@ -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}
{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 Destination directory for output files\n\
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
index 46976a5c3b6..f476b1b861f 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties
@@ -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.
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 1e8da4906d8..36c141aeba7 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -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,
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
index 8c9d9000af4..1a71cab46ee 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java
@@ -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);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
index 04a59cec522..afa1c437d0a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java
@@ -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;
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
index 3c2dce90873..09b38d68587 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java
@@ -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;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index 988a25d01ff..c8b6b258462 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -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("");
@@ -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;
+ }
//
//
@@ -2310,6 +2319,10 @@ public class Types {
return false;
}
+ public boolean overridesObjectMethod(Symbol msym) {
+ return ((MethodSymbol)msym).implementation(syms.objectType.tsym, this, true) != null;
+ }
+
//
class ImplementationCache {
@@ -2455,6 +2468,70 @@ public class Types {
}
//
+
+ //where
+ public List interfaceCandidates(Type site, MethodSymbol ms) {
+ return interfaceCandidates(site, ms, false);
+ }
+
+ public List interfaceCandidates(Type site, MethodSymbol ms, boolean intfOnly) {
+ Filter filter = new MethodFilter(ms, site, intfOnly);
+ List 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 prune(List methods, Comparator cmp) {
+ ListBuffer 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 ownerComparator = new Comparator() {
+ public int compare(MethodSymbol s1, MethodSymbol s2) {
+ return s1.owner.isSubClass(s2.owner, Types.this) ? -1 : 1;
+ }
+ };
+ // where
+ private class MethodFilter implements Filter {
+
+ 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));
+ }
+ };
+ //
+
/**
* Does t have the same arguments as s? It is assumed that both
* types are (possibly polymorphic) method types. Monomorphic
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
index ca8d2a4fe87..6e0027b5a64 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
@@ -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 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
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java
index 568ad6766a3..cbc79e223bd 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java
@@ -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;
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index 8e0d6aa7bdc..52dccced8a6 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -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 prov = types.interfaceCandidates(site, (MethodSymbol)m);
+ if (prov.size() > 1) {
+ ListBuffer abstracts = ListBuffer.lb();
+ ListBuffer 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 {
+
+ 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) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index c52ffb76460..4273e857535 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -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.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);
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
index b2e9997bfce..c290f8c71be 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java
@@ -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 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,
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 448ecfd474a..cbc5bccb9aa 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -51,7 +51,10 @@ import java.util.Collection;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
import java.util.Map;
+import java.util.Set;
import javax.lang.model.element.ElementVisitor;
@@ -88,6 +91,7 @@ public class Resolve {
public final boolean boxingEnabled; // = source.allowBoxing();
public final boolean varargsEnabled; // = source.allowVarargs();
public final boolean allowMethodHandles;
+ public final boolean allowDefaultMethods;
private final boolean debugResolve;
final EnumSet verboseResolutionMode;
@@ -122,6 +126,7 @@ public class Resolve {
verboseResolutionMode = VerboseResolutionMode.getVerboseResolutionMode(options);
Target target = Target.instance(context);
allowMethodHandles = target.hasMethodHandles();
+ allowDefaultMethods = source.allowDefaultMethods();
polymorphicSignatureScope = new Scope(syms.noSymbol);
inapplicableMethodException = new InapplicableMethodException(diags);
@@ -447,22 +452,9 @@ public class Resolve {
List typeargtypes,
boolean allowBoxing,
boolean useVarargs,
- Warner warn)
- throws Infer.InferenceException {
- if (useVarargs && (m.flags() & VARARGS) == 0) {
- //better error recovery - if we stumbled upon a non-varargs method
- //during varargs applicability phase, the method should be treated as
- //not applicable; the reason for inapplicability can be found in the
- //candidate for 'm' that was created during the BOX phase.
- Candidate prevCandidate = currentResolutionContext.getCandidate(m, BOX);
- JCDiagnostic details = null;
- if (prevCandidate != null && !prevCandidate.isApplicable()) {
- details = prevCandidate.details;
- }
- throw inapplicableMethodException.setMessage(details);
- }
- Type mt = types.memberType(site, m);
+ Warner warn) throws Infer.InferenceException {
+ Type mt = types.memberType(site, m);
// tvars is the list of formal type variables for which type arguments
// need to inferred.
List tvars = List.nil();
@@ -1020,8 +1012,11 @@ public class Resolve {
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
- if (sym.kind == ERR) return bestSoFar;
- if (!sym.isInheritedIn(site.tsym, types)) return bestSoFar;
+ if (sym.kind == ERR ||
+ !sym.isInheritedIn(site.tsym, types) ||
+ (useVarargs && (sym.flags() & VARARGS) == 0)) {
+ return bestSoFar;
+ }
Assert.check(sym.kind < AMBIGUOUS);
try {
Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
@@ -1032,13 +1027,13 @@ public class Resolve {
if (!operator)
currentResolutionContext.addInapplicableCandidate(sym, ex.getDiagnostic());
switch (bestSoFar.kind) {
- case ABSENT_MTH:
- return new InapplicableSymbolError(currentResolutionContext);
- case WRONG_MTH:
- if (operator) return bestSoFar;
- bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
- default:
- return bestSoFar;
+ case ABSENT_MTH:
+ return new InapplicableSymbolError(currentResolutionContext);
+ case WRONG_MTH:
+ if (operator) return bestSoFar;
+ bestSoFar = new InapplicableSymbolsError(currentResolutionContext);
+ default:
+ return bestSoFar;
}
}
if (!isAccessible(env, site, sym)) {
@@ -1327,6 +1322,42 @@ public class Resolve {
}
}
+ Symbol findMethodInScope(Env env,
+ Type site,
+ Name name,
+ List argtypes,
+ List typeargtypes,
+ Scope sc,
+ Symbol bestSoFar,
+ boolean allowBoxing,
+ boolean useVarargs,
+ boolean operator,
+ boolean abstractok) {
+ for (Symbol s : sc.getElementsByName(name, new LookupFilter(abstractok))) {
+ bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
+ bestSoFar, allowBoxing, useVarargs, operator);
+ }
+ return bestSoFar;
+ }
+ //where
+ class LookupFilter implements Filter {
+
+ boolean abstractOk;
+
+ LookupFilter(boolean abstractOk) {
+ this.abstractOk = abstractOk;
+ }
+
+ public boolean accepts(Symbol s) {
+ long flags = s.flags();
+ return s.kind == MTH &&
+ (flags & SYNTHETIC) == 0 &&
+ (abstractOk ||
+ (flags & DEFAULT) != 0 ||
+ (flags & ABSTRACT) == 0);
+ }
+ };
+
/** Find best qualified method matching given name, type and value
* arguments.
* @param env The current environment.
@@ -1371,49 +1402,76 @@ public class Resolve {
boolean allowBoxing,
boolean useVarargs,
boolean operator) {
- boolean abstractOk = true;
- List itypes = List.nil();
+ @SuppressWarnings({"unchecked","rawtypes"})
+ List[] itypes = (List[])new List[] { List.nil(), List.nil() };
+ InterfaceLookupPhase iphase = InterfaceLookupPhase.ABSTRACT_OK;
for (TypeSymbol s : superclasses(intype)) {
- bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
+ bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
s.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- //We should not look for abstract methods if receiver is a concrete class
- //(as concrete classes are expected to implement all abstracts coming
- //from superinterfaces)
- abstractOk &= (s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0;
- if (abstractOk) {
+ if (name == names.init) return bestSoFar;
+ iphase = (iphase == null) ? null : iphase.update(s, this);
+ if (iphase != null) {
for (Type itype : types.interfaces(s.type)) {
- itypes = types.union(types.closure(itype), itypes);
+ itypes[iphase.ordinal()] = types.union(types.closure(itype), itypes[iphase.ordinal()]);
}
}
- if (name == names.init) break;
}
Symbol concrete = bestSoFar.kind < ERR &&
(bestSoFar.flags() & ABSTRACT) == 0 ?
bestSoFar : methodNotFound;
- if (name != names.init) {
+ for (InterfaceLookupPhase iphase2 : InterfaceLookupPhase.values()) {
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK && !allowDefaultMethods) break;
//keep searching for abstract methods
- for (Type itype : itypes) {
+ for (Type itype : itypes[iphase2.ordinal()]) {
if (!itype.isInterface()) continue; //skip j.l.Object (included by Types.closure())
- bestSoFar = lookupMethod(env, site, name, argtypes, typeargtypes,
- itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
- if (concrete != bestSoFar &&
- concrete.kind < ERR && bestSoFar.kind < ERR &&
- types.isSubSignature(concrete.type, bestSoFar.type)) {
- //this is an hack - as javac does not do full membership checks
- //most specific ends up comparing abstract methods that might have
- //been implemented by some concrete method in a subclass and,
- //because of raw override, it is possible for an abstract method
- //to be more specific than the concrete method - so we need
- //to explicitly call that out (see CR 6178365)
- bestSoFar = concrete;
- }
+ if (iphase2 == InterfaceLookupPhase.DEFAULT_OK &&
+ (itype.tsym.flags() & DEFAULT) == 0) continue;
+ bestSoFar = findMethodInScope(env, site, name, argtypes, typeargtypes,
+ itype.tsym.members(), bestSoFar, allowBoxing, useVarargs, operator, true);
+ if (concrete != bestSoFar &&
+ concrete.kind < ERR && bestSoFar.kind < ERR &&
+ types.isSubSignature(concrete.type, bestSoFar.type)) {
+ //this is an hack - as javac does not do full membership checks
+ //most specific ends up comparing abstract methods that might have
+ //been implemented by some concrete method in a subclass and,
+ //because of raw override, it is possible for an abstract method
+ //to be more specific than the concrete method - so we need
+ //to explicitly call that out (see CR 6178365)
+ bestSoFar = concrete;
+ }
}
}
return bestSoFar;
}
+ enum InterfaceLookupPhase {
+ ABSTRACT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ //We should not look for abstract methods if receiver is a concrete class
+ //(as concrete classes are expected to implement all abstracts coming
+ //from superinterfaces)
+ if ((s.flags() & (ABSTRACT | INTERFACE | ENUM)) != 0) {
+ return this;
+ } else if (rs.allowDefaultMethods) {
+ return DEFAULT_OK;
+ } else {
+ return null;
+ }
+ }
+ },
+ DEFAULT_OK() {
+ @Override
+ InterfaceLookupPhase update(Symbol s, Resolve rs) {
+ return this;
+ }
+ };
+
+ abstract InterfaceLookupPhase update(Symbol s, Resolve rs);
+ }
+
/**
* Return an Iterable object to scan the superclasses of a given type.
* It's crucial that the scan is done lazily, as we don't want to accidentally
@@ -1467,34 +1525,6 @@ public class Resolve {
};
}
- /**
- * Lookup a method with given name and argument types in a given scope
- */
- Symbol lookupMethod(Env env,
- Type site,
- Name name,
- List argtypes,
- List typeargtypes,
- Scope sc,
- Symbol bestSoFar,
- boolean allowBoxing,
- boolean useVarargs,
- boolean operator,
- boolean abstractok) {
- for (Symbol s : sc.getElementsByName(name, lookupFilter)) {
- bestSoFar = selectBest(env, site, argtypes, typeargtypes, s,
- bestSoFar, allowBoxing, useVarargs, operator);
- }
- return bestSoFar;
- }
- //where
- Filter lookupFilter = new Filter() {
- public boolean accepts(Symbol s) {
- return s.kind == MTH &&
- (s.flags() & SYNTHETIC) == 0;
- }
- };
-
/** Find unqualified method matching given name, type and value arguments.
* @param env The current environment.
* @param name The method's name.
@@ -1898,7 +1928,7 @@ public class Resolve {
((InapplicableSymbolError)errSym).errCandidate().sym : accessedSym;
List argtypes2 = Type.map(argtypes,
- deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.firstErroneousResolutionPhase()));
+ deferredAttr.new RecoveryDeferredTypeMap(AttrMode.SPECULATIVE, msym, currentResolutionContext.step));
if (msym != accessedSym) {
//fixup deferred type caches - this 'hack' is required because the symbol
@@ -1920,7 +1950,7 @@ public class Resolve {
/** Check that sym is not an abstract method.
*/
void checkNonAbstract(DiagnosticPosition pos, Symbol sym) {
- if ((sym.flags() & ABSTRACT) != 0)
+ if ((sym.flags() & ABSTRACT) != 0 && (sym.flags() & DEFAULT) == 0)
log.error(pos, "abstract.cant.be.accessed.directly",
kindName(sym), sym, sym.location());
}
@@ -1992,33 +2022,14 @@ public class Resolve {
Name name,
List argtypes,
List typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findFun(env, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired,
- steps.head.isVarargsRequired);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, env.enclClass.sym, new BasicLookupHelper(name, env.enclClass.sym.type, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return findFun(env, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, env.enclClass.sym.type, name, false, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- }
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** Resolve a qualified method identifier
@@ -2044,40 +2055,27 @@ public class Resolve {
DiagnosticPosition pos, Env env,
Symbol location, Type site, Name name, List argtypes,
List typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = resolveContext;
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findMethod(env, site, name, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired(), false);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, location, resolveContext, new BasicLookupHelper(name, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired(), false);
}
- if (sym.kind >= AMBIGUOUS) {
- //if nothing is found return the 'first' error
- MethodResolutionPhase errPhase =
- currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, location, site, name, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- } else if (allowMethodHandles) {
- MethodSymbol msym = (MethodSymbol)sym;
- if (msym.isSignaturePolymorphic(types)) {
- env.info.pendingResolutionPhase = BASIC;
- return findPolymorphicSignatureInstance(env, sym, argtypes);
+ @Override
+ Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ sym = super.access(env, pos, location, sym);
+ } else if (allowMethodHandles) {
+ MethodSymbol msym = (MethodSymbol)sym;
+ if (msym.isSignaturePolymorphic(types)) {
+ env.info.pendingResolutionPhase = BASIC;
+ return findPolymorphicSignatureInstance(env, sym, argtypes);
+ }
}
+ return sym;
}
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** Find or create an implicit method of exactly the given type (after erasure).
@@ -2145,38 +2143,53 @@ public class Resolve {
List typeargtypes) {
return resolveConstructor(new MethodResolutionContext(), pos, env, site, argtypes, typeargtypes);
}
+
private Symbol resolveConstructor(MethodResolutionContext resolveContext,
- DiagnosticPosition pos,
+ final DiagnosticPosition pos,
Env env,
Type site,
List argtypes,
List typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = resolveContext;
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findConstructor(pos, env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired());
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, site.tsym, resolveContext, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return findConstructor(pos, env, site, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {//if nothing is found return the 'first' error
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(currentResolutionContext.resolutionCache.get(errPhase),
- pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
- }
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
+ }
+
+ /** Resolve a constructor, throw a fatal error if not found.
+ * @param pos The position to use for error reporting.
+ * @param env The environment current at the method invocation.
+ * @param site The type to be constructed.
+ * @param argtypes The types of the invocation's value arguments.
+ * @param typeargtypes The types of the invocation's type arguments.
+ */
+ public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env env,
+ Type site,
+ List argtypes,
+ List typeargtypes) {
+ MethodResolutionContext resolveContext = new MethodResolutionContext();
+ resolveContext.internalResolution = true;
+ Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
+ if (sym.kind == MTH) return (MethodSymbol)sym;
+ else throw new FatalError(
+ diags.fragment("fatal.err.cant.locate.ctor", site));
+ }
+
+ Symbol findConstructor(DiagnosticPosition pos, Env env,
+ Type site, List argtypes,
+ List typeargtypes,
+ boolean allowBoxing,
+ boolean useVarargs) {
+ Symbol sym = findMethod(env, site,
+ names.init, argtypes,
+ typeargtypes, allowBoxing,
+ useVarargs, false);
+ chk.checkDeprecated(pos, env.info.scope.owner, sym);
+ return sym;
}
/** Resolve constructor using diamond inference.
@@ -2194,47 +2207,36 @@ public class Resolve {
Type site,
List argtypes,
List typeargtypes) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = findDiamond(env, site, argtypes, typeargtypes,
- steps.head.isBoxingRequired(),
- steps.head.isVarargsRequired());
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
+ return lookupMethod(env, pos, site.tsym, new BasicLookupHelper(names.init, site, argtypes, typeargtypes) {
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return findDiamond(env, site, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired());
}
- if (sym.kind >= AMBIGUOUS) {
- Symbol errSym =
- currentResolutionContext.resolutionCache.get(currentResolutionContext.firstErroneousResolutionPhase());
- final JCDiagnostic details = errSym.kind == WRONG_MTH ?
- ((InapplicableSymbolError)errSym).errCandidate().details :
- null;
- errSym = new InapplicableSymbolError(errSym.kind, "diamondError", currentResolutionContext) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
- Symbol location, Type site, Name name, List argtypes, List typeargtypes) {
- String key = details == null ?
- "cant.apply.diamond" :
- "cant.apply.diamond.1";
- return diags.create(dkind, log.currentSource(), pos, key,
- diags.fragment("diamond", site.tsym), details);
- }
- };
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- sym = accessMethod(errSym, pos, site, names.init, true, argtypes, typeargtypes);
- env.info.pendingResolutionPhase = errPhase;
+ @Override
+ Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ final JCDiagnostic details = sym.kind == WRONG_MTH ?
+ ((InapplicableSymbolError)sym).errCandidate().details :
+ null;
+ sym = new InapplicableSymbolError(sym.kind, "diamondError", currentResolutionContext) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos,
+ Symbol location, Type site, Name name, List argtypes, List typeargtypes) {
+ String key = details == null ?
+ "cant.apply.diamond" :
+ "cant.apply.diamond.1";
+ return diags.create(dkind, log.currentSource(), pos, key,
+ diags.fragment("diamond", site.tsym), details);
+ }
+ };
+ sym = accessMethod(sym, pos, site, names.init, true, argtypes, typeargtypes);
+ env.info.pendingResolutionPhase = currentResolutionContext.step;
+ }
+ return sym;
}
- return sym;
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
+ });
}
/** This method scans all the constructor symbol in a given class scope -
@@ -2281,392 +2283,7 @@ public class Resolve {
return bestSoFar;
}
- /**
- * Resolution of member references is typically done as a single
- * overload resolution step, where the argument types A are inferred from
- * the target functional descriptor.
- *
- * If the member reference is a method reference with a type qualifier,
- * a two-step lookup process is performed. The first step uses the
- * expected argument list A, while the second step discards the first
- * type from A (which is treated as a receiver type).
- *
- * There are two cases in which inference is performed: (i) if the member
- * reference is a constructor reference and the qualifier type is raw - in
- * which case diamond inference is used to infer a parameterization for the
- * type qualifier; (ii) if the member reference is an unbound reference
- * where the type qualifier is raw - in that case, during the unbound lookup
- * the receiver argument type is used to infer an instantiation for the raw
- * qualifier type.
- *
- * When a multi-step resolution process is exploited, it is an error
- * if two candidates are found (ambiguity).
- *
- * This routine returns a pair (T,S), where S is the member reference symbol,
- * and T is the type of the class in which S is defined. This is necessary as
- * the type T might be dynamically inferred (i.e. if constructor reference
- * has a raw qualifier).
- */
- Pair resolveMemberReference(DiagnosticPosition pos,
- Env env,
- JCMemberReference referenceTree,
- Type site,
- Name name, List argtypes,
- List typeargtypes,
- boolean boxingAllowed) {
- //step 1 - bound lookup
- ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
- new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, boxingAllowed) :
- new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
- Env boundEnv = env.dup(env.tree, env.info.dup());
- Symbol boundSym = findMemberReference(boundEnv, boundLookupHelper);
- //step 2 - unbound lookup
- ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
- Env unboundEnv = env.dup(env.tree, env.info.dup());
- Symbol unboundSym = findMemberReference(unboundEnv, unboundLookupHelper);
-
- //merge results
- Pair res;
- if (unboundSym.kind != MTH) {
- res = new Pair(boundSym, boundLookupHelper);
- env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
- } else if (boundSym.kind == MTH) {
- res = new Pair(ambiguityError(boundSym, unboundSym), boundLookupHelper);
- env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
- } else {
- res = new Pair(unboundSym, unboundLookupHelper);
- env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
- }
-
- return res;
- }
-
- /**
- * Helper for defining custom method-like lookup logic; a lookup helper
- * provides hooks for (i) the actual lookup logic and (ii) accessing the
- * lookup result (this step might result in compiler diagnostics to be generated)
- */
- abstract class LookupHelper {
-
- /** name of the symbol to lookup */
- Name name;
-
- /** location in which the lookup takes place */
- Type site;
-
- /** actual types used during the lookup */
- List argtypes;
-
- /** type arguments used during the lookup */
- List typeargtypes;
-
- LookupHelper(Name name, Type site, List argtypes, List typeargtypes) {
- this.name = name;
- this.site = site;
- this.argtypes = argtypes;
- this.typeargtypes = typeargtypes;
- }
-
- /**
- * Search for a symbol under a given overload resolution phase - this method
- * is usually called several times, once per each overload resolution phase
- */
- abstract Symbol lookup(Env env, MethodResolutionPhase phase);
-
- /**
- * Validate the result of the lookup
- */
- abstract Symbol access(Env env, Symbol symbol);
- }
-
- /**
- * Helper class for member reference lookup. A reference lookup helper
- * defines the basic logic for member reference lookup; a method gives
- * access to an 'unbound' helper used to perform an unbound member
- * reference lookup.
- */
- abstract class ReferenceLookupHelper extends LookupHelper {
-
- /** The member reference tree */
- JCMemberReference referenceTree;
-
- /** Max overload resolution phase handled by this helper */
- MethodResolutionPhase maxPhase;
-
- ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List argtypes, List typeargtypes, boolean boxingAllowed) {
- super(name, site, argtypes, typeargtypes);
- this.referenceTree = referenceTree;
- this.maxPhase = boxingAllowed ? VARARITY : BASIC;
- }
-
- /**
- * Returns an unbound version of this lookup helper. By default, this
- * method returns an dummy lookup helper.
- */
- ReferenceLookupHelper unboundLookup() {
- //dummy loopkup helper that always return 'methodNotFound'
- return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase.isBoxingRequired()) {
- @Override
- ReferenceLookupHelper unboundLookup() {
- return this;
- }
- @Override
- Symbol lookupReference(Env env, MethodResolutionPhase phase) {
- return methodNotFound;
- }
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- Assert.error();
- return null;
- }
- };
- }
-
- /**
- * Get the kind of the member reference
- */
- abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
-
- @Override
- Symbol lookup(Env env, MethodResolutionPhase phase) {
- return (env.info.pendingResolutionPhase.ordinal() > maxPhase.ordinal()) ?
- methodNotFound : lookupReference(env, phase);
- }
-
- abstract Symbol lookupReference(Env env, MethodResolutionPhase phase);
-
- Symbol access(Env env, Symbol sym) {
- if (sym.kind >= AMBIGUOUS) {
- MethodResolutionPhase errPhase = currentResolutionContext.firstErroneousResolutionPhase();
- if (errPhase.ordinal() > maxPhase.ordinal()) {
- errPhase = maxPhase;
- }
- env.info.pendingResolutionPhase = errPhase;
- sym = currentResolutionContext.resolutionCache.get(errPhase);
- }
- return sym;
- }
- }
-
- /**
- * Helper class for method reference lookup. The lookup logic is based
- * upon Resolve.findMethod; in certain cases, this helper class has a
- * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
- * In such cases, non-static lookup results are thrown away.
- */
- class MethodReferenceLookupHelper extends ReferenceLookupHelper {
-
- MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List argtypes, List typeargtypes, boolean boxingAllowed) {
- super(referenceTree, name, site, argtypes, typeargtypes, boxingAllowed);
- }
-
- protected Symbol lookupReferenceInternal(Env env, MethodResolutionPhase phase) {
- return findMethod(env, site, name, argtypes, typeargtypes,
- phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
- }
-
- protected Symbol adjustLookupResult(Env env, Symbol sym) {
- return !TreeInfo.isStaticSelector(referenceTree.expr, names) ||
- sym.kind != MTH ||
- sym.isStatic() ? sym : new StaticError(sym);
- }
-
- @Override
- final Symbol lookupReference(Env env, MethodResolutionPhase phase) {
- return adjustLookupResult(env, lookupReferenceInternal(env, phase));
- }
-
- @Override
- ReferenceLookupHelper unboundLookup() {
- if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
- argtypes.nonEmpty() &&
- types.isSubtypeUnchecked(argtypes.head, site)) {
- return new UnboundMethodReferenceLookupHelper(referenceTree, name,
- site, argtypes, typeargtypes, maxPhase.isBoxingRequired());
- } else {
- return super.unboundLookup();
- }
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- if (sym.isStatic()) {
- return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
- ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
- } else {
- Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
- return selName != null && selName == names._super ?
- ReferenceKind.SUPER :
- ReferenceKind.BOUND;
- }
- }
- }
-
- /**
- * Helper class for unbound method reference lookup. Essentially the same
- * as the basic method reference lookup helper; main difference is that static
- * lookup results are thrown away. If qualifier type is raw, an attempt to
- * infer a parameterized type is made using the first actual argument (that
- * would otherwise be ignored during the lookup).
- */
- class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
-
- UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
- List argtypes, List typeargtypes, boolean boxingAllowed) {
- super(referenceTree, name,
- site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site,
- argtypes.tail, typeargtypes, boxingAllowed);
- }
-
- @Override
- protected Symbol adjustLookupResult(Env env, Symbol sym) {
- return sym.kind != MTH || !sym.isStatic() ? sym : new StaticError(sym);
- }
-
- @Override
- ReferenceLookupHelper unboundLookup() {
- return this;
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- return ReferenceKind.UNBOUND;
- }
- }
-
- /**
- * Helper class for constructor reference lookup. The lookup logic is based
- * upon either Resolve.findMethod or Resolve.findDiamond - depending on
- * whether the constructor reference needs diamond inference (this is the case
- * if the qualifier type is raw). A special erroneous symbol is returned
- * if the lookup returns the constructor of an inner class and there's no
- * enclosing instance in scope.
- */
- class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
-
- boolean needsInference;
-
- ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List argtypes,
- List typeargtypes, boolean boxingAllowed) {
- super(referenceTree, names.init, site, argtypes, typeargtypes, boxingAllowed);
- if (site.isRaw()) {
- this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
- needsInference = true;
- }
- }
-
- @Override
- protected Symbol lookupReference(Env env, MethodResolutionPhase phase) {
- Symbol sym = needsInference ?
- findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
- findMethod(env, site, name, argtypes, typeargtypes,
- phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
- return sym.kind != MTH ||
- site.getEnclosingType().hasTag(NONE) ||
- hasEnclosingInstance(env, site) ?
- sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
- @Override
- JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) {
- return diags.create(dkind, log.currentSource(), pos,
- "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
- }
- };
- }
-
- @Override
- ReferenceKind referenceKind(Symbol sym) {
- return site.getEnclosingType().hasTag(NONE) ?
- ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
- }
- }
-
- /**
- * Resolution step for member reference. This generalizes a standard
- * method/constructor lookup - on each overload resolution step, a
- * lookup helper class is used to perform the reference lookup; at the end
- * of the lookup, the helper is used to validate the results.
- */
- Symbol findMemberReference(Env env, LookupHelper lookupHelper) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= ERRONEOUS) {
- currentResolutionContext.step = env.info.pendingResolutionPhase = steps.head;
- sym = lookupHelper.lookup(env, steps.head);
- currentResolutionContext.resolutionCache.put(steps.head, sym);
- steps = steps.tail;
- }
- return lookupHelper.access(env, sym);
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
- }
-
- /** Resolve constructor.
- * @param pos The position to use for error reporting.
- * @param env The environment current at the constructor invocation.
- * @param site The type of class for which a constructor is searched.
- * @param argtypes The types of the constructor invocation's value
- * arguments.
- * @param typeargtypes The types of the constructor invocation's type
- * arguments.
- * @param allowBoxing Allow boxing and varargs conversions.
- * @param useVarargs Box trailing arguments into an array for varargs.
- */
- Symbol resolveConstructor(DiagnosticPosition pos, Env env,
- Type site, List argtypes,
- List typeargtypes,
- boolean allowBoxing,
- boolean useVarargs) {
- MethodResolutionContext prevResolutionContext = currentResolutionContext;
- try {
- currentResolutionContext = new MethodResolutionContext();
- return findConstructor(pos, env, site, argtypes, typeargtypes, allowBoxing, useVarargs);
- }
- finally {
- currentResolutionContext = prevResolutionContext;
- }
- }
-
- Symbol findConstructor(DiagnosticPosition pos, Env env,
- Type site, List argtypes,
- List typeargtypes,
- boolean allowBoxing,
- boolean useVarargs) {
- Symbol sym = findMethod(env, site,
- names.init, argtypes,
- typeargtypes, allowBoxing,
- useVarargs, false);
- chk.checkDeprecated(pos, env.info.scope.owner, sym);
- return sym;
- }
-
- /** Resolve a constructor, throw a fatal error if not found.
- * @param pos The position to use for error reporting.
- * @param env The environment current at the method invocation.
- * @param site The type to be constructed.
- * @param argtypes The types of the invocation's value arguments.
- * @param typeargtypes The types of the invocation's type arguments.
- */
- public MethodSymbol resolveInternalConstructor(DiagnosticPosition pos, Env env,
- Type site,
- List argtypes,
- List typeargtypes) {
- MethodResolutionContext resolveContext = new MethodResolutionContext();
- resolveContext.internalResolution = true;
- Symbol sym = resolveConstructor(resolveContext, pos, env, site, argtypes, typeargtypes);
- if (sym.kind == MTH) return (MethodSymbol)sym;
- else throw new FatalError(
- diags.fragment("fatal.err.cant.locate.ctor", site));
- }
/** Resolve operator.
* @param pos The position to use for error reporting.
@@ -2718,6 +2335,350 @@ public class Resolve {
return resolveOperator(pos, optag, env, List.of(left, right));
}
+ /**
+ * Resolution of member references is typically done as a single
+ * overload resolution step, where the argument types A are inferred from
+ * the target functional descriptor.
+ *
+ * If the member reference is a method reference with a type qualifier,
+ * a two-step lookup process is performed. The first step uses the
+ * expected argument list A, while the second step discards the first
+ * type from A (which is treated as a receiver type).
+ *
+ * There are two cases in which inference is performed: (i) if the member
+ * reference is a constructor reference and the qualifier type is raw - in
+ * which case diamond inference is used to infer a parameterization for the
+ * type qualifier; (ii) if the member reference is an unbound reference
+ * where the type qualifier is raw - in that case, during the unbound lookup
+ * the receiver argument type is used to infer an instantiation for the raw
+ * qualifier type.
+ *
+ * When a multi-step resolution process is exploited, it is an error
+ * if two candidates are found (ambiguity).
+ *
+ * This routine returns a pair (T,S), where S is the member reference symbol,
+ * and T is the type of the class in which S is defined. This is necessary as
+ * the type T might be dynamically inferred (i.e. if constructor reference
+ * has a raw qualifier).
+ */
+ Pair resolveMemberReference(DiagnosticPosition pos,
+ Env env,
+ JCMemberReference referenceTree,
+ Type site,
+ Name name, List argtypes,
+ List typeargtypes,
+ boolean boxingAllowed) {
+ MethodResolutionPhase maxPhase = boxingAllowed ? VARARITY : BASIC;
+ //step 1 - bound lookup
+ ReferenceLookupHelper boundLookupHelper = name.equals(names.init) ?
+ new ConstructorReferenceLookupHelper(referenceTree, site, argtypes, typeargtypes, maxPhase) :
+ new MethodReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ Env boundEnv = env.dup(env.tree, env.info.dup());
+ Symbol boundSym = lookupMethod(boundEnv, env.tree.pos(), site.tsym, boundLookupHelper);
+
+ //step 2 - unbound lookup
+ ReferenceLookupHelper unboundLookupHelper = boundLookupHelper.unboundLookup();
+ Env unboundEnv = env.dup(env.tree, env.info.dup());
+ Symbol unboundSym = lookupMethod(unboundEnv, env.tree.pos(), site.tsym, unboundLookupHelper);
+
+ //merge results
+ Pair res;
+ if (unboundSym.kind != MTH) {
+ res = new Pair(boundSym, boundLookupHelper);
+ env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
+ } else if (boundSym.kind == MTH) {
+ res = new Pair(ambiguityError(boundSym, unboundSym), boundLookupHelper);
+ env.info.pendingResolutionPhase = boundEnv.info.pendingResolutionPhase;
+ } else {
+ res = new Pair(unboundSym, unboundLookupHelper);
+ env.info.pendingResolutionPhase = unboundEnv.info.pendingResolutionPhase;
+ }
+
+ return res;
+ }
+
+ /**
+ * Helper for defining custom method-like lookup logic; a lookup helper
+ * provides hooks for (i) the actual lookup logic and (ii) accessing the
+ * lookup result (this step might result in compiler diagnostics to be generated)
+ */
+ abstract class LookupHelper {
+
+ /** name of the symbol to lookup */
+ Name name;
+
+ /** location in which the lookup takes place */
+ Type site;
+
+ /** actual types used during the lookup */
+ List argtypes;
+
+ /** type arguments used during the lookup */
+ List typeargtypes;
+
+ /** Max overload resolution phase handled by this helper */
+ MethodResolutionPhase maxPhase;
+
+ LookupHelper(Name name, Type site, List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) {
+ this.name = name;
+ this.site = site;
+ this.argtypes = argtypes;
+ this.typeargtypes = typeargtypes;
+ this.maxPhase = maxPhase;
+ }
+
+ /**
+ * Should lookup stop at given phase with given result
+ */
+ protected boolean shouldStop(Symbol sym, MethodResolutionPhase phase) {
+ return phase.ordinal() > maxPhase.ordinal() ||
+ sym.kind < ERRONEOUS || sym.kind == AMBIGUOUS;
+ }
+
+ /**
+ * Search for a symbol under a given overload resolution phase - this method
+ * is usually called several times, once per each overload resolution phase
+ */
+ abstract Symbol lookup(Env env, MethodResolutionPhase phase);
+
+ /**
+ * Validate the result of the lookup
+ */
+ abstract Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym);
+ }
+
+ abstract class BasicLookupHelper extends LookupHelper {
+
+ BasicLookupHelper(Name name, Type site, List argtypes, List typeargtypes) {
+ super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ }
+
+ @Override
+ Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ if (sym.kind >= AMBIGUOUS) {
+ //if nothing is found return the 'first' error
+ sym = accessMethod(sym, pos, location, site, name, true, argtypes, typeargtypes);
+ }
+ return sym;
+ }
+ }
+
+ /**
+ * Helper class for member reference lookup. A reference lookup helper
+ * defines the basic logic for member reference lookup; a method gives
+ * access to an 'unbound' helper used to perform an unbound member
+ * reference lookup.
+ */
+ abstract class ReferenceLookupHelper extends LookupHelper {
+
+ /** The member reference tree */
+ JCMemberReference referenceTree;
+
+ ReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) {
+ super(name, site, argtypes, typeargtypes, maxPhase);
+ this.referenceTree = referenceTree;
+
+ }
+
+ /**
+ * Returns an unbound version of this lookup helper. By default, this
+ * method returns an dummy lookup helper.
+ */
+ ReferenceLookupHelper unboundLookup() {
+ //dummy loopkup helper that always return 'methodNotFound'
+ return new ReferenceLookupHelper(referenceTree, name, site, argtypes, typeargtypes, maxPhase) {
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ return this;
+ }
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return methodNotFound;
+ }
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ Assert.error();
+ return null;
+ }
+ };
+ }
+
+ /**
+ * Get the kind of the member reference
+ */
+ abstract JCMemberReference.ReferenceKind referenceKind(Symbol sym);
+
+ Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ //skip error reporting
+ return sym;
+ }
+ }
+
+ /**
+ * Helper class for method reference lookup. The lookup logic is based
+ * upon Resolve.findMethod; in certain cases, this helper class has a
+ * corresponding unbound helper class (see UnboundMethodReferenceLookupHelper).
+ * In such cases, non-static lookup results are thrown away.
+ */
+ class MethodReferenceLookupHelper extends ReferenceLookupHelper {
+
+ MethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, name, site, argtypes, typeargtypes, maxPhase);
+ }
+
+ protected Symbol lookupReferenceInternal(Env env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
+ }
+
+ protected Symbol adjustLookupResult(Env env, Symbol sym) {
+ return !TreeInfo.isStaticSelector(referenceTree.expr, names) ||
+ sym.kind != MTH ||
+ sym.isStatic() ? sym : new StaticError(sym);
+ }
+
+ @Override
+ final Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return adjustLookupResult(env, lookupReferenceInternal(env, phase));
+ }
+
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ if (TreeInfo.isStaticSelector(referenceTree.expr, names) &&
+ argtypes.nonEmpty() &&
+ types.isSubtypeUnchecked(argtypes.head, site)) {
+ return new UnboundMethodReferenceLookupHelper(referenceTree, name,
+ site, argtypes, typeargtypes, maxPhase);
+ } else {
+ return super.unboundLookup();
+ }
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ if (sym.isStatic()) {
+ return TreeInfo.isStaticSelector(referenceTree.expr, names) ?
+ ReferenceKind.STATIC : ReferenceKind.STATIC_EVAL;
+ } else {
+ Name selName = TreeInfo.name(referenceTree.getQualifierExpression());
+ return selName != null && selName == names._super ?
+ ReferenceKind.SUPER :
+ ReferenceKind.BOUND;
+ }
+ }
+ }
+
+ /**
+ * Helper class for unbound method reference lookup. Essentially the same
+ * as the basic method reference lookup helper; main difference is that static
+ * lookup results are thrown away. If qualifier type is raw, an attempt to
+ * infer a parameterized type is made using the first actual argument (that
+ * would otherwise be ignored during the lookup).
+ */
+ class UnboundMethodReferenceLookupHelper extends MethodReferenceLookupHelper {
+
+ UnboundMethodReferenceLookupHelper(JCMemberReference referenceTree, Name name, Type site,
+ List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, name,
+ site.isRaw() ? types.asSuper(argtypes.head, site.tsym) : site,
+ argtypes.tail, typeargtypes, maxPhase);
+ }
+
+ @Override
+ protected Symbol adjustLookupResult(Env env, Symbol sym) {
+ return sym.kind != MTH || !sym.isStatic() ? sym : new StaticError(sym);
+ }
+
+ @Override
+ ReferenceLookupHelper unboundLookup() {
+ return this;
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return ReferenceKind.UNBOUND;
+ }
+ }
+
+ /**
+ * Helper class for constructor reference lookup. The lookup logic is based
+ * upon either Resolve.findMethod or Resolve.findDiamond - depending on
+ * whether the constructor reference needs diamond inference (this is the case
+ * if the qualifier type is raw). A special erroneous symbol is returned
+ * if the lookup returns the constructor of an inner class and there's no
+ * enclosing instance in scope.
+ */
+ class ConstructorReferenceLookupHelper extends ReferenceLookupHelper {
+
+ boolean needsInference;
+
+ ConstructorReferenceLookupHelper(JCMemberReference referenceTree, Type site, List argtypes,
+ List typeargtypes, MethodResolutionPhase maxPhase) {
+ super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
+ if (site.isRaw()) {
+ this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym);
+ needsInference = true;
+ }
+ }
+
+ @Override
+ protected Symbol lookup(Env env, MethodResolutionPhase phase) {
+ Symbol sym = needsInference ?
+ findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) :
+ findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(), phase.isVarargsRequired(), syms.operatorNames.contains(name));
+ return sym.kind != MTH ||
+ site.getEnclosingType().hasTag(NONE) ||
+ hasEnclosingInstance(env, site) ?
+ sym : new InvalidSymbolError(Kinds.MISSING_ENCL, sym, null) {
+ @Override
+ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) {
+ return diags.create(dkind, log.currentSource(), pos,
+ "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType());
+ }
+ };
+ }
+
+ @Override
+ ReferenceKind referenceKind(Symbol sym) {
+ return site.getEnclosingType().hasTag(NONE) ?
+ ReferenceKind.TOPLEVEL : ReferenceKind.IMPLICIT_INNER;
+ }
+ }
+
+ /**
+ * Main overload resolution routine. On each overload resolution step, a
+ * lookup helper class is used to perform the method/constructor lookup;
+ * at the end of the lookup, the helper is used to validate the results
+ * (this last step might trigger overload resolution diagnostics).
+ */
+ Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol location, LookupHelper lookupHelper) {
+ return lookupMethod(env, pos, location, new MethodResolutionContext(), lookupHelper);
+ }
+
+ Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol location,
+ MethodResolutionContext resolveContext, LookupHelper lookupHelper) {
+ MethodResolutionContext prevResolutionContext = currentResolutionContext;
+ try {
+ Symbol bestSoFar = methodNotFound;
+ currentResolutionContext = resolveContext;
+ for (MethodResolutionPhase phase : methodResolutionSteps) {
+ if (!phase.isApplicable(boxingEnabled, varargsEnabled) ||
+ lookupHelper.shouldStop(bestSoFar, phase)) break;
+ MethodResolutionPhase prevPhase = currentResolutionContext.step;
+ Symbol prevBest = bestSoFar;
+ currentResolutionContext.step = phase;
+ bestSoFar = phase.mergeResults(bestSoFar, lookupHelper.lookup(env, phase));
+ env.info.pendingResolutionPhase = (prevBest == bestSoFar) ? prevPhase : phase;
+ }
+ return lookupHelper.access(env, pos, location, bestSoFar);
+ } finally {
+ currentResolutionContext = prevResolutionContext;
+ }
+ }
+
/**
* Resolve `c.name' where name == this or name == super.
* @param pos The position to use for error reporting.
@@ -2744,9 +2705,47 @@ public class Resolve {
if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true;
env1 = env1.outer;
}
+ if (allowDefaultMethods && c.isInterface() &&
+ name == names._super && !isStatic(env) &&
+ types.isDirectSuperInterface(c.type, env.enclClass.sym)) {
+ //this might be a default super call if one of the superinterfaces is 'c'
+ for (Type t : pruneInterfaces(env.enclClass.type)) {
+ if (t.tsym == c) {
+ env.info.defaultSuperCallSite = t;
+ return new VarSymbol(0, names._super,
+ types.asSuper(env.enclClass.type, c), env.enclClass.sym);
+ }
+ }
+ //find a direct superinterface that is a subtype of 'c'
+ for (Type i : types.interfaces(env.enclClass.type)) {
+ if (i.tsym.isSubClass(c, types) && i.tsym != c) {
+ log.error(pos, "illegal.default.super.call", c,
+ diags.fragment("redundant.supertype", c, i));
+ return syms.errSymbol;
+ }
+ }
+ Assert.error();
+ }
log.error(pos, "not.encl.class", c);
return syms.errSymbol;
}
+ //where
+ private List pruneInterfaces(Type t) {
+ ListBuffer result = ListBuffer.lb();
+ for (Type t1 : types.interfaces(t)) {
+ boolean shouldAdd = true;
+ for (Type t2 : types.interfaces(t)) {
+ if (t1 != t2 && types.isSubtypeNoCapture(t2, t1)) {
+ shouldAdd = false;
+ }
+ }
+ if (shouldAdd) {
+ result.append(t1);
+ }
+ }
+ return result.toList();
+ }
+
/**
* Resolve `c.this' for an enclosing class c that contains the
@@ -3114,20 +3113,14 @@ public class Resolve {
return types.createErrorType(name, location, syms.errSymbol.type).tsym;
}
- protected boolean shouldReport(Candidate c) {
- MethodResolutionPhase errPhase = resolveContext.firstErroneousResolutionPhase();
- return !c.isApplicable() &&
- c.step == errPhase;
- }
-
private Candidate errCandidate() {
+ Candidate bestSoFar = null;
for (Candidate c : resolveContext.candidates) {
- if (shouldReport(c)) {
- return c;
- }
+ if (c.isApplicable()) continue;
+ bestSoFar = c;
}
- Assert.error();
- return null;
+ Assert.checkNonNull(bestSoFar);
+ return bestSoFar;
}
}
@@ -3156,7 +3149,7 @@ public class Resolve {
pos,
"cant.apply.symbols",
name == names.init ? KindName.CONSTRUCTOR : absentKind(kind),
- getName(),
+ name == names.init ? site.tsym.name : name,
argtypes);
return new JCDiagnostic.MultilineDiagnostic(err, candidateDetails(site));
} else {
@@ -3167,24 +3160,17 @@ public class Resolve {
//where
List candidateDetails(Type site) {
- List details = List.nil();
+ Map details = new LinkedHashMap();
for (Candidate c : resolveContext.candidates) {
- if (!shouldReport(c)) continue;
+ if (c.isApplicable()) continue;
JCDiagnostic detailDiag = diags.fragment("inapplicable.method",
Kinds.kindName(c.sym),
c.sym.location(site, types),
c.sym.asMemberOf(site, types),
c.details);
- details = details.prepend(detailDiag);
+ details.put(c.sym, detailDiag);
}
- return details.reverse();
- }
-
- private Name getName() {
- Symbol sym = resolveContext.candidates.head.sym;
- return sym.name == names.init ?
- sym.owner.name :
- sym.name;
+ return List.from(details.values());
}
}
@@ -3322,7 +3308,21 @@ public class Resolve {
enum MethodResolutionPhase {
BASIC(false, false),
BOX(true, false),
- VARARITY(true, true);
+ VARARITY(true, true) {
+ @Override
+ public Symbol mergeResults(Symbol bestSoFar, Symbol sym) {
+ switch (sym.kind) {
+ case WRONG_MTH:
+ return (bestSoFar.kind == WRONG_MTH || bestSoFar.kind == WRONG_MTHS) ?
+ bestSoFar :
+ sym;
+ case ABSENT_MTH:
+ return bestSoFar;
+ default:
+ return sym;
+ }
+ }
+ };
boolean isBoxingRequired;
boolean isVarargsRequired;
@@ -3344,6 +3344,10 @@ public class Resolve {
return (varargsEnabled || !isVarargsRequired) &&
(boxingEnabled || !isBoxingRequired);
}
+
+ public Symbol mergeResults(Symbol prev, Symbol sym) {
+ return sym;
+ }
}
final List methodResolutionSteps = List.of(BASIC, BOX, VARARITY);
@@ -3359,29 +3363,11 @@ public class Resolve {
private List candidates = List.nil();
- private Map resolutionCache =
- new EnumMap(MethodResolutionPhase.class);
-
MethodResolutionPhase step = null;
private boolean internalResolution = false;
private DeferredAttr.AttrMode attrMode = DeferredAttr.AttrMode.SPECULATIVE;
- private MethodResolutionPhase firstErroneousResolutionPhase() {
- MethodResolutionPhase bestSoFar = BASIC;
- Symbol sym = methodNotFound;
- List steps = methodResolutionSteps;
- while (steps.nonEmpty() &&
- steps.head.isApplicable(boxingEnabled, varargsEnabled) &&
- sym.kind >= WRONG_MTHS) {
- sym = resolutionCache.get(steps.head);
- if (sym.kind == ABSENT_MTH) break; //ignore spurious empty entries
- bestSoFar = steps.head;
- steps = steps.tail;
- }
- return bestSoFar;
- }
-
void addInapplicableCandidate(Symbol sym, JCDiagnostic details) {
Candidate c = new Candidate(currentResolutionContext.step, sym, details, null);
candidates = candidates.append(c);
@@ -3392,16 +3378,6 @@ public class Resolve {
candidates = candidates.append(c);
}
- Candidate getCandidate(Symbol sym, MethodResolutionPhase phase) {
- for (Candidate c : currentResolutionContext.candidates) {
- if (c.step == phase &&
- c.sym.baseSymbol() == sym.baseSymbol()) {
- return c;
- }
- }
- return null;
- }
-
/**
* This class represents an overload resolution candidate. There are two
* kinds of candidates: applicable methods and inapplicable methods;
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java
index 85a4df6477e..3184c09d69d 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java
@@ -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);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
index f2b8ab56d16..1f86b01f1ea 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
@@ -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
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
index bf9b0d67509..2353391c71e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java
@@ -1540,7 +1540,7 @@ public class ClassWriter extends ClassFile {
List interfaces = types.interfaces(c.type);
List 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;
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java
index 1580f293215..d692c899f79 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java
@@ -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);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
index 20391d322b1..f6432b864a0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java
@@ -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 targetKey =
new Context.Key();
diff --git a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
index f21a9ca8358..64d9d67e60f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java
@@ -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));
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
index 7e71133db60..5f491e0e7e0 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -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.of(stm), key)));
+ }
+
/** CatchClause = CATCH "(" FormalParameter ")" Block
*/
protected JCCatch catchClause() {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
index e8dd77889cc..a9b3d1a2680 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties
@@ -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
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
index e29ae005402..bb4eee23cc3 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java
@@ -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
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java b/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java
index 4994fe66634..e9b5b23c1fb 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java
@@ -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;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
index 67f5e4cc40a..e26070180d5 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java
@@ -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 subPackages = new ListBuffer();
ListBuffer excludedPackages = new ListBuffer();
- 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;
diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
index ba6142c015e..861fea44a36 100644
--- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
+++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
@@ -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}.
diff --git a/langtools/test/tools/javac/7132880/T7132880.out b/langtools/test/tools/javac/7132880/T7132880.out
index caeaaa2b261..e88309d1230 100644
--- a/langtools/test/tools/javac/7132880/T7132880.out
+++ b/langtools/test/tools/javac/7132880/T7132880.out
@@ -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
diff --git a/langtools/test/tools/javac/8002286/T8002286.java b/langtools/test/tools/javac/8002286/T8002286.java
new file mode 100644
index 00000000000..f4a45791080
--- /dev/null
+++ b/langtools/test/tools/javac/8002286/T8002286.java
@@ -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 { }
+}
diff --git a/langtools/test/tools/javac/8002286/T8002286.out b/langtools/test/tools/javac/8002286/T8002286.out
new file mode 100644
index 00000000000..dd533236d43
--- /dev/null
+++ b/langtools/test/tools/javac/8002286/T8002286.out
@@ -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
diff --git a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
index 9cf36e89529..196e73992a7 100644
--- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
+++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out
@@ -1,4 +1,4 @@
-T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605))}
-T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (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, m(T6799605), (compiler.misc.infer.arg.length.mismatch: T))}
-T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (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, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:17:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.inferred.do.not.conform.to.upper.bounds: compiler.misc.type.captureof: 1, ?, T6799605)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:18:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (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, m(T6799605,T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T))}
+T6799605.java:19:9: compiler.err.cant.apply.symbols: kindname.method, m, T6799605,T6799605,T6799605,{(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.method, T6799605, m(T6799605,T6799605,T6799605), (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
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java
new file mode 100644
index 00000000000..802f631f5b1
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java
@@ -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 diagnostics =
+ new DiagnosticCollector();
+ boolean ok = Helper.compileCode(diagnostics,files);
+ if (!shouldCompile && !ok) {
+ checkErrorKeys(className, diagnostics);
+ }
+ return (shouldCompile == ok);
+ }
+
+ private void checkErrorKeys (
+ String className, DiagnosticCollector 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();
+ }
+}
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java
new file mode 100644
index 00000000000..ba4e1652a03
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java
@@ -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 diagnostics =
+ new DiagnosticCollector();
+ ok = compileCode(clName.toString(), contents, diagnostics);
+
+ String errorKey1 = "compiler.note.deprecated.filename";
+ String errorKey2 = "compiler.note.deprecated.recompile";
+ List> 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]);
+ }
+ }
+}
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java
new file mode 100644
index 00000000000..dbe38afd768
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java
@@ -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 diagnostics =
+ new DiagnosticCollector();
+ 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]);
+ }
+ }
+}
+
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java
new file mode 100644
index 00000000000..653c2f5ce0a
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java
@@ -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 /**/ /*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 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 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;
+ }
+ }
+}
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java
new file mode 100644
index 00000000000..b0b019f065d
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java
@@ -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 diagnostics =
+ new DiagnosticCollector();
+ 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]);
+ }
+ }
+}
+
diff --git a/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java
new file mode 100644
index 00000000000..99c5c5eb0ce
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java
@@ -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 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 diagnostics =
+ new DiagnosticCollector();
+ 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 setRetentionValMatrix() {
+ HashMap 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 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();
+ }
+}
+
diff --git a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java
index c397f019374..f08d850d035 100644
--- a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java
+++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java
@@ -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++) {
diff --git a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java
new file mode 100644
index 00000000000..746b296edfc
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java
@@ -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 {}
diff --git a/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java
new file mode 100644
index 00000000000..d960f8f9049
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java
@@ -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) { }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg01.java b/langtools/test/tools/javac/defaultMethods/Neg01.java
new file mode 100644
index 00000000000..6a3c19fdfef
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.java
@@ -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; }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg01.out b/langtools/test/tools/javac/defaultMethods/Neg01.out
new file mode 100644
index 00000000000..ca44ab6bec9
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg01.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg02.java b/langtools/test/tools/javac/defaultMethods/Neg02.java
new file mode 100644
index 00000000000..0fa686557de
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.java
@@ -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) { }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg02.out b/langtools/test/tools/javac/defaultMethods/Neg02.out
new file mode 100644
index 00000000000..3fb05ab2adc
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg02.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg03.java b/langtools/test/tools/javac/defaultMethods/Neg03.java
new file mode 100644
index 00000000000..94ea0016b43
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.java
@@ -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) { }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg03.out b/langtools/test/tools/javac/defaultMethods/Neg03.out
new file mode 100644
index 00000000000..338eb6ca7ab
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg03.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg04.java b/langtools/test/tools/javac/defaultMethods/Neg04.java
new file mode 100644
index 00000000000..21aac883702
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.java
@@ -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; }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg04.out b/langtools/test/tools/javac/defaultMethods/Neg04.out
new file mode 100644
index 00000000000..a6fc1ad0b15
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg04.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg05.java b/langtools/test/tools/javac/defaultMethods/Neg05.java
new file mode 100644
index 00000000000..c34ff3ebde6
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.java
@@ -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; }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg05.out b/langtools/test/tools/javac/defaultMethods/Neg05.out
new file mode 100644
index 00000000000..17a0c4505e9
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg05.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg06.java b/langtools/test/tools/javac/defaultMethods/Neg06.java
new file mode 100644
index 00000000000..52c88b97551
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.java
@@ -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 ""; }
+ }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg06.out b/langtools/test/tools/javac/defaultMethods/Neg06.out
new file mode 100644
index 00000000000..53c39d01254
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg06.out
@@ -0,0 +1,2 @@
+Neg06.java:10:37: compiler.err.missing.ret.stmt
+1 error
diff --git a/langtools/test/tools/javac/defaultMethods/Neg07.java b/langtools/test/tools/javac/defaultMethods/Neg07.java
new file mode 100644
index 00000000000..a5d0ab70fbe
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.java
@@ -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
+ }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg07.out b/langtools/test/tools/javac/defaultMethods/Neg07.out
new file mode 100644
index 00000000000..97d2ac84962
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg07.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg08.java b/langtools/test/tools/javac/defaultMethods/Neg08.java
new file mode 100644
index 00000000000..918dc2df172
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.java
@@ -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
+ }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg08.out b/langtools/test/tools/javac/defaultMethods/Neg08.out
new file mode 100644
index 00000000000..38f1c9bf9e3
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg08.out
@@ -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
diff --git a/langtools/test/tools/javac/defaultMethods/Neg09.java b/langtools/test/tools/javac/defaultMethods/Neg09.java
new file mode 100644
index 00000000000..9f662e5e42e
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.java
@@ -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 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
+ }
+}
diff --git a/langtools/test/tools/javac/defaultMethods/Neg09.out b/langtools/test/tools/javac/defaultMethods/Neg09.out
new file mode 100644
index 00000000000..2f13e2f4758
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg09.out
@@ -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
+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
+- compiler.err.warnings.and.werror
+1 error
+2 warnings
diff --git a/langtools/test/tools/javac/defaultMethods/Neg10.java b/langtools/test/tools/javac/defaultMethods/Neg10.java
new file mode 100644
index 00000000000..ce904dd599b
--- /dev/null
+++ b/langtools/test/tools/javac/defaultMethods/Neg10.java
@@ -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 {
+ default void m() throws X { }
+ }
+
+ static class C1 {
+ public void m() throws Exception { } //unchecked (throws) override
+ }
+
+ static class C2 extends C1 implements I