# HG changeset patch # User lana # Date 1352501242 28800 # Node ID 0e685b019743b5c3618530d1114b2151333885b3 # Parent 1833592bde35456cf08e9a3f97973a6dce2397ef# Parent f083d81c2b461421fe9c9cf5281252714dd93fbf Merge diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties --- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/resources/standard.properties Fri Nov 09 14:47:22 2012 -0800 @@ -41,32 +41,21 @@ 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_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.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_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.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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/resources/doclets.properties Fri Nov 09 14:47:22 2012 -0800 @@ -21,10 +21,8 @@ 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.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_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.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.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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java Fri Nov 09 14:47:22 2012 -0800 @@ -555,7 +555,7 @@ * * @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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/code/Flags.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Flags.java Fri Nov 09 14:47:22 2012 -0800 @@ -67,7 +67,6 @@ if ((mask&NATIVE) != 0) flags.add(Flag.NATIVE); if ((mask&INTERFACE) != 0) flags.add(Flag.INTERFACE); if ((mask&ABSTRACT) != 0) flags.add(Flag.ABSTRACT); - if ((mask&DEFAULT) != 0) flags.add(Flag.DEFAULT); if ((mask&STRICTFP) != 0) flags.add(Flag.STRICTFP); if ((mask&BRIDGE) != 0) flags.add(Flag.BRIDGE); if ((mask&SYNTHETIC) != 0) flags.add(Flag.SYNTHETIC); diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/code/Source.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Source.java Fri Nov 09 14:47:22 2012 -0800 @@ -206,6 +206,9 @@ public boolean allowDefaultMethods() { return compareTo(JDK1_8) >= 0; } + public boolean allowStrictMethodClashCheck() { + return compareTo(JDK1_8) >= 0; + } public boolean allowEffectivelyFinalInInnerClasses() { return compareTo(JDK1_8) >= 0; } diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Symbol.java Fri Nov 09 14:47:22 2012 -0800 @@ -1192,9 +1192,9 @@ // check for an inherited implementation if ((flags() & ABSTRACT) != 0 || - (other.flags() & ABSTRACT) == 0 || - !other.isOverridableIn(origin) || - !this.isMemberOf(origin, types)) + (other.flags() & ABSTRACT) == 0 || + !other.isOverridableIn(origin) || + !this.isMemberOf(origin, types)) return false; // assert types.asSuper(origin.type, other.owner) != null; diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/code/Types.java --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java Fri Nov 09 14:47:22 2012 -0800 @@ -75,6 +75,7 @@ final boolean allowBoxing; final boolean allowCovariantReturns; final boolean allowObjectToPrimitiveCast; + final boolean allowDefaultMethods; final ClassReader reader; final Check chk; JCDiagnostic.Factory diags; @@ -98,6 +99,7 @@ allowBoxing = source.allowBoxing(); allowCovariantReturns = source.allowCovariantReturns(); allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast(); + allowDefaultMethods = source.allowDefaultMethods(); reader = ClassReader.instance(context); chk = Check.instance(context); capturedName = names.fromString(""); @@ -2146,6 +2148,13 @@ return List.nil(); } }; + + public boolean isDirectSuperInterface(Type t, TypeSymbol tsym) { + for (Type t2 : interfaces(tsym.type)) { + if (isSameType(t, t2)) return true; + } + return false; + } // // @@ -2310,6 +2319,10 @@ return false; } + public boolean overridesObjectMethod(Symbol msym) { + return ((MethodSymbol)msym).implementation(syms.objectType.tsym, this, true) != null; + } + // class ImplementationCache { @@ -2455,6 +2468,70 @@ } // + + //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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 09 14:47:22 2012 -0800 @@ -135,6 +135,7 @@ allowStringsInSwitch = source.allowStringsInSwitch(); allowPoly = source.allowPoly() && options.isSet("allowPoly"); allowLambda = source.allowLambda(); + allowDefaultMethods = source.allowDefaultMethods(); sourceName = source.name; relax = (options.isSet("-retrofit") || options.isSet("-relax")); @@ -178,6 +179,10 @@ */ boolean allowCovariantReturns; + /** Switch: support default methods ? + */ + boolean allowDefaultMethods; + /** Switch: support lambda expressions ? */ boolean allowLambda; @@ -898,6 +903,10 @@ localEnv.info.lint = lint; + if (isDefaultMethod && types.overridesObjectMethod(m)) { + log.error(tree, "default.overrides.object.member", m.name, Kinds.kindName(m.location()), m.location()); + } + // Enter all type parameters into the local method scope. for (List l = tree.typarams; l.nonEmpty(); l = l.tail) localEnv.info.scope.enterIfAbsent(l.head.type.tsym); @@ -961,10 +970,12 @@ log.error(tree.pos(), "default.allowed.in.intf.annotation.member"); } - } else if ((owner.flags() & INTERFACE) != 0 && !isDefaultMethod) { - log.error(tree.body.pos(), "intf.meth.cant.have.body"); - } else if ((tree.mods.flags & ABSTRACT) != 0) { - log.error(tree.pos(), "abstract.meth.cant.have.body"); + } else if ((tree.sym.flags() & ABSTRACT) != 0 && !isDefaultMethod) { + if ((owner.flags() & INTERFACE) != 0) { + log.error(tree.body.pos(), "intf.meth.cant.have.body"); + } else { + log.error(tree.pos(), "abstract.meth.cant.have.body"); + } } else if ((tree.mods.flags & NATIVE) != 0) { log.error(tree.pos(), "native.meth.cant.have.body"); } else { @@ -3281,6 +3292,23 @@ } } + if (env.info.defaultSuperCallSite != null && + !types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true).contains(sym)) { + Symbol ovSym = null; + for (MethodSymbol msym : types.interfaceCandidates(env.enclClass.type, (MethodSymbol)sym, true)) { + if (msym.overrides(sym, msym.enclClass(), types, true)) { + for (Type i : types.interfaces(env.enclClass.type)) { + if (i.tsym.isSubClass(msym.owner, types)) { + ovSym = i.tsym; + break; + } + } + } + } + log.error(env.tree.pos(), "illegal.default.super.call", env.info.defaultSuperCallSite, + diags.fragment("overridden.default", sym, ovSym)); + } + // Compute the identifier's instantiated type. // For methods, we need to compute the instance type by // Resolve.instantiate from the symbol's type as well as @@ -3700,6 +3728,9 @@ // are compatible (i.e. no two define methods with same arguments // yet different return types). (JLS 8.4.6.3) chk.checkCompatibleSupertypes(tree.pos(), c.type); + if (allowDefaultMethods) { + chk.checkDefaultMethodClashes(tree.pos(), c.type); + } } // Check that class does not import the same parameterized interface diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/AttrContext.java Fri Nov 09 14:47:22 2012 -0800 @@ -72,6 +72,10 @@ */ Attr.ResultInfo returnResult = null; + /** Symbol corresponding to the site of a qualified default super call + */ + Type defaultSuperCallSite = null; + /** Duplicate this context, replacing scope field and copying all others. */ AttrContext dup(Scope scope) { @@ -84,6 +88,7 @@ info.lint = lint; info.enclVar = enclVar; info.returnResult = returnResult; + info.defaultSuperCallSite = defaultSuperCallSite; return info; } diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/Check.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java Fri Nov 09 14:47:22 2012 -0800 @@ -119,6 +119,9 @@ allowAnnotations = source.allowAnnotations(); allowCovariantReturns = source.allowCovariantReturns(); allowSimplifiedVarargs = source.allowSimplifiedVarargs(); + allowDefaultMethods = source.allowDefaultMethods(); + allowStrictMethodClashCheck = source.allowStrictMethodClashCheck() && + options.isSet("strictMethodClashCheck"); //pre-lambda guard complexInference = options.isSet("complexinference"); warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); @@ -162,6 +165,14 @@ */ boolean allowSimplifiedVarargs; + /** Switch: default methods enabled? + */ + boolean allowDefaultMethods; + + /** Switch: should unrelated return types trigger a method clash? + */ + boolean allowStrictMethodClashCheck; + /** Switch: -complexinference option set? */ boolean complexInference; @@ -1114,7 +1125,7 @@ } else if ((sym.owner.flags_field & INTERFACE) != 0) { if ((flags & DEFAULT) != 0) { mask = InterfaceDefaultMethodMask; - implicit = PUBLIC; + implicit = PUBLIC | ABSTRACT; } else { mask = implicit = InterfaceMethodFlags; } @@ -2047,11 +2058,21 @@ undef == null && e != null; e = e.sibling) { if (e.sym.kind == MTH && - (e.sym.flags() & (ABSTRACT|IPROXY)) == ABSTRACT) { + (e.sym.flags() & (ABSTRACT|IPROXY|DEFAULT)) == ABSTRACT) { MethodSymbol absmeth = (MethodSymbol)e.sym; MethodSymbol implmeth = absmeth.implementation(impl, types, true); - if (implmeth == null || implmeth == absmeth) + if (implmeth == null || implmeth == absmeth) { + //look for default implementations + if (allowDefaultMethods) { + MethodSymbol prov = types.interfaceCandidates(impl.type, absmeth).head; + if (prov != null && prov.overrides(absmeth, impl, types, true)) { + implmeth = prov; + } + } + } + if (implmeth == null || implmeth == absmeth) { undef = absmeth; + } } } if (undef == null) { @@ -2354,7 +2375,7 @@ if (m2 == m1) continue; //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) m1 has the same erasure as m2, issue an error - if (!types.isSubSignature(sym.type, types.memberType(site, m2), false) && + if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) && types.hasSameArgs(m2.erasure(types), m1.erasure(types))) { sym.flags_field |= CLASH; String key = m1 == sym ? @@ -2386,7 +2407,7 @@ for (Symbol s : types.membersClosure(site, true).getElementsByName(sym.name, cf)) { //if (i) the signature of 'sym' is not a subsignature of m1 (seen as //a member of 'site') and (ii) 'sym' has the same erasure as m1, issue an error - if (!types.isSubSignature(sym.type, types.memberType(site, s), false) && + if (!types.isSubSignature(sym.type, types.memberType(site, s), allowStrictMethodClashCheck) && types.hasSameArgs(s.erasure(types), sym.erasure(types))) { log.error(pos, "name.clash.same.erasure.no.hide", @@ -2420,6 +2441,62 @@ } } + void checkDefaultMethodClashes(DiagnosticPosition pos, Type site) { + DefaultMethodClashFilter dcf = new DefaultMethodClashFilter(site); + for (Symbol m : types.membersClosure(site, false).getElements(dcf)) { + Assert.check(m.kind == MTH); + List 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java Fri Nov 09 14:47:22 2012 -0800 @@ -502,7 +502,7 @@ 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 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java Fri Nov 09 14:47:22 2012 -0800 @@ -560,6 +560,12 @@ MethodSymbol m = new MethodSymbol(0, tree.name, null, enclScope.owner); m.flags_field = chk.checkFlags(tree.pos(), tree.mods.flags, m, tree); tree.sym = m; + + //if this is a default method, add the DEFAULT flag to the enclosing interface + if ((tree.mods.flags & DEFAULT) != 0) { + m.enclClass().flags_field |= DEFAULT; + } + Env localEnv = methodEnv(tree, env); DeferredLintHandler prevLintHandler = @@ -677,7 +683,7 @@ localEnv.info.scope.owner = tree.sym; } if ((tree.mods.flags & STATIC) != 0 || - (env.enclClass.sym.flags() & INTERFACE) != 0) + ((env.enclClass.sym.flags() & INTERFACE) != 0 && env.enclMethod == null)) localEnv.info.staticLevel++; return localEnv; } @@ -1001,20 +1007,19 @@ } } - // If this is a class, enter symbols for this and super into - // current scope. - if ((c.flags_field & INTERFACE) == 0) { - VarSymbol thisSym = - new VarSymbol(FINAL | HASINIT, names._this, c.type, c); - thisSym.pos = Position.FIRSTPOS; - env.info.scope.enter(thisSym); - if (ct.supertype_field.hasTag(CLASS)) { - VarSymbol superSym = - new VarSymbol(FINAL | HASINIT, names._super, - ct.supertype_field, c); - superSym.pos = Position.FIRSTPOS; - env.info.scope.enter(superSym); - } + // enter symbols for 'this' into current scope. + VarSymbol thisSym = + new VarSymbol(FINAL | HASINIT, names._this, c.type, c); + thisSym.pos = Position.FIRSTPOS; + env.info.scope.enter(thisSym); + // if this is a class, enter symbol for 'super' into current scope. + if ((c.flags_field & INTERFACE) == 0 && + ct.supertype_field.hasTag(CLASS)) { + VarSymbol superSym = + new VarSymbol(FINAL | HASINIT, names._super, + ct.supertype_field, c); + superSym.pos = Position.FIRSTPOS; + env.info.scope.enter(superSym); } // check that no package exists with same fully qualified name, diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java Fri Nov 09 14:47:22 2012 -0800 @@ -51,7 +51,10 @@ 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 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 @@ 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 @@ 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); - } + 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 @@ 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 @@ 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 @@ } } + 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 @@ 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 @@ }; } - /** - * 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 @@ ((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 @@ /** 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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. @@ -2719,6 +2336,350 @@ } /** + * 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. * @param env The environment current at the expression. @@ -2744,9 +2705,47 @@ if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; env1 = env1.outer; } + if (allowDefaultMethods && c.isInterface() && + name == names._super && !isStatic(env) && + types.isDirectSuperInterface(c.type, env.enclClass.sym)) { + //this might be a default super call if one of the superinterfaces is 'c' + for (Type t : pruneInterfaces(env.enclClass.type)) { + if (t.tsym == c) { + env.info.defaultSuperCallSite = t; + return new VarSymbol(0, names._super, + types.asSuper(env.enclClass.type, c), env.enclClass.sym); + } + } + //find a direct superinterface that is a subtype of 'c' + for (Type i : types.interfaces(env.enclClass.type)) { + if (i.tsym.isSubClass(c, types) && i.tsym != c) { + log.error(pos, "illegal.default.super.call", c, + diags.fragment("redundant.supertype", c, i)); + return syms.errSymbol; + } + } + Assert.error(); + } log.error(pos, "not.encl.class", c); return syms.errSymbol; } + //where + private List 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 @@ 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 @@ 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 @@ //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 @@ 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 @@ 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 @@ 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 @@ 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/CRTable.java Fri Nov 09 14:47:22 2012 -0800 @@ -503,6 +503,14 @@ 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 @@ */ 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 @@ */ 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Nov 09 14:47:22 2012 -0800 @@ -115,6 +115,9 @@ */ boolean lintClassfile; + /** Switch: allow default methods + */ + boolean allowDefaultMethods; /** Switch: preserve parameter names from the variable table. */ @@ -279,6 +282,7 @@ allowVarargs = source.allowVarargs(); allowAnnotations = source.allowAnnotations(); allowSimplifiedVarargs = source.allowSimplifiedVarargs(); + allowDefaultMethods = source.allowDefaultMethods(); saveParameterNames = options.isSet("save-parameter-names"); cacheCompletionFailure = options.isUnset("dev"); preferSource = "source".equals(options.get("-Xprefer")); @@ -937,6 +941,18 @@ new AttributeReader(names.Code, V45_3, MEMBER_ATTRIBUTE) { protected void read(Symbol sym, int attrLen) { + if (currentOwner.isInterface() && + (sym.flags_field & ABSTRACT) == 0 && !name.equals(names.clinit)) { + if (majorVersion > Target.JDK1_8.majorVersion || + //todo replace with Target.Version when available + (majorVersion == Target.JDK1_8.majorVersion && minorVersion >= Target.JDK1_8.minorVersion)) { + currentOwner.flags_field |= DEFAULT; + sym.flags_field |= DEFAULT | ABSTRACT; + } else { + //protect against ill-formed classfiles + throw new CompletionFailure(currentOwner, "default method found in pre JDK 8 classfile"); + } + } if (readAllOfClassFile || saveParameterNames) ((MethodSymbol)sym).code = readCode(sym); else diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Fri Nov 09 14:47:22 2012 -0800 @@ -1540,7 +1540,7 @@ 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 @@ result |= ACC_BRIDGE; if ((flags & VARARGS) != 0 && target.useVarargsFlag()) result |= ACC_VARARGS; + if ((flags & DEFAULT) != 0) + result &= ~ABSTRACT; return result; } diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Items.java Fri Nov 09 14:47:22 2012 -0800 @@ -523,7 +523,7 @@ Item invoke() { MethodType mtype = (MethodType)member.externalType(types); int rescode = Code.typecode(mtype.restype); - if ((member.owner.flags() & Flags.INTERFACE) != 0) { + if ((member.owner.flags() & Flags.INTERFACE) != 0 && !nonvirtual) { code.emitInvokeinterface(pool.put(member), mtype); } else if (nonvirtual) { code.emitInvokespecial(pool.put(member), mtype); diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java --- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Target.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 @@ /** 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/main/Main.java --- a/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/main/Main.java Fri Nov 09 14:47:22 2012 -0800 @@ -533,7 +533,7 @@ * 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java --- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Nov 09 14:47:22 2012 -0800 @@ -88,6 +88,15 @@ /** 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 @@ 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 @@ } } + 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties --- a/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javac/resources/compiler.properties Fri Nov 09 14:47:22 2012 -0800 @@ -574,7 +574,7 @@ interface expected here compiler.err.intf.meth.cant.have.body=\ - interface methods cannot have body + interface abstract methods cannot have body compiler.err.invalid.annotation.member.type=\ invalid type for annotation member @@ -941,6 +941,31 @@ compiler.err.types.incompatible.diff.ret=\ types {0} and {1} are incompatible; both define {2}, but with unrelated return types +# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol +compiler.err.types.incompatible.unrelated.defaults=\ + {0} {1} inherits unrelated defaults for {2}({3}) from types {4} and {5} + +# 0: kind, 1: type, 2: name, 3: list of type, 4: symbol, 5: symbol +compiler.err.types.incompatible.abstract.default=\ + {0} {1} inherits abstract and default for {2}({3}) from types {4} and {5} + +# 0: name, 1: kind, 2: symbol +compiler.err.default.overrides.object.member=\ + default method {0} in {1} {2} overrides a member of java.lang.Object + +# 0: type, 1: message segment +compiler.err.illegal.default.super.call=\ + bad type qualifier {0} in default super call\n\ + {1} + +# 0: symbol, 1: type +compiler.misc.overridden.default=\ + method {0} is overridden in {2} + +# 0: symbol, 1: symbol +compiler.misc.redundant.supertype=\ + redundant interface {0} is extended by {1} + compiler.err.unclosed.char.lit=\ unclosed character literal diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java Fri Nov 09 14:47:22 2012 -0800 @@ -81,6 +81,9 @@ docenv.makeAnnotationTypeElementDoc(meth, docComment, tree, lineMap); else docenv.makeMethodDoc(meth, docComment, tree, lineMap); + + // release resources + tree.body = null; } @Override diff -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/SeeTagImpl.java Fri Nov 09 14:47:22 2012 -0800 @@ -267,8 +267,6 @@ } 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javadoc/Start.java --- a/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/Start.java Fri Nov 09 14:47:22 2012 -0800 @@ -54,6 +54,8 @@ * @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 @@ private long defaultFilter = PUBLIC | PROTECTED; - private Messager messager; + private final Messager messager; String docLocale = ""; @@ -96,8 +98,8 @@ 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 @@ 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 @@ 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 @@ javaNames.append(arg); } } + compOpts.notifyListeners(); if (javaNames.isEmpty() && subPackages.isEmpty()) { usageError("main.No_packages_or_classes_specified"); @@ -394,14 +387,13 @@ // 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 -r 1833592bde35 -r 0e685b019743 langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Fri Nov 09 14:47:22 2012 -0800 @@ -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.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.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.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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/7132880/T7132880.out --- a/langtools/test/tools/javac/7132880/T7132880.out Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/7132880/T7132880.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/8002286/T8002286.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/8002286/T8002286.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/8002286/T8002286.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/8002286/T8002286.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/Diagnostics/6799605/T6799605.out --- a/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/Diagnostics/6799605/T6799605.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/BasicSyntaxCombo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 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 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 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 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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DeprecatedAnnoCombo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/DocumentedAnnoCombo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/Helper.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 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 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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/InheritedAnnoCombo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/annotations/repeatingAnnotations/combo/RetentionAnnoCombo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/classfiles/ClassVersionChecker.java --- a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 @@ * -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/ClassReaderTest.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/ClassReaderTest/pkg/Foo.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg01.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg01.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg01.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg01.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg02.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg02.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg02.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg02.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg03.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg03.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg03.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg03.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg04.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg04.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg04.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg04.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg05.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg05.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg05.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg05.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg06.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg06.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg06.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg06.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,2 @@ +Neg06.java:10:37: compiler.err.missing.ret.stmt +1 error diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg07.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg07.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg07.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg07.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg08.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg08.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg08.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg08.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg09.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg09.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg09.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg09.out Fri Nov 09 14:47:22 2012 -0800 @@ -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 -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg10.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg10.java Fri Nov 09 14:47:22 2012 -0800 @@ -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 { } + + static class C3 implements I { + public void m() throws Exception { } //unchecked (throws) override + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg10.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg10.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,5 @@ +Neg10.java:15:12: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C1, m(), Neg10.I), java.lang.Exception +Neg10.java:18:21: compiler.warn.override.unchecked.thrown: (compiler.misc.cant.implement: m(), Neg10.C3, m(), Neg10.I), java.lang.Exception +- compiler.err.warnings.and.werror +1 error +2 warnings diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg11.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg11.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,20 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that default overrides are properly type-checked + * @compile/fail/ref=Neg11.out -XDallowDefaultMethods -XDrawDiagnostics Neg11.java + */ +class Neg11 { + interface I { + default void m() { } + } + + static class C1 { + public void m() throws Exception { } //bad throws + } + + static class C2 extends C1 implements I { } + + static class C3 implements I { + public void m() throws Exception { } //bad throws + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg11.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg11.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,3 @@ +Neg11.java:15:12: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C1, m(), Neg11.I), java.lang.Exception +Neg11.java:18:21: compiler.err.override.meth.doesnt.throw: (compiler.misc.cant.implement: m(), Neg11.C3, m(), Neg11.I), java.lang.Exception +2 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg12.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg12.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,27 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that abstract methods are discarded in overload resolution diags + * @compile/fail/ref=Neg12.out -XDallowDefaultMethods -XDrawDiagnostics Neg12.java + */ +class Neg12 { + + interface I1 { + default void m(String s) {}; + } + + interface I2 { + void m(String s); + } + + static class B { + void m(Integer i) { } + } + + static class C extends B implements I1 { } + static class D extends B implements I2 { } + + void test(C c, D d) { + c.m(); + d.m(); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg12.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg12.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,4 @@ +Neg12.java:21:12: compiler.err.does.not.override.abstract: Neg12.D, m(java.lang.String), Neg12.I2 +Neg12.java:24:10: compiler.err.cant.apply.symbols: kindname.method, m, ,{(compiler.misc.inapplicable.method: kindname.method, Neg12.I1, m(java.lang.String), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, Neg12.B, m(java.lang.Integer), (compiler.misc.arg.length.mismatch))} +Neg12.java:25:10: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Integer, compiler.misc.no.args, kindname.class, Neg12.B, (compiler.misc.arg.length.mismatch) +3 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg13.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg13.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,18 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that default method overriding object members are flagged as error + * @compile/fail/ref=Neg13.out -XDallowDefaultMethods -XDrawDiagnostics Neg13.java + */ +interface Neg13 { + default protected Object clone() { return null; } //protected not allowed here + default boolean equals(Object obj) { return false; } + default protected void finalize() { } //protected not allowed here + default Class getClass() { return null; } + default int hashCode() { return 0; } + default void notify() { } + default void notifyAll() { } + default String toString() { return null; } + default void wait() { } + default void wait(long timeout) { } + default void wait(long timeout, int nanos) { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg13.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg13.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,12 @@ +Neg13.java:7:30: compiler.err.mod.not.allowed.here: protected +Neg13.java:9:28: compiler.err.mod.not.allowed.here: protected +Neg13.java:8:21: compiler.err.default.overrides.object.member: equals, kindname.interface, Neg13 +Neg13.java:10:22: compiler.err.override.meth: (compiler.misc.cant.override: getClass(), Neg13, getClass(), java.lang.Object), final +Neg13.java:11:17: compiler.err.default.overrides.object.member: hashCode, kindname.interface, Neg13 +Neg13.java:12:18: compiler.err.override.meth: (compiler.misc.cant.override: notify(), Neg13, notify(), java.lang.Object), final +Neg13.java:13:18: compiler.err.override.meth: (compiler.misc.cant.override: notifyAll(), Neg13, notifyAll(), java.lang.Object), final +Neg13.java:14:20: compiler.err.default.overrides.object.member: toString, kindname.interface, Neg13 +Neg13.java:15:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(), Neg13, wait(), java.lang.Object), final +Neg13.java:16:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long), Neg13, wait(long), java.lang.Object), final +Neg13.java:17:18: compiler.err.override.meth: (compiler.misc.cant.override: wait(long,int), Neg13, wait(long,int), java.lang.Object), final +11 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg14.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg14.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that a class cannot have two sibling interfaces with a default and abstract method + * @compile/fail/ref=Neg14.out -XDallowDefaultMethods -XDrawDiagnostics Neg14.java + */ +class Neg14 { + interface IA { int m(); } + interface IB { default int m() { return 1; } } + + abstract class AB implements IA, IB {} +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg14.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg14.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,2 @@ +Neg14.java:10:14: compiler.err.types.incompatible.abstract.default: kindname.class, Neg14.AB, m, , Neg14.IB, Neg14.IA +1 error diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg15.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg15.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,14 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that level skipping in default super calls is correctly rejected + * @compile/fail/ref=Neg15.out -XDallowDefaultMethods -XDrawDiagnostics Neg15.java + */ +class Neg15 { + interface I { default void m() { } } + interface J extends I { default void m() { } } + interface K extends I {} + + static class C implements J, K { + void foo() { K.super.m(); } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg15.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg15.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,2 @@ +Neg15.java:12:31: compiler.err.illegal.default.super.call: Neg15.K, (compiler.misc.overridden.default: m(), Neg15.J) +1 error diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg16.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg16.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,13 @@ +/* + * @test /nodynamiccopyright/ + * @summary check that level skipping in default super calls is correctly rejected + * @compile/fail/ref=Neg16.out -XDallowDefaultMethods -XDrawDiagnostics Neg16.java + */ +class Neg16 { + interface I { default void m() { } } + interface J extends I { default void m() { } } + + static class C implements I, J { + void foo() { I.super.m(); } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Neg16.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Neg16.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,2 @@ +Neg16.java:11:23: compiler.err.illegal.default.super.call: Neg16.I, (compiler.misc.redundant.supertype: Neg16.I, Neg16.J) +1 error diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos01.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos01.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary basic test for default methods + * @ignore awaits lambda support + * @author Maurizio Cimadamore + * @compile -XDallowLambda -XDallowPoly -XDallowDefaultMethods Pos01.java + */ + +import java.util.*; + +class Pos01 { + + interface Mapper { + T map(T in); + } + + interface ExtendedList extends List { + default List testMap(Mapper r) { + return Pos01.listMapper(this, r); + } + } + + static class MyList extends ArrayList implements ExtendedList {} + + public static void main(String[] args) { + MyList l = new MyList(); + l.add(1); l.add(2); l.add(3); + l.testMap((Integer x) -> x * x ); + } + + static List listMapper(List l, Mapper mapper) { + MyList new_list = new MyList(); + for (T el : l) { + new_list.add(mapper.map(el)); + } + return new_list; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos02.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos02.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary test for explicit resolution of ambiguous default methods + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos02.java + */ + +class Pos02 { + interface IA { default int m() { return Pos02.m1(this); } } + interface IB { default int m() { return Pos02.m2(this); } } + + static class A implements IA {} + static class B implements IB {} + + static class AB implements IA, IB { + public int m() { return 0; } + void test() { + AB.this.m(); + IA.super.m(); + } + } + + static int m1(IA a) { return 0; } + static int m2(IB b) { return 0; } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos04.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos04.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary test for overriding with default method + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos04.java + */ + +class Pos04 { + interface A { default int m() { return Pos04.m(this); } } + static abstract class B { public int m() { return 0; } } + + static class C extends B implements A { + void test() { + C.this.m(); + A.super.m(); + } + } + + static int m(A a) { return 0; } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos05.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos05.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that indirectly inherited default methods are discovered during resolution + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos05.java + */ + +class Pos05 { + interface A { + default void m() { Pos05.impl(this); } + } + + interface B extends A { } + + static class E implements B { } + + void test(E e) { + e.m(); + } + + static void impl(A a) { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos06.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos06.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that well-formed MI hierarchies behaves well w.r.t. method resolution (i.e. no ambiguities) + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos06.java + */ + +class Pos06 { + interface A { + default void m() { Pos06.impl(this); } + } + + interface B extends A { + default void m() { Pos06.impl(this); } + } + + static class X implements A, B { } + + void test(X x) { + x.m(); + ((A)x).m(); + ((B)x).m(); + } + + static void impl(Object a) { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos07.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos07.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that compilation order does not matter + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos07.java + */ + +class Pos07 { + interface A { + default void foo() { Pos07.impl(this); } + default void bar() { Pos07.impl(this); } + } + + static class C implements B, A {} + + interface B extends A { + default void foo() { Pos07.impl(this); } + } + + static void impl(A a) {} +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos08.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos08.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that common overrider solves default method conflicts + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos08.java + */ + +class Pos08 { + interface A { + default void m() { Pos08.a(this); } + } + + interface B { + default void m() { Pos08.b(this); } + } + + interface C extends A, B { + default void m() { Pos08.b(this); } + } + + static void a(A o) { } + static void b(B o) { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos10.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos10.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that type-variables in generic extension decl can be accessed from default impl + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods Pos10.java + */ + +class Pos10 { + interface Function { + Y apply(X x); + } + + interface A { + default void m(Function f) { Impl.m(this, f); } + } + + static class Impl { + static void m(A a, Function f) { } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos11.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos11.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary complex test with conflict resolution via overriding + * @author Brian Goetz + * @compile -XDallowDefaultMethods Pos11.java + */ + +class Pos11 { + interface A { + default void get() { Pos11.one(this); } + } + + interface B { + default void get() { Pos11.two(this); } + } + + interface C extends A { + default void get() { Pos11.two(this); } + } + + interface D extends A, B { + default void get() { Pos11.two(this); } + } + + static class X implements C { } + + static class Y implements C, A { } + + static class Z implements D, A, B { } + + static void one(Object a) { } + static void two(Object a) { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos12.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos12.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that 'this' can be used from within an extension method + * @compile -XDallowDefaultMethods Pos12.java + */ + +interface Pos12 { + + default Object m() { + Object o = this; + f(this); + return this; + } + + void f(Object o); +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos13.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos13.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary qualified 'this' inside default method causes StackOverflowException + * @compile -XDallowDefaultMethods Pos13.java + */ + +public class Pos13 { + + static int assertionCount = 0; + + static void assertTrue(boolean cond) { + assertionCount++; + if (!cond) + throw new AssertionError(); + } + + interface Outer { + abstract void doSomething(); + + default void m() { + new SubOuter() { + public void doSomething() { + Outer.this.doSomething(); + } + }.doSomething(); + } + } + + interface SubOuter extends Outer { } + + static class E implements Outer { + public void doSomething() { assertTrue(true); } + } + + public static void main(String[] args) { + new E().m(); + assertTrue(assertionCount == 1); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos14.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos14.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that overload resolution selects most specific signature + * @compile -XDallowDefaultMethods Pos14.java + */ + +class Pos14 { + interface A { default Object m() { return null; } } + static abstract class B { abstract public String m(); } + + static abstract class C extends B implements A { + void test() { + m().length(); + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos15.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos15.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that overload resolution selects most specific signature + * @compile -XDallowDefaultMethods Pos15.java + */ + +class Pos15 { + interface A { default String m() { return null; } } + static abstract class B { abstract public Object m(); } + + static abstract class C extends B implements A { + void test() { + m().length(); + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/Pos16.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/Pos16.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary 'class wins' should not short-circuit overload resolution + * @compile -XDallowDefaultMethods Pos16.java + */ + +class Pos16 { + interface I { + default String m(Integer i) { return ""; } + } + + class C implements I { + Integer m(Object o) { return 1; } + } + + void test(C c) { + c.m(1).length(); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/TestDefaultBody.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/TestDefaultBody.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @ignore awaits for VM support + * @summary check that code attributed for default methods is correctly generated + * @compile -XDallowDefaultMethods TestDefaultBody.java + * @run main TestDefaultBody + */ + +import com.sun.tools.classfile.AccessFlags; +import com.sun.tools.classfile.Attribute; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.Code_attribute; +import com.sun.tools.classfile.Instruction; +import com.sun.tools.classfile.Method; + +import com.sun.tools.classfile.Opcode; +import java.io.*; + +public class TestDefaultBody { + + interface TestInterface { + int no_default(int i); + default int yes_default(int i) { return impl(this, i); } + } + + static int impl(TestInterface ti, int i) { return 0; } + + static final String TARGET_CLASS_NAME = "TestDefaultBody"; + static final String TARGET_NAME = "impl"; + static final String TARGET_TYPE = "(LTestDefaultBody$TestInterface;I)I"; + static final String SUBTEST_NAME = TestInterface.class.getName() + ".class"; + static final String TEST_METHOD_NAME = "yes_default"; + + public static void main(String... args) throws Exception { + new TestDefaultBody().run(); + } + + public void run() throws Exception { + String workDir = System.getProperty("test.classes"); + File compiledTest = new File(workDir, SUBTEST_NAME); + verifyDefaultBody(compiledTest); + } + + void verifyDefaultBody(File f) { + System.err.println("verify: " + f); + try { + ClassFile cf = ClassFile.read(f); + Method testMethod = null; + Code_attribute codeAttr = null; + for (Method m : cf.methods) { + codeAttr = (Code_attribute)m.attributes.get(Attribute.Code); + String mname = m.getName(cf.constant_pool); + if (mname.equals(TEST_METHOD_NAME)) { + testMethod = m; + break; + } else { + codeAttr = null; + } + } + if (testMethod == null) { + throw new Error("Test method not found"); + } + if (testMethod.access_flags.is(AccessFlags.ACC_ABSTRACT)) { + throw new Error("Test method is abstract"); + } + if (codeAttr == null) { + throw new Error("Code attribute in test method not found"); + } + + boolean found = false; + for (Instruction instr : codeAttr.getInstructions()) { + if (instr.getOpcode() == Opcode.INVOKESTATIC) { + found = true; + int pc_index = instr.getShort(1); + CONSTANT_Methodref_info mref = (CONSTANT_Methodref_info)cf.constant_pool.get(pc_index); + String className = mref.getClassName(); + String targetName = mref.getNameAndTypeInfo().getName(); + String targetType = mref.getNameAndTypeInfo().getType(); + + if (!className.equals(TARGET_CLASS_NAME)) { + throw new Error("unexpected class in default method body " + className); + } + if (!targetName.equals(TARGET_NAME)) { + throw new Error("unexpected method name in default method body " + targetName); + } + if (!targetType.equals(TARGET_TYPE)) { + throw new Error("unexpected method type in default method body " + targetType); + } + break; + } + } + + if (!found) { + throw new Error("no invokestatic found in default method body"); + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + f +": " + e); + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/TestNoBridgeOnDefaults.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @ignore awaits for VM support + * @summary check that javac does not generate bridge methods for defaults + * @compile -XDallowDefaultMethods TestNoBridgeOnDefaults.java + * @run main TestNoBridgeOnDefaults + */ + +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool.*; +import com.sun.tools.classfile.Method; + +import java.io.*; + +public class TestNoBridgeOnDefaults { + + interface A { + default A m(X x, Y y) { return Impl.m1(this, x, y); } + } + + static abstract class B implements A { } + + interface C extends A { + default C m(X x, Y y) { return Impl.m2(this, x, y); } + } + + static abstract class D extends B implements C { } + + static class Impl { + static A m1(A rec, X x, Y y) { return null; } + static C m2(C rec, X x, Y y) { return null; } + } + + static final String[] SUBTEST_NAMES = { B.class.getName() + ".class", D.class.getName() + ".class" }; + static final String TEST_METHOD_NAME = "m"; + + public static void main(String... args) throws Exception { + new TestNoBridgeOnDefaults().run(); + } + + public void run() throws Exception { + String workDir = System.getProperty("test.classes"); + for (int i = 0 ; i < SUBTEST_NAMES.length ; i ++) { + File compiledTest = new File(workDir, SUBTEST_NAMES[i]); + checkNoBridgeOnDefaults(compiledTest); + } + } + + void checkNoBridgeOnDefaults(File f) { + System.err.println("check: " + f); + try { + ClassFile cf = ClassFile.read(f); + for (Method m : cf.methods) { + String mname = m.getName(cf.constant_pool); + if (mname.equals(TEST_METHOD_NAME)) { + throw new Error("unexpected bridge method found " + m); + } + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + f +": " + e); + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/crossCompile/Clinit.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/crossCompile/Clinit.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +interface Clinit { + String s = Inner.m(); + + static class Inner { + static String m() { return ""; } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/crossCompile/CrossCompile.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary check that clinit in interface doesn't cause spurious default method diagnostics + * @compile -source 1.4 -target 1.4 Clinit.java + * @compile CrossCompile.java + */ +class CrossCompile { + void test() { + String s = Clinit.s; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/FDTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/FDTest.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Automatic test for checking correctness of default resolution + */ + +import shapegen.*; + +import com.sun.source.util.JavacTask; + +import java.net.URI; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import javax.tools.Diagnostic; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +public class FDTest { + + enum TestKind { + POSITIVE, + NEGATIVE; + + Collection getHierarchy(HierarchyGenerator hg) { + return this == POSITIVE ? + hg.getOK() : hg.getErr(); + } + } + + public static void main(String[] args) throws Exception { + //create default shared JavaCompiler - reused across multiple compilations + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + + HierarchyGenerator hg = new HierarchyGenerator(); + for (TestKind tk : TestKind.values()) { + for (Hierarchy hs : tk.getHierarchy(hg)) { + new FDTest(tk, hs).run(comp, fm); + } + } + } + + TestKind tk; + Hierarchy hs; + DefenderTestSource source; + DiagnosticChecker diagChecker; + + FDTest(TestKind tk, Hierarchy hs) { + this.tk = tk; + this.hs = hs; + this.source = new DefenderTestSource(); + this.diagChecker = new DiagnosticChecker(); + } + + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, + Arrays.asList("-XDallowDefaultMethods"), null, Arrays.asList(source)); + try { + ct.analyze(); + } catch (Throwable ex) { + throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true)); + } + check(); + } + + void check() { + boolean errorExpected = tk == TestKind.NEGATIVE; + if (errorExpected != diagChecker.errorFound) { + throw new AssertionError("problem in source: \n" + + "\nerror found = " + diagChecker.errorFound + + "\nerror expected = " + errorExpected + + "\n" + dumpHierarchy() + + "\n" + source.getCharContent(true)); + } + } + + String dumpHierarchy() { + StringBuilder buf = new StringBuilder(); + buf.append("root = " + hs.root + "\n"); + for (ClassCase cc : hs.all) { + buf.append(" class name = " + cc.getName() + "\n"); + buf.append(" class OK = " + cc.get_OK() + "\n"); + buf.append(" prov = " + cc.get_mprov() + "\n"); + + } + return buf.toString(); + } + + class DefenderTestSource extends SimpleJavaFileObject { + + String source; + + public DefenderTestSource() { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + StringBuilder buf = new StringBuilder(); + List defaultRef = new ArrayList<>(); + for (ClassCase cc : hs.all) { + hs.genClassDef(buf, cc, null, defaultRef); + } + source = buf.toString(); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + static class DiagnosticChecker implements javax.tools.DiagnosticListener { + + boolean errorFound; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + errorFound = true; + } + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/ClassCase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/ClassCase.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * + * @author Robert Field + */ +public class ClassCase { + + public enum Kind { + IVAC (true, "v"), + IPRESENT (true, "p"), + IDEFAULT (true, "d"), + CNONE (false, "n"), + CABSTRACT (false, "a"), + CCONCRETE (false, "c"); + + private final String prefix; + public final boolean isInterface; + + Kind(boolean isInterface, String prefix) { + this.isInterface = isInterface; + this.prefix = prefix; + } + } + + public final Kind kind; + private final ClassCase superclass; + private final List supertypes; + + private String name; + private boolean _OK; + private boolean _HasClassMethod; + private Set _mprov; + private boolean _IsConcrete; + private boolean _HasDefault; + private ClassCase _mres; + private ClassCase _mdefend; + + private Set executed = new HashSet() {}; + + public ClassCase(Kind kind, ClassCase superclass, List interfaces) { + this.kind = kind; + this.superclass = superclass; + + // Set supertypes from superclass (if any) and interfaces + List lc; + if (superclass == null) { + lc = interfaces; + } else { + lc = new ArrayList<>(); + lc.add(superclass); + lc.addAll(interfaces); + } + this.supertypes = lc; + } + + public final boolean isInterface() { return kind.isInterface; } + public final boolean isClass() { return !kind.isInterface; } + + public Set get_mprov() { + exec(RuleGroup.PROVENENCE); + return _mprov; + } + + public void set_mprov(ClassCase cc) { + Set s = new HashSet<>(); + s.add(cc); + _mprov = s; + } + + public void set_mprov(Set s) { + _mprov = s; + } + + public ClassCase get_mres() { + exec(RuleGroup.RESOLUTION); + return _mres; + } + + public void set_mres(ClassCase cc) { + _mres = cc; + } + + public ClassCase get_mdefend() { + exec(RuleGroup.DEFENDER); + return _mdefend; + } + + public void set_mdefend(ClassCase cc) { + _mdefend = cc; + } + + public boolean get_HasClassMethod() { + exec(RuleGroup.PROVENENCE); + return _HasClassMethod; + } + + public void set_HasClassMethod(boolean bool) { + _HasClassMethod = bool; + } + + public boolean get_HasDefault() { + exec(RuleGroup.MARKER); + return _HasDefault; + } + + public void set_HasDefault(boolean bool) { + _HasDefault = bool; + } + + public boolean get_IsConcrete() { + exec(RuleGroup.MARKER); + return _IsConcrete; + } + + public void set_IsConcrete(boolean bool) { + _IsConcrete = bool; + } + + public boolean get_OK() { + exec(RuleGroup.CHECKING); + return _OK; + } + + public void set_OK(boolean bool) { + _OK = bool; + } + + public boolean isMethodDefined() { + for (ClassCase cc : supertypes) { + if (cc.isMethodDefined()) { + return true; + } + } + switch (kind) { + case CCONCRETE: + case CABSTRACT: + case IPRESENT: + case IDEFAULT: + return true; + default: + return false; + } + } + + public boolean isAbstract() { + return isMethodDefined() && (get_mres()==null); + } + + public boolean hasSuperclass() { + return superclass != null; + } + + public ClassCase getSuperclass() { + return superclass; + } + + public List getSupertypes() { + return supertypes; + } + + public List getInterfaces() { + if (superclass != null) { + if (supertypes.get(0) != superclass) { + throw new AssertionError("superclass missing from supertypes"); + } + return supertypes.subList(1, supertypes.size()); + } else { + return supertypes; + } + } + + public boolean isSubtypeOf(ClassCase cc) { + // S-Refl + if (cc.equals(this)) { + return true; + } + + // S-Def + for (ClassCase sp : getSupertypes()) { + if (cc.equals(sp)) { + return true; + } + } + + // _S-Trans + for (ClassCase sp : getSupertypes()) { + if (sp.isSubtypeOf(cc)) { + return true; + } + } + + return false; + } + + public void init(Map namingContext) { + if (name != null) { + return; // Already inited + } + + for (ClassCase sup : supertypes) { + sup.init(namingContext); + } + + // Build name + StringBuilder sb = new StringBuilder(); + if (!supertypes.isEmpty()) { + sb.append(isInterface() ? "I" : "C"); + for (ClassCase cc : supertypes) { + sb.append(cc.getName()); + } + sb.append(kind.isInterface ? "i" : "c"); + } + sb.append(kind.prefix); + String pname = sb.toString(); + Integer icnt = namingContext.get(pname); + int cnt = icnt == null ? 0 : icnt; + ++cnt; + namingContext.put(pname, cnt); + if (cnt > 1) { + sb.append(cnt); + } + this.name = sb.toString(); + } + + public boolean isa(Kind... kinds) { + for (Kind k : kinds) { + if (kind == k) { + return true; + } + } + return false; + } + + private void exec(RuleGroup rg ) { + if (!executed.contains(rg)) { + rg.exec(this); + executed.add(rg); + } + } + + public void collectClasses(Set seen) { + seen.add(this); + for (ClassCase cc : supertypes) { + cc.collectClasses(seen); + } + } + + public String getID() { + if (name == null) { + throw new Error("Access to uninitialized ClassCase"); + } else { + return name; + } + } + + public final String getName() { + if (name == null) { + return "ClassCase uninited@" + hashCode(); + } else { + return name; + } + } + + @Override + public boolean equals(Object obj) { + return obj instanceof ClassCase && getID().equals(((ClassCase)obj).getID()); + } + + @Override + public int hashCode() { + return getID().hashCode(); + } + + @Override + public String toString() { + return getName(); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/Hierarchy.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/Hierarchy.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import java.util.List; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import static shapegen.ClassCase.Kind.*; + +/** + * + * @author Robert Field + */ +public class Hierarchy { + + public final ClassCase root; + public final Set all; + + public Hierarchy(ClassCase root) { + this.root = root; + root.init(new HashMap()); + Set allClasses = new HashSet<>(); + root.collectClasses(allClasses); + this.all = allClasses; + } + + public boolean anyDefaults() { + for (ClassCase cc : all) { + if (cc.kind == IDEFAULT) { + return true; + } + } + return false; + } + + public boolean get_OK() { + return root.get_OK(); + } + + public String testName() { + return root + "Test"; + } + + private static void genInterfaceList(StringBuilder buf, String prefix, List interfaces) { + if (!interfaces.isEmpty()) { + buf.append(" "); + buf.append(prefix); + buf.append(" "); + buf.append(interfaces.get(0)); + for (int i = 1; i < interfaces.size(); ++i) { + buf.append(", " + interfaces.get(i)); + } + } + } + + public static void genClassDef(StringBuilder buf, ClassCase cc, String implClass, List defaultRef) { + if (cc.isInterface()) { + buf.append("interface "); + buf.append(cc.getName() + " "); + genInterfaceList(buf, "extends", cc.getInterfaces()); + buf.append(" {\n"); + + switch (cc.kind) { + case IDEFAULT: + buf.append(" default String m() { return \"\"; }\n"); + defaultRef.add(cc); + break; + case IPRESENT: + buf.append(" String m();\n"); + break; + case IVAC: + break; + default: + throw new AssertionError("Unexpected kind"); + } + buf.append("}\n\n"); + } else { + buf.append((cc.isAbstract()? "abstract " : "")); + buf.append(" class " + cc.getName()); + if (cc.getSuperclass() != null) { + buf.append(" extends " + cc.getSuperclass()); + } + + genInterfaceList(buf, "implements", cc.getInterfaces()); + buf.append(" {\n"); + + switch (cc.kind) { + case CCONCRETE: + buf.append(" public String m() { return \"\"; }\n"); + break; + case CABSTRACT: + buf.append(" public abstract String m();\n"); + break; + case CNONE: + break; + default: + throw new AssertionError("Unexpected kind"); + } + buf.append("}\n\n"); + } + } + + @Override + public boolean equals(Object obj) { + return obj instanceof Hierarchy && root.getID().equals(((Hierarchy)obj).root.getID()); + } + + @Override + public int hashCode() { + return root.getID().hashCode(); + } + + @Override + public String toString() { + return root.getName(); + } + +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/HierarchyGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/HierarchyGenerator.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import shapegen.ClassCase.Kind; + +import java.util.Collection; +import java.util.Set; +import java.util.HashSet; +import java.util.Collections; +import java.util.ArrayList; +import java.util.List; + +import static shapegen.ClassCase.Kind.*; + +import static java.lang.Math.pow; + +/** + * + * @author Robert Field + */ +public final class HierarchyGenerator { + + private static int okcnt = 0; + private static int errcnt = 0; + private static Set uniqueOK = new HashSet<>(); + private static Set uniqueErr = new HashSet<>(); + + /** + * @param args the command line arguments + */ + public HierarchyGenerator() { + organize("exhaustive interface", iExhaustive(2)); + organize("exhaustive class", cExhaustive()); + organize("shapes interface", iShapes()); + organize("shapes class/interface", ciShapes()); + + System.out.printf("\nExpect OK: %d -- unique %d", okcnt, uniqueOK.size()); + System.out.printf("\nExpect Error: %d -- unique %d\n", errcnt, uniqueErr.size()); + } + + public Collection getOK() { + return uniqueOK; + } + + public Collection getErr() { + return uniqueErr; + } + + private void organize(String tname, List totest) { + System.out.printf("\nTesting %s....\n", tname); + int nodefault = 0; + List ok = new ArrayList<>(); + List err = new ArrayList<>(); + for (Hierarchy cc : totest) { + if (cc.anyDefaults()) { + //System.out.printf(" %s\n", cc); + if (cc.get_OK()) { + ok.add(cc); + } else { + err.add(cc); + } + } else { + ++nodefault; + } + } + + errcnt += err.size(); + okcnt += ok.size(); + uniqueErr.addAll(err); + uniqueOK.addAll(ok); + + System.out.printf(" %5d No default\n %5d Error\n %5d OK\n %5d Total\n", + nodefault, err.size(), ok.size(), totest.size()); + } + + public List iExhaustive(int idepth) { + List current = new ArrayList<>(); + for (int i = 0; i < idepth; ++i) { + current = ilayer(current); + } + return wrapInClassAndHierarchy(current); + } + + private List ilayer(List srcLayer) { + List lay = new ArrayList<>(); + for (int i = (int) pow(2, srcLayer.size()) - 1; i >= 0; --i) { + List itfs = new ArrayList<>(); + for (int b = srcLayer.size() - 1; b >= 0; --b) { + if ((i & (1< cExhaustive() { + final Kind[] iKinds = new Kind[]{IDEFAULT, IVAC, IPRESENT, null}; + final Kind[] cKinds = new Kind[]{CNONE, CABSTRACT, CCONCRETE}; + List totest = new ArrayList<>(); + for (int i1 = 0; i1 < iKinds.length; ++i1) { + for (int i2 = 0; i2 < iKinds.length; ++i2) { + for (int i3 = 0; i3 < iKinds.length; ++i3) { + for (int c1 = 0; c1 < cKinds.length; ++c1) { + for (int c2 = 0; c2 < cKinds.length; ++c2) { + for (int c3 = 0; c3 < cKinds.length; ++c3) { + totest.add( new Hierarchy( + new ClassCase(cKinds[c1], + new ClassCase(cKinds[c2], + new ClassCase(cKinds[c3], + null, + iList(iKinds[i1]) + ), + iList(iKinds[i2]) + ), + iList(iKinds[i3]) + ))); + } + } + } + } + } + } + return totest; + } + + private List iList(Kind kind) { + if (kind == null) { + return Collections.EMPTY_LIST; + } else { + List itfs = new ArrayList<>(); + itfs.add(new ClassCase(kind, null, Collections.EMPTY_LIST)); + return itfs; + } + } + + public List ciShapes() { + return wrapInHierarchy(TTShape.allCases(true)); + } + + public List iShapes() { + return wrapInClassAndHierarchy(TTShape.allCases(false)); + } + + public List wrapInClassAndHierarchy(List ihs) { + List totest = new ArrayList<>(); + for (ClassCase cc : ihs) { + List interfaces = new ArrayList<>(); + interfaces.add(cc); + totest.add(new Hierarchy(new ClassCase(CNONE, null, interfaces))); + } + return totest; + } + + public List wrapInHierarchy(List ihs) { + List totest = new ArrayList<>(); + for (ClassCase cc : ihs) { + totest.add(new Hierarchy(cc)); + } + return totest; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/Rule.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/Rule.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +/** + * + * @author Robert Field + */ +public abstract class Rule { + + public final String name; + + public Rule(String name) { + this.name = name; + } + + abstract boolean guard(ClassCase cc); + + abstract void eval(ClassCase cc); + + @Override + public String toString() { + return name; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/RuleGroup.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/RuleGroup.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import java.util.HashSet; +import java.util.Set; + +import static shapegen.ClassCase.Kind.*; + +/** + * + * @author Robert Field + */ +public class RuleGroup { + + final String name; + private final Rule[] rules; + + public RuleGroup(String name, Rule[] rules) { + this.name = name; + this.rules = rules; + } + + public boolean exec(ClassCase cc) { + boolean found = false; + for (Rule rule : rules) { + if (rule.guard(cc)) { + if (found) { + throw new RuntimeException("Bad rules -- multiple matches " + toString() + " for " + cc); + } else { + rule.eval(cc); + found = true; + } + } + } + return found; + } + + @Override + public String toString() { + return name; + } + + public static RuleGroup PROVENENCE = new RuleGroup("Provenence", new Rule[] { + new Rule("P-CDeclare") { + boolean guard(ClassCase cc) { + return cc.isa(CCONCRETE, CABSTRACT); + } + + void eval(ClassCase cc) { + cc.set_mprov(cc); + cc.set_HasClassMethod(true); + } + }, + + new Rule("P-IDeclare") { + boolean guard(ClassCase cc) { + return cc.isa(IDEFAULT, IPRESENT); + } + + void eval(ClassCase cc) { + cc.set_mprov(cc); + } + }, + + new Rule("P-IntfInh") { + boolean guard(ClassCase cc) { + return cc.isa(IVAC, CNONE) && !(cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod()); + } + + void eval(ClassCase cc) { + Set _S = new HashSet<>(); + for (ClassCase t : cc.getSupertypes()) { + _S.addAll(t.get_mprov()); + } + Set tops = new HashSet<>(); + for (ClassCase _W : _S) { + for (ClassCase _V : _S) { + if (_V.equals(_W) || !(_V.isSubtypeOf(_W))) { + tops.add(_W); + } + } + } + cc.set_mprov(tops); + } + }, + + new Rule("P-ClassInh") { + boolean guard(ClassCase cc) { + return cc.isa(CNONE) && (cc.hasSuperclass() && cc.getSuperclass().get_HasClassMethod()); + } + + void eval(ClassCase cc) { + cc.set_mprov(cc.getSuperclass()); + cc.set_HasClassMethod(true); + } + }, + + }); + + public static RuleGroup MARKER = new RuleGroup("Marker", new Rule[] { + new Rule("M-Default") { + boolean guard(ClassCase cc) { + return cc.isa(IDEFAULT); + } + + void eval(ClassCase cc) { + cc.set_HasDefault(true); + } + }, + + new Rule("M-Conc") { + boolean guard(ClassCase cc) { + return cc.isa(CCONCRETE); + } + + void eval(ClassCase cc) { + cc.set_IsConcrete(true); + } + }, + + }); + + public static RuleGroup RESOLUTION = new RuleGroup("Resolution", new Rule[] { + new Rule("R-Resolve") { + boolean guard(ClassCase cc) { + if (!(cc.isClass() && cc.get_mprov().size() == 1)) { + return false; + } + ClassCase _V = cc.get_mprov().iterator().next(); + return _V.get_IsConcrete() || _V.get_HasDefault(); + } + + void eval(ClassCase cc) { + ClassCase _V = cc.get_mprov().iterator().next(); + cc.set_mres(_V); + } + }, + + }); + + public static RuleGroup DEFENDER = new RuleGroup("Defender", new Rule[] { + new Rule("D-Defend") { + boolean guard(ClassCase cc) { + ClassCase mresSuper = cc.hasSuperclass() ? cc.getSuperclass().get_mres() : null; + boolean eq = cc.get_mres() == null ? mresSuper == null : cc.get_mres().equals(mresSuper); + return cc.isa(CNONE) && !eq; + } + + void eval(ClassCase cc) { + cc.set_mdefend(cc.get_mres()); + } + }, + + }); + + public static RuleGroup CHECKING = new RuleGroup("Checking", new Rule[] { + new Rule("C-Check") { + boolean guard(ClassCase cc) { + for (ClassCase t : cc.getSupertypes()) { + if (! t.get_OK()) { + return false; + } + } + int defenderCount = 0; + int provCount = 0; + for (ClassCase prov : cc.get_mprov()) { + if (prov.get_HasDefault()) { + defenderCount++; + } + provCount++; + } + return provCount <= 1 || defenderCount == 0; + } + + void eval(ClassCase cc) { + cc.set_OK(true); + } + }, + + }); + +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/TTNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTNode.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import shapegen.ClassCase.Kind; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static shapegen.ClassCase.Kind.*; + +/** + * Type Template Node + * + * @author Robert Field + */ +public class TTNode { + + final List supertypes; + final boolean canBeClass; + + private int currentKindIndex; + private Kind[] kinds; + + public TTNode(List subtypes, boolean canBeClass) { + this.supertypes = subtypes; + this.canBeClass = canBeClass; + } + + public void start(boolean includeClasses) { + kinds = + supertypes.isEmpty()? + (new Kind[]{IDEFAULT, IPRESENT}) + : ((includeClasses && canBeClass)? + new Kind[]{CNONE, IVAC, IDEFAULT, IPRESENT} + : new Kind[]{IVAC, IDEFAULT, IPRESENT}); + currentKindIndex = 0; + + for (TTNode sub : supertypes) { + sub.start(includeClasses); + } + } + + public boolean next() { + ++currentKindIndex; + if (currentKindIndex >= kinds.length) { + currentKindIndex = 0; + return false; + } else { + return true; + } + } + + public void collectAllSubtypes(Set subs) { + subs.add(this); + for (TTNode n : supertypes) { + n.collectAllSubtypes(subs); + } + } + + private Kind getKind() { + return kinds[currentKindIndex]; + } + + boolean isInterface() { + return getKind().isInterface; + } + + boolean isClass() { + return !isInterface(); + } + + boolean hasDefault() { + return getKind() == IDEFAULT; + } + + public boolean isValid() { + for (TTNode n : supertypes) { + if (!n.isValid() || (isInterface() && n.isClass())) { + return false; + } + } + return true; + } + + public ClassCase genCase() { + ClassCase subclass; + List ttintfs; + if (isClass() && !supertypes.isEmpty() && supertypes.get(0).isClass()) { + subclass = supertypes.get(0).genCase(); + ttintfs = supertypes.subList(1, supertypes.size()); + } else { + subclass = null; + ttintfs = supertypes; + } + List intfs = new ArrayList<>(); + for (TTNode node : ttintfs) { + intfs.add(node.genCase()); + } + return new ClassCase(getKind(), subclass, intfs); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/TTParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTParser.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.io.IOException; +import java.io.StringReader; + +import static java.lang.Character.isLetter; +import static java.lang.Character.isUpperCase; +import static java.lang.Character.isWhitespace; + +/** + * Parse a type template definition string + * + * input :: classDef + * classDef :: letter [ ( classDef* ) ] + * + * @author Robert Field + */ +public class TTParser extends StringReader { + + private Map letterMap = new HashMap<>(); + private char ch; + + private final String def; + + public TTParser(String s) { + super(s); + this.def = s; + } + + private void advance() throws IOException { + do { + ch = (char)read(); + } while (isWhitespace(ch)); + } + + public TTNode parse() { + try { + advance(); + return classDef(); + } catch (IOException t) { + throw new RuntimeException(t); + } + } + + private TTNode classDef() throws IOException { + if (!isLetter(ch)) { + if (ch == (char)-1) { + throw new IOException("Unexpected end of type template in " + def); + } else { + throw new IOException("Unexpected character in type template: " + (Character)ch + " in " + def); + } + } + char nodeCh = ch; + TTNode node = letterMap.get(nodeCh); + boolean canBeClass = isUpperCase(nodeCh); + advance(); + if (node == null) { + List subtypes = new ArrayList<>(); + if (ch == '(') { + advance(); + while (ch != ')') { + subtypes.add(classDef()); + } + advance(); + } + node = new TTNode(subtypes, canBeClass); + letterMap.put(nodeCh, node); + } + return node; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/fd/shapegen/TTShape.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/fd/shapegen/TTShape.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package shapegen; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * + * @author Robert Field + */ +public class TTShape { + + private final TTNode root; + private final TTNode[] nodes; + + TTShape(TTNode root) { + this.root = root; + Set subs = new HashSet<>(); + root.collectAllSubtypes(subs); + nodes = subs.toArray(new TTNode[subs.size()]); + } + + private List toCases(boolean includeClasses) { + List ccs = new ArrayList<>(); + root.start(includeClasses); + int i; + outer: + while (true) { + if (root.isValid()) { + ClassCase cc = root.genCase(); + //System.out.println(cc); + ccs.add(cc); + } + + i = 0; + do { + if (i >= nodes.length) { + break outer; + } + } while(!nodes[i++].next()); + } + return ccs; + } + + public static List allCases(boolean includeClasses) { + List ccs = new ArrayList<>(); + for (TTShape shape : SHAPES) { + ccs.addAll(shape.toCases(includeClasses)); + } + return ccs; + } + + public static TTShape parse(String s) { + return new TTShape(new TTParser(s).parse()); + } + + public static final TTShape[] SHAPES = new TTShape[] { + parse("a"), + parse("a(b)"), + parse("A(bb)"), + parse("A(B(d)c(d))"), + parse("A(b(c))"), + parse("A(B(cd)d)"), + parse("A(B(c)c)"), + parse("A(B(Ce)d(e))"), + parse("A(B(C)d(e))"), + parse("A(Bc(d))"), + parse("A(B(d)dc)"), + parse("A(B(dc)dc)"), + parse("A(B(c(d))d)"), + parse("A(B(C(d))d)"), + parse("A(B(C(e)d(e))e)"), + parse("A(B(c(d))c)"), + parse("A(B(dc(d))c)"), + parse("A(B(C(d))d)"), + }; + +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/separate/Separate.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/separate/Separate.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary smoke test for separate compilation of default methods + * @author Maurizio Cimadamore + * @compile -XDallowDefaultMethods pkg1/A.java + * @compile -XDallowDefaultMethods Separate.java + */ + +import pkg1.A; + +class Separate { + interface B extends A.I { + default void m() { A.m(this); } + } + + interface C extends A.I, B { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/separate/pkg1/A.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/separate/pkg1/A.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package pkg1; + +public class A { + public interface I { + default void m() { A.m(this); } + } + + public static void m(Object o) {} +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/defaultMethods/super/TestDefaultSuperCall.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,406 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Automatic test for checking correctness of default super/this resolution + */ + +import com.sun.source.util.JavacTask; +import java.net.URI; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import javax.tools.Diagnostic; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +public class TestDefaultSuperCall { + + static int checkCount = 0; + + enum InterfaceKind { + DEFAULT("interface A extends B { default void m() { } }"), + ABSTRACT("interface A extends B { void m(); }"), + NONE("interface A extends B { }"); + + String interfaceStr; + + InterfaceKind(String interfaceStr) { + this.interfaceStr = interfaceStr; + } + + boolean methodDefined() { + return this == DEFAULT; + } + } + + enum PruneKind { + NO_PRUNE("interface C { }"), + PRUNE("interface C extends A { }"); + + boolean methodDefined(InterfaceKind ik) { + return this == PRUNE && + ik.methodDefined(); + } + + String interfaceStr; + + PruneKind(String interfaceStr) { + this.interfaceStr = interfaceStr; + } + } + + enum QualifierKind { + DIRECT_1("C"), + DIRECT_2("A"), + INDIRECT("B"), + UNRELATED("E"), + ENCLOSING_1(null), + ENCLOSING_2(null); + + String qualifierStr; + + QualifierKind(String qualifierStr) { + this.qualifierStr = qualifierStr; + } + + String getQualifier(Shape sh) { + switch (this) { + case ENCLOSING_1: return sh.enclosingAt(0); + case ENCLOSING_2: return sh.enclosingAt(1); + default: + return qualifierStr; + } + } + + boolean isEnclosing() { + return this == ENCLOSING_1 || + this == ENCLOSING_2; + } + + boolean allowSuperCall(InterfaceKind ik, PruneKind pk) { + switch (this) { + case DIRECT_1: + return pk.methodDefined(ik); + case DIRECT_2: + return ik.methodDefined() && pk == PruneKind.NO_PRUNE; + default: + return false; + } + } + } + + enum ExprKind { + THIS("this"), + SUPER("super"); + + String exprStr; + + ExprKind(String exprStr) { + this.exprStr = exprStr; + } + } + + enum ElementKind { + INTERFACE("interface #N { #B }", true), + INTERFACE_EXTENDS("interface #N extends A, C { #B }", true), + CLASS("class #N { #B }", false), + CLASS_EXTENDS("abstract class #N implements A, C { #B }", false), + STATIC_CLASS("static class #N { #B }", true), + STATIC_CLASS_EXTENDS("abstract static class #N implements A, C { #B }", true), + ANON_CLASS("new Object() { #B };", false), + METHOD("void test() { #B }", false), + STATIC_METHOD("static void test() { #B }", true), + DEFAULT_METHOD("default void test() { #B }", false); + + String templateDecl; + boolean isStatic; + + ElementKind(String templateDecl, boolean isStatic) { + this.templateDecl = templateDecl; + this.isStatic = isStatic; + } + + boolean isClassDecl() { + switch(this) { + case METHOD: + case STATIC_METHOD: + case DEFAULT_METHOD: + return false; + default: + return true; + } + } + + boolean isAllowedEnclosing(ElementKind ek, boolean isTop) { + switch (this) { + case CLASS: + case CLASS_EXTENDS: + //class is implicitly static inside interface, so skip this combo + return ek.isClassDecl() && + ek != INTERFACE && ek != INTERFACE_EXTENDS; + case ANON_CLASS: + return !ek.isClassDecl(); + case METHOD: + return ek == CLASS || ek == CLASS_EXTENDS || + ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS || + ek == ANON_CLASS; + case INTERFACE: + case INTERFACE_EXTENDS: + case STATIC_CLASS: + case STATIC_CLASS_EXTENDS: + case STATIC_METHOD: + return (isTop && (ek == CLASS || ek == CLASS_EXTENDS)) || + ek == STATIC_CLASS || ek == STATIC_CLASS_EXTENDS; + case DEFAULT_METHOD: + return ek == INTERFACE || ek == INTERFACE_EXTENDS; + default: + throw new AssertionError("Bad enclosing element kind" + this); + } + } + + boolean isAllowedTop() { + switch (this) { + case CLASS: + case CLASS_EXTENDS: + case INTERFACE: + case INTERFACE_EXTENDS: + return true; + default: + return false; + } + } + + boolean hasSuper() { + return this == INTERFACE_EXTENDS || + this == STATIC_CLASS_EXTENDS || + this == CLASS_EXTENDS; + } + } + + static class Shape { + + String shapeStr; + List enclosingElements; + List enclosingNames; + List elementsWithMethod; + + Shape(ElementKind... elements) { + System.err.println("elements = " + Arrays.toString(elements)); + enclosingElements = new ArrayList<>(); + enclosingNames = new ArrayList<>(); + elementsWithMethod = new ArrayList<>(); + int count = 0; + String prevName = null; + for (ElementKind ek : elements) { + String name = "name"+count++; + if (ek.isStatic) { + enclosingElements = new ArrayList<>(); + enclosingNames = new ArrayList<>(); + } + if (ek.isClassDecl()) { + enclosingElements.add(ek); + enclosingNames.add(name); + } else { + elementsWithMethod.add(prevName); + } + String element = ek.templateDecl.replaceAll("#N", name); + shapeStr = shapeStr == null ? element : shapeStr.replaceAll("#B", element); + prevName = name; + } + } + + String getShape(QualifierKind qk, ExprKind ek) { + String methName = ek == ExprKind.THIS ? "test" : "m"; + String call = qk.getQualifier(this) + "." + ek.exprStr + "." + methName + "();"; + return shapeStr.replaceAll("#B", call); + } + + String enclosingAt(int index) { + return index < enclosingNames.size() ? enclosingNames.get(index) : "BAD"; + } + } + + public static void main(String... args) throws Exception { + + //create default shared JavaCompiler - reused across multiple compilations + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + + for (InterfaceKind ik : InterfaceKind.values()) { + for (PruneKind pk : PruneKind.values()) { + for (ElementKind ek1 : ElementKind.values()) { + if (!ek1.isAllowedTop()) continue; + for (ElementKind ek2 : ElementKind.values()) { + if (!ek2.isAllowedEnclosing(ek1, true)) continue; + for (ElementKind ek3 : ElementKind.values()) { + if (!ek3.isAllowedEnclosing(ek2, false)) continue; + for (ElementKind ek4 : ElementKind.values()) { + if (!ek4.isAllowedEnclosing(ek3, false)) continue; + for (ElementKind ek5 : ElementKind.values()) { + if (!ek5.isAllowedEnclosing(ek4, false) || ek5.isClassDecl()) continue; + for (QualifierKind qk : QualifierKind.values()) { + for (ExprKind ek : ExprKind.values()) { + new TestDefaultSuperCall(ik, pk, new Shape(ek1, ek2, ek3, ek4, ek5), qk, ek).run(comp, fm); + } + } + } + } + } + } + } + } + } + System.out.println("Total check executed: " + checkCount); + } + + InterfaceKind ik; + PruneKind pk; + Shape sh; + QualifierKind qk; + ExprKind ek; + JavaSource source; + DiagnosticChecker diagChecker; + + TestDefaultSuperCall(InterfaceKind ik, PruneKind pk, Shape sh, QualifierKind qk, ExprKind ek) { + this.ik = ik; + this.pk = pk; + this.sh = sh; + this.qk = qk; + this.ek = ek; + this.source = new JavaSource(); + this.diagChecker = new DiagnosticChecker(); + } + + class JavaSource extends SimpleJavaFileObject { + + String template = "interface E {}\n" + + "interface B { }\n" + + "#I\n" + + "#P\n" + + "#C"; + + String source; + + public JavaSource() { + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); + source = template.replaceAll("#I", ik.interfaceStr) + .replaceAll("#P", pk.interfaceStr) + .replaceAll("#C", sh.getShape(qk, ek)); + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + void run(JavaCompiler tool, StandardJavaFileManager fm) throws Exception { + JavacTask ct = (JavacTask)tool.getTask(null, fm, diagChecker, + Arrays.asList("-XDallowDefaultMethods"), null, Arrays.asList(source)); + try { + ct.analyze(); + } catch (Throwable ex) { + throw new AssertionError("Error thrown when analyzing the following source:\n" + source.getCharContent(true)); + } + check(); + } + + void check() { + boolean errorExpected = false; + + boolean badEnclosing = false; + boolean badThis = false; + boolean badSuper = false; + + if (qk == QualifierKind.ENCLOSING_1 && + sh.enclosingNames.size() < 1) { + errorExpected |= true; + badEnclosing = true; + } + + if (qk == QualifierKind.ENCLOSING_2 && + sh.enclosingNames.size() < 2) { + errorExpected |= true; + badEnclosing = true; + } + + if (ek == ExprKind.THIS) { + boolean found = false; + for (int i = 0; i < sh.enclosingElements.size(); i++) { + if (sh.enclosingElements.get(i) == ElementKind.ANON_CLASS) continue; + if (sh.enclosingNames.get(i).equals(qk.getQualifier(sh))) { + found = sh.elementsWithMethod.contains(sh.enclosingNames.get(i)); + break; + } + } + errorExpected |= !found; + if (!found) { + badThis = true; + } + } + + if (ek == ExprKind.SUPER) { + + int lastIdx = sh.enclosingElements.size() - 1; + boolean found = lastIdx == -1 ? false : + sh.enclosingElements.get(lastIdx).hasSuper() && qk.allowSuperCall(ik, pk); + + errorExpected |= !found; + if (!found) { + badSuper = true; + } + } + + checkCount++; + if (diagChecker.errorFound != errorExpected) { + throw new AssertionError("Problem when compiling source:\n" + source.getCharContent(true) + + "\nenclosingElems: " + sh.enclosingElements + + "\nenclosingNames: " + sh.enclosingNames + + "\nelementsWithMethod: " + sh.elementsWithMethod + + "\nbad encl: " + badEnclosing + + "\nbad this: " + badThis + + "\nbad super: " + badSuper + + "\nqual kind: " + qk + + "\nfound error: " + diagChecker.errorFound); + } + } + + static class DiagnosticChecker implements javax.tools.DiagnosticListener { + + boolean errorFound; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + System.err.println(diagnostic.getMessage(Locale.getDefault())); + errorFound = true; + } + } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/CheckResourceKeys.java --- a/langtools/test/tools/javac/diags/CheckResourceKeys.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/diags/CheckResourceKeys.java Fri Nov 09 14:47:22 2012 -0800 @@ -310,9 +310,8 @@ pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { String name = fo.getName(); // ignore resource files, and files which are not really part of javac - if (name.contains("resources") - || name.contains("Launcher.class") - || name.contains("CreateSymbols.class")) + if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*") + || name.matches(".*CreateSymbols\\.class.*")) continue; scan(fo, results); } diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/CatchWithoutTry.java --- a/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/diags/examples/CatchWithoutTry.java Fri Nov 09 14:47:22 2012 -0800 @@ -22,9 +22,6 @@ */ // key: compiler.err.catch.without.try -// key: compiler.err.expected -// key: compiler.err.not.stmt -// key: compiler.err.lambda.not.supported.in.source class CatchWithoutTry { void m() { diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/DefaultOverridesObjectMember.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/DefaultOverridesObjectMember.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.default.overrides.object.member +// options: -XDallowDefaultMethods + +interface DefaultOverridesObjectMember { + default String toString() { return ""; } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/OverriddenDefault.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/OverriddenDefault.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.illegal.default.super.call +// key: compiler.misc.overridden.default +// options: -XDallowDefaultMethods + +class OverriddenDefault { + interface I { default void m() { } } + interface J extends I { default void m() { } } + interface K extends I {} + + static class C implements J, K { + void foo() { K.super.m(); } + } +} \ No newline at end of file diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/RedundantSupertype.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/RedundantSupertype.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.illegal.default.super.call +// key: compiler.misc.redundant.supertype +// options: -XDallowDefaultMethods + +class RedundantSupertype { + interface I { default void m() { } } + interface J extends I { default void m() { } } + + static class C implements I, J { + void foo() { I.super.m(); } + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/TypesIncompatibleAbstractDefault.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleAbstractDefault.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.types.incompatible.abstract.default +// options: -XDallowDefaultMethods + +class TypesIncompatibleAbstractDefault { + interface A { + default void m() { } + } + + interface B { + void m(); + } + + interface AB extends A, B { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/diags/examples/TypesIncompatibleUnrelatedDefaults.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/diags/examples/TypesIncompatibleUnrelatedDefaults.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// key: compiler.err.types.incompatible.unrelated.defaults +// options: -XDallowDefaultMethods + +class TypesIncompatibleUnrelatedDefaults { + interface A { + default void m() { } + } + + interface B { + default void m() { } + } + + interface AB extends A, B { } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/generics/7022054/T7022054pos1.java --- a/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/generics/7022054/T7022054pos1.java Fri Nov 09 14:47:22 2012 -0800 @@ -26,7 +26,8 @@ * @bug 7022054 * * @summary Invalid compiler error on covariant overriding methods with the same erasure - * @compile T7022054pos1.java + * @compile -source 7 T7022054pos1.java + * @compile/fail -XDstrictMethodClashCheck T7022054pos1.java * */ diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/generics/7022054/T7022054pos2.java --- a/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/generics/7022054/T7022054pos2.java Fri Nov 09 14:47:22 2012 -0800 @@ -26,8 +26,8 @@ * @bug 7022054 * * @summary Invalid compiler error on covariant overriding methods with the same erasure - * @compile T7022054pos2.java - * + * @compile -source 7 T7022054pos2.java + * @compile/fail -XDstrictMethodClashCheck T7022054pos2.java */ class T7022054pos2 { diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/generics/inference/6611449/T6611449.out --- a/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/generics/inference/6611449/T6611449.out Fri Nov 09 14:47:22 2012 -0800 @@ -1,5 +1,5 @@ -T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))} -T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.infer.arg.length.mismatch: T))} +T6611449.java:18:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.infer.arg.length.mismatch: T))} +T6611449.java:19:9: compiler.err.cant.apply.symbols: kindname.constructor, T6611449, int,int,{(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T), (compiler.misc.infer.arg.length.mismatch: T)),(compiler.misc.inapplicable.method: kindname.constructor, T6611449, T6611449(T,T), (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S))} T6611449.java:20:9: compiler.err.cant.apply.symbol: kindname.method, m1, T, int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S) T6611449.java:21:9: compiler.err.cant.apply.symbol: kindname.method, m2, T,T, int,int, kindname.class, T6611449, (compiler.misc.inferred.do.not.conform.to.upper.bounds: java.lang.Integer, S) 4 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/generics/inference/7086601/T7086601a.out --- a/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/generics/inference/7086601/T7086601a.out Fri Nov 09 14:47:22 2012 -0800 @@ -1,5 +1,5 @@ -T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Iterable,java.lang.Iterable), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))} -T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable,java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Iterable,java.lang.Iterable,java.lang.Iterable), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))} -T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Iterable...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object))} -T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable,java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Iterable...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object))} +T7086601a.java:20:9: compiler.err.cant.apply.symbols: kindname.method, m1, java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Iterable,java.lang.Iterable), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m1(java.lang.Object), (compiler.misc.arg.length.mismatch))} +T7086601a.java:24:9: compiler.err.cant.apply.symbols: kindname.method, m2, java.lang.Iterable,java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Iterable,java.lang.Iterable,java.lang.Iterable), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m2(java.lang.Object), (compiler.misc.arg.length.mismatch))} +T7086601a.java:28:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Iterable...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch))} +T7086601a.java:32:9: compiler.err.cant.apply.symbols: kindname.method, m3, java.lang.Iterable,java.lang.Iterable,java.lang.Iterable,{(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Iterable...), (compiler.misc.incompatible.upper.bounds: S, java.lang.Double,java.lang.Integer,java.lang.String,java.lang.Object)),(compiler.misc.inapplicable.method: kindname.method, T7086601, m3(java.lang.Object), (compiler.misc.arg.length.mismatch))} 4 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/incompleteStatements/T8000484.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/incompleteStatements/T8000484.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,17 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8000484 + * @summary Bad error recovery when 'catch' without 'try' is found + * @compile/fail/ref=T8000484.out -XDrawDiagnostics T8000484.java + */ + +public class T8000484 { + void m() { + catch (Exception e){} + else{} + finally{} + catch (Exception e) {catch (Exception e){}} + else{else{}} + finally{finally{}} + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/incompleteStatements/T8000484.out --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/incompleteStatements/T8000484.out Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,10 @@ +T8000484.java:10:9: compiler.err.catch.without.try +T8000484.java:11:9: compiler.err.else.without.if +T8000484.java:12:9: compiler.err.finally.without.try +T8000484.java:13:30: compiler.err.catch.without.try +T8000484.java:13:9: compiler.err.catch.without.try +T8000484.java:14:14: compiler.err.else.without.if +T8000484.java:14:9: compiler.err.else.without.if +T8000484.java:15:17: compiler.err.finally.without.try +T8000484.java:15:9: compiler.err.finally.without.try +9 errors diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/options/T6949443.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/options/T6949443.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 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 6949443 + * @summary VisitTree assertion triggered using -Xjcov on small sample program + * @compile -Xjcov T6949443.java + */ + +public class T6949443 { + public static void main(String[] args) { + Integer i = 0; + i++; + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/resolve/tests/AmbiguityPrecedence.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javac/resolve/tests/AmbiguityPrecedence.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,45 @@ +/* + * 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. + */ + +@TraceResolve(keys={"compiler.err.ref.ambiguous"}) +class AmbiguityPrecedence { + + @Candidate(applicable=Phase.BASIC) + static void m1(long l, int i) {} + @Candidate(applicable=Phase.BASIC) + static void m1(int i, long l) {} + @Candidate + static void m1(Integer i1, Integer i2) {} + + @Candidate(applicable=Phase.BOX) + static void m2(Object o, Integer i) {} + @Candidate(applicable=Phase.BOX) + static void m2(Integer i, Object o) {} + @Candidate + static void m2(Integer... o) {} + + { + m1(1, 1); + m2(1, 1); + } +} diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java --- a/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/scope/7046348/EagerInterfaceCompletionTest.java Fri Nov 09 14:47:22 2012 -0800 @@ -30,6 +30,7 @@ import java.io.File; import java.net.URI; import java.util.Arrays; +import java.util.List; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; @@ -43,13 +44,15 @@ JavaCompiler javacTool; File testDir; + VersionKind versionKind; HierarchyKind hierarchyKind; TestKind testKind; ActionKind actionKind; - EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir, + EagerInterfaceCompletionTest(JavaCompiler javacTool, File testDir, VersionKind versionKind, HierarchyKind hierarchyKind, TestKind testKind, ActionKind actionKind) { this.javacTool = javacTool; + this.versionKind = versionKind; this.hierarchyKind = hierarchyKind; this.testDir = testDir; this.testKind = testKind; @@ -62,7 +65,7 @@ actionKind.doAction(this); DiagnosticChecker dc = new DiagnosticChecker(); compile(dc, testKind.source); - if (testKind.completionFailure(actionKind, hierarchyKind) != dc.errorFound) { + if (testKind.completionFailure(versionKind, actionKind, hierarchyKind) != dc.errorFound) { if (dc.errorFound) { error("Unexpected completion failure" + "\nhierarhcyKind " + hierarchyKind + @@ -80,7 +83,8 @@ void compile(DiagnosticChecker dc, JavaSource... sources) { try { CompilationTask ct = javacTool.getTask(null, null, dc, - Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", testDir.getAbsolutePath()), + Arrays.asList("-d", testDir.getAbsolutePath(), "-cp", + testDir.getAbsolutePath(), versionKind.optsArr[0], versionKind.optsArr[1]), null, Arrays.asList(sources)); ct.call(); } @@ -108,12 +112,25 @@ boolean errorFound = false; public void report(Diagnostic diagnostic) { - errorFound = true; + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + errorFound = true; + } } } //global declarations + enum VersionKind { + PRE_LAMBDA("-source", "7"), + LAMBDA("-source", "8"); + + String[] optsArr; + + VersionKind(String... optsArr) { + this.optsArr = optsArr; + } + } + enum HierarchyKind { INTERFACE("interface A { boolean f = false; void m(); }\n" + "class B implements A { public void m() {} }"), @@ -157,13 +174,14 @@ this.source = new JavaSource("Test2.java", code); } - boolean completionFailure(ActionKind ak, HierarchyKind hk) { + boolean completionFailure(VersionKind vk, ActionKind ak, HierarchyKind hk) { switch (this) { case ACCESS_ONLY: case CONSTR: return ak == ActionKind.REMOVE_B; case FIELD: case SUPER: return true; - case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B; + case METHOD: return hk != HierarchyKind.INTERFACE || ak == ActionKind.REMOVE_B || + (hk == HierarchyKind.INTERFACE && ak == ActionKind.REMOVE_A && vk == VersionKind.LAMBDA); default: throw new AssertionError("Unexpected test kind " + this); } } @@ -173,12 +191,15 @@ String SCRATCH_DIR = System.getProperty("user.dir"); JavaCompiler javacTool = ToolProvider.getSystemJavaCompiler(); int n = 0; - for (HierarchyKind hierarchyKind : HierarchyKind.values()) { - for (TestKind testKind : TestKind.values()) { - for (ActionKind actionKind : ActionKind.values()) { - File testDir = new File(SCRATCH_DIR, "test"+n); - new EagerInterfaceCompletionTest(javacTool, testDir, hierarchyKind, testKind, actionKind).test(); - n++; + for (VersionKind versionKind : VersionKind.values()) { + for (HierarchyKind hierarchyKind : HierarchyKind.values()) { + for (TestKind testKind : TestKind.values()) { + for (ActionKind actionKind : ActionKind.values()) { + File testDir = new File(SCRATCH_DIR, "test"+n); + new EagerInterfaceCompletionTest(javacTool, testDir, versionKind, + hierarchyKind, testKind, actionKind).test(); + n++; + } } } } diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javac/versions/check.sh --- a/langtools/test/tools/javac/versions/check.sh Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javac/versions/check.sh Fri Nov 09 14:47:22 2012 -0800 @@ -1,5 +1,5 @@ # -# Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2004, 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 @@ -22,7 +22,7 @@ # # @test -# @bug 4981566 5028634 5094412 6304984 7025786 7025789 +# @bug 4981566 5028634 5094412 6304984 7025786 7025789 8001112 # @summary Check interpretation of -target and -source options # @build CheckClassFileVersion # @run shell check.sh @@ -47,32 +47,39 @@ "$JC" ${TESTTOOLVMOPTS} -d $TC $* $TC/X.java && "$J" $CFV $TC/X.class $V || exit 2 } +# check for all combinations of target values +check_target() { + check $1 -source $2 -target $3 + check $1 -source $2 -target 1.${3} +} +# check for all combinations of source and target values +check_source_target() { + check_target $1 $2 $3 + check_target $1 1.${2} $3 +} + check 48.0 -source 1.4 check 49.0 -source 1.4 -target 1.5 check 49.0 -source 1.5 -target 1.5 -check 50.0 -source 1.4 -target 1.6 -check 50.0 -source 1.5 -target 1.6 -check 50.0 -source 1.6 -target 1.6 -check 50.0 -source 1.6 -target 6 -check 50.0 -source 6 -target 1.6 -check 50.0 -source 6 -target 6 +check_target 50.0 1.4 6 +check_target 50.0 1.5 6 +check_source_target 50.0 6 6 + +check_target 51.0 1.4 7 +check_target 51.0 1.5 7 +check_source_target 51.0 6 7 +check_source_target 51.0 7 7 -check 51.0 -check 51.0 -source 1.5 -check 51.0 -source 1.6 -check 51.0 -source 6 -check 51.0 -source 1.7 -check 51.0 -source 7 -check 51.0 -source 7 -target 1.7 -check 51.0 -source 7 -target 7 +check_target 52.0 1.4 8 +check_target 52.0 1.5 8 +check_source_target 52.0 6 8 +check_source_target 52.0 7 8 +check_source_target 52.0 8 8 -# Update when class file version is revved -check 51.0 -source 1.8 -check 51.0 -source 8 -check 51.0 -target 1.8 -check 51.0 -target 8 +# and finally the default with no options +check 52.0 # Check source versions diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javadoc/6958836/Test.java --- a/langtools/test/tools/javadoc/6958836/Test.java Thu Nov 08 11:53:23 2012 -0800 +++ b/langtools/test/tools/javadoc/6958836/Test.java Fri Nov 09 14:47:22 2012 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -23,7 +23,7 @@ /* * @test - * @bug 6958836 + * @bug 6958836 8002168 * @summary javadoc should support -Xmaxerrs and -Xmaxwarns */ diff -r 1833592bde35 -r 0e685b019743 langtools/test/tools/javadoc/CheckResourceKeys.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/langtools/test/tools/javadoc/CheckResourceKeys.java Fri Nov 09 14:47:22 2012 -0800 @@ -0,0 +1,240 @@ +/* + * Copyright (c) 2010, 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 8000612 + * @summary need test program to validate javadoc resource bundles + */ + +import java.io.*; +import java.util.*; +import javax.tools.*; +import com.sun.tools.classfile.*; + +/** + * Compare string constants in javadoc classes against keys in javadoc resource bundles. + */ +public class CheckResourceKeys { + /** + * Main program. + * Options: + * -finddeadkeys + * look for keys in resource bundles that are no longer required + * -findmissingkeys + * look for keys in resource bundles that are missing + * + * @throws Exception if invoked by jtreg and errors occur + */ + public static void main(String... args) throws Exception { + CheckResourceKeys c = new CheckResourceKeys(); + if (c.run(args)) + return; + + if (is_jtreg()) + throw new Exception(c.errors + " errors occurred"); + else + System.exit(1); + } + + static boolean is_jtreg() { + return (System.getProperty("test.src") != null); + } + + /** + * Main entry point. + */ + boolean run(String... args) throws Exception { + boolean findDeadKeys = false; + boolean findMissingKeys = false; + + if (args.length == 0) { + if (is_jtreg()) { + findDeadKeys = true; + findMissingKeys = true; + } else { + System.err.println("Usage: java CheckResourceKeys "); + System.err.println("where options include"); + System.err.println(" -finddeadkeys find keys in resource bundles which are no longer required"); + System.err.println(" -findmissingkeys find keys in resource bundles that are required but missing"); + return true; + } + } else { + for (String arg: args) { + if (arg.equalsIgnoreCase("-finddeadkeys")) + findDeadKeys = true; + else if (arg.equalsIgnoreCase("-findmissingkeys")) + findMissingKeys = true; + else + error("bad option: " + arg); + } + } + + if (errors > 0) + return false; + + Set codeKeys = getCodeKeys(); + Set resourceKeys = getResourceKeys(); + + System.err.println("found " + codeKeys.size() + " keys in code"); + System.err.println("found " + resourceKeys.size() + " keys in resource bundles"); + + if (findDeadKeys) + findDeadKeys(codeKeys, resourceKeys); + + if (findMissingKeys) + findMissingKeys(codeKeys, resourceKeys); + + return (errors == 0); + } + + /** + * Find keys in resource bundles which are probably no longer required. + * A key is required if there is a string in the code that is a resource key, + * or if the key is well-known according to various pragmatic rules. + */ + void findDeadKeys(Set codeKeys, Set resourceKeys) { + for (String rk: resourceKeys) { + if (codeKeys.contains(rk)) + continue; + + error("Resource key not found in code: " + rk); + } + } + + /** + * For all strings in the code that look like they might be + * a resource key, verify that a key exists. + */ + void findMissingKeys(Set codeKeys, Set resourceKeys) { + for (String ck: codeKeys) { + if (resourceKeys.contains(ck)) + continue; + error("No resource for \"" + ck + "\""); + } + } + + /** + * Get the set of strings from (most of) the javadoc classfiles. + */ + Set getCodeKeys() throws IOException { + Set results = new TreeSet(); + JavaCompiler c = ToolProvider.getSystemJavaCompiler(); + JavaFileManager fm = c.getStandardFileManager(null, null, null); + JavaFileManager.Location javadocLoc = findJavadocLocation(fm); + String[] pkgs = { + "com.sun.tools.doclets", + "com.sun.tools.javadoc" + }; + for (String pkg: pkgs) { + for (JavaFileObject fo: fm.list(javadocLoc, + pkg, EnumSet.of(JavaFileObject.Kind.CLASS), true)) { + String name = fo.getName(); + // ignore resource files + if (name.matches(".*resources.[A-Za-z_0-9]+\\.class.*")) + continue; + scan(fo, results); + } + } + + // special handling for code strings synthesized in + // com.sun.tools.doclets.internal.toolkit.util.Util.getTypeName + String[] extras = { + "AnnotationType", "Class", "Enum", "Error", "Exception", "Interface" + }; + for (String s: extras) { + if (results.contains("doclet." + s)) + results.add("doclet." + s.toLowerCase()); + } + + return results; + } + + // depending on how the test is run, javadoc may be on bootclasspath or classpath + JavaFileManager.Location findJavadocLocation(JavaFileManager fm) { + JavaFileManager.Location[] locns = + { StandardLocation.PLATFORM_CLASS_PATH, StandardLocation.CLASS_PATH }; + try { + for (JavaFileManager.Location l: locns) { + JavaFileObject fo = fm.getJavaFileForInput(l, + "com.sun.tools.javadoc.Main", JavaFileObject.Kind.CLASS); + if (fo != null) { + System.err.println("found javadoc in " + l); + return l; + } + } + } catch (IOException e) { + throw new Error(e); + } + throw new IllegalStateException("Cannot find javadoc"); + } + + /** + * Get the set of strings from a class file. + * Only strings that look like they might be a resource key are returned. + */ + void scan(JavaFileObject fo, Set results) throws IOException { + //System.err.println("scan " + fo.getName()); + InputStream in = fo.openInputStream(); + try { + ClassFile cf = ClassFile.read(in); + for (ConstantPool.CPInfo cpinfo: cf.constant_pool.entries()) { + if (cpinfo.getTag() == ConstantPool.CONSTANT_Utf8) { + String v = ((ConstantPool.CONSTANT_Utf8_info) cpinfo).value; + if (v.matches("(doclet|main|javadoc|tag)\\.[A-Za-z0-9-_.]+")) + results.add(v); + } + } + } catch (ConstantPoolException ignore) { + } finally { + in.close(); + } + } + + /** + * Get the set of keys from the javadoc resource bundles. + */ + Set getResourceKeys() { + String[] names = { + "com.sun.tools.doclets.formats.html.resources.standard", + "com.sun.tools.doclets.internal.toolkit.resources.doclets", + "com.sun.tools.javadoc.resources.javadoc", + }; + Set results = new TreeSet(); + for (String name : names) { + ResourceBundle b = ResourceBundle.getBundle(name); + results.addAll(b.keySet()); + } + return results; + } + + /** + * Report an error. + */ + void error(String msg) { + System.err.println("Error: " + msg); + errors++; + } + + int errors; +}