30 import javax.tools.JavaFileManager; |
30 import javax.tools.JavaFileManager; |
31 |
31 |
32 import com.sun.tools.javac.code.*; |
32 import com.sun.tools.javac.code.*; |
33 import com.sun.tools.javac.code.Attribute.Compound; |
33 import com.sun.tools.javac.code.Attribute.Compound; |
34 import com.sun.tools.javac.jvm.*; |
34 import com.sun.tools.javac.jvm.*; |
|
35 import com.sun.tools.javac.resources.CompilerProperties.Errors; |
|
36 import com.sun.tools.javac.resources.CompilerProperties.Fragments; |
35 import com.sun.tools.javac.tree.*; |
37 import com.sun.tools.javac.tree.*; |
36 import com.sun.tools.javac.util.*; |
38 import com.sun.tools.javac.util.*; |
37 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
39 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition; |
38 import com.sun.tools.javac.util.List; |
40 import com.sun.tools.javac.util.List; |
39 |
41 |
82 private final JCDiagnostic.Factory diags; |
84 private final JCDiagnostic.Factory diags; |
83 private boolean warnOnSyntheticConflicts; |
85 private boolean warnOnSyntheticConflicts; |
84 private boolean suppressAbortOnBadClassFile; |
86 private boolean suppressAbortOnBadClassFile; |
85 private boolean enableSunApiLintControl; |
87 private boolean enableSunApiLintControl; |
86 private final JavaFileManager fileManager; |
88 private final JavaFileManager fileManager; |
|
89 private final Source source; |
87 private final Profile profile; |
90 private final Profile profile; |
88 private final boolean warnOnAccessToSensitiveMembers; |
91 private final boolean warnOnAccessToSensitiveMembers; |
89 |
92 |
90 // The set of lint options currently in effect. It is initialized |
93 // The set of lint options currently in effect. It is initialized |
91 // from the context, and then is set/reset as needed by Attr as it |
94 // from the context, and then is set/reset as needed by Attr as it |
120 diags = JCDiagnostic.Factory.instance(context); |
123 diags = JCDiagnostic.Factory.instance(context); |
121 Options options = Options.instance(context); |
124 Options options = Options.instance(context); |
122 lint = Lint.instance(context); |
125 lint = Lint.instance(context); |
123 fileManager = context.get(JavaFileManager.class); |
126 fileManager = context.get(JavaFileManager.class); |
124 |
127 |
125 Source source = Source.instance(context); |
128 source = Source.instance(context); |
126 allowSimplifiedVarargs = source.allowSimplifiedVarargs(); |
129 allowSimplifiedVarargs = source.allowSimplifiedVarargs(); |
127 allowDefaultMethods = source.allowDefaultMethods(); |
130 allowDefaultMethods = source.allowDefaultMethods(); |
128 allowStrictMethodClashCheck = source.allowStrictMethodClashCheck(); |
131 allowStrictMethodClashCheck = source.allowStrictMethodClashCheck(); |
129 allowPrivateSafeVarargs = source.allowPrivateSafeVarargs(); |
132 allowPrivateSafeVarargs = source.allowPrivateSafeVarargs(); |
|
133 allowDiamondWithAnonymousClassCreation = source.allowDiamondWithAnonymousClassCreation(); |
130 complexInference = options.isSet("complexinference"); |
134 complexInference = options.isSet("complexinference"); |
131 warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); |
135 warnOnSyntheticConflicts = options.isSet("warnOnSyntheticConflicts"); |
132 suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); |
136 suppressAbortOnBadClassFile = options.isSet("suppressAbortOnBadClassFile"); |
133 enableSunApiLintControl = options.isSet("enableSunApiLintControl"); |
137 enableSunApiLintControl = options.isSet("enableSunApiLintControl"); |
134 warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers"); |
138 warnOnAccessToSensitiveMembers = options.isSet("warnOnAccessToSensitiveMembers"); |
166 boolean allowStrictMethodClashCheck; |
170 boolean allowStrictMethodClashCheck; |
167 |
171 |
168 /** Switch: can the @SafeVarargs annotation be applied to private methods? |
172 /** Switch: can the @SafeVarargs annotation be applied to private methods? |
169 */ |
173 */ |
170 boolean allowPrivateSafeVarargs; |
174 boolean allowPrivateSafeVarargs; |
|
175 |
|
176 /** Switch: can diamond inference be used in anonymous instance creation ? |
|
177 */ |
|
178 boolean allowDiamondWithAnonymousClassCreation; |
171 |
179 |
172 /** Switch: -complexinference option set? |
180 /** Switch: -complexinference option set? |
173 */ |
181 */ |
174 boolean complexInference; |
182 boolean complexInference; |
175 |
183 |
771 */ |
779 */ |
772 Type checkDiamond(JCNewClass tree, Type t) { |
780 Type checkDiamond(JCNewClass tree, Type t) { |
773 if (!TreeInfo.isDiamond(tree) || |
781 if (!TreeInfo.isDiamond(tree) || |
774 t.isErroneous()) { |
782 t.isErroneous()) { |
775 return checkClassType(tree.clazz.pos(), t, true); |
783 return checkClassType(tree.clazz.pos(), t, true); |
776 } else if (tree.def != null) { |
784 } else if (tree.def != null && !allowDiamondWithAnonymousClassCreation) { |
777 log.error(tree.clazz.pos(), |
785 log.error(tree.clazz.pos(), |
778 "cant.apply.diamond.1", |
786 Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name))); |
779 t, diags.fragment("diamond.and.anon.class", t)); |
|
780 return types.createErrorType(t); |
787 return types.createErrorType(t); |
781 } else if (t.tsym.type.getTypeArguments().isEmpty()) { |
788 } else if (t.tsym.type.getTypeArguments().isEmpty()) { |
782 log.error(tree.clazz.pos(), |
789 log.error(tree.clazz.pos(), |
783 "cant.apply.diamond.1", |
790 "cant.apply.diamond.1", |
784 t, diags.fragment("diamond.non.generic", t)); |
791 t, diags.fragment("diamond.non.generic", t)); |
791 return types.createErrorType(t); |
798 return types.createErrorType(t); |
792 } else { |
799 } else { |
793 return t; |
800 return t; |
794 } |
801 } |
795 } |
802 } |
|
803 |
|
804 /** Check that the type inferred using the diamond operator does not contain |
|
805 * non-denotable types such as captured types or intersection types. |
|
806 * @param t the type inferred using the diamond operator |
|
807 * @return the (possibly empty) list of non-denotable types. |
|
808 */ |
|
809 List<Type> checkDiamondDenotable(ClassType t) { |
|
810 ListBuffer<Type> buf = new ListBuffer<>(); |
|
811 for (Type arg : t.getTypeArguments()) { |
|
812 if (!diamondTypeChecker.visit(arg, null)) { |
|
813 buf.append(arg); |
|
814 } |
|
815 } |
|
816 return buf.toList(); |
|
817 } |
|
818 // where |
|
819 |
|
820 /** diamondTypeChecker: A type visitor that descends down the given type looking for non-denotable |
|
821 * types. The visit methods return false as soon as a non-denotable type is encountered and true |
|
822 * otherwise. |
|
823 */ |
|
824 private static final Types.SimpleVisitor<Boolean, Void> diamondTypeChecker = new Types.SimpleVisitor<Boolean, Void>() { |
|
825 @Override |
|
826 public Boolean visitType(Type t, Void s) { |
|
827 return true; |
|
828 } |
|
829 @Override |
|
830 public Boolean visitClassType(ClassType t, Void s) { |
|
831 if (t.isCompound()) { |
|
832 return false; |
|
833 } |
|
834 for (Type targ : t.getTypeArguments()) { |
|
835 if (!visit(targ, s)) { |
|
836 return false; |
|
837 } |
|
838 } |
|
839 return true; |
|
840 } |
|
841 @Override |
|
842 public Boolean visitCapturedType(CapturedType t, Void s) { |
|
843 return false; |
|
844 } |
|
845 |
|
846 @Override |
|
847 public Boolean visitArrayType(ArrayType t, Void s) { |
|
848 return visit(t.elemtype, s); |
|
849 } |
|
850 |
|
851 @Override |
|
852 public Boolean visitWildcardType(WildcardType t, Void s) { |
|
853 return visit(t.type, s); |
|
854 } |
|
855 }; |
796 |
856 |
797 void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) { |
857 void checkVarargsMethodDecl(Env<AttrContext> env, JCMethodDecl tree) { |
798 MethodSymbol m = tree.sym; |
858 MethodSymbol m = tree.sym; |
799 if (!allowSimplifiedVarargs) return; |
859 if (!allowSimplifiedVarargs) return; |
800 boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null; |
860 boolean hasTrustMeAnno = m.attribute(syms.trustMeType.tsym) != null; |
1915 /** Check that a given method conforms with any method it overrides. |
1975 /** Check that a given method conforms with any method it overrides. |
1916 * @param tree The tree from which positions are extracted |
1976 * @param tree The tree from which positions are extracted |
1917 * for errors. |
1977 * for errors. |
1918 * @param m The overriding method. |
1978 * @param m The overriding method. |
1919 */ |
1979 */ |
1920 void checkOverride(JCMethodDecl tree, MethodSymbol m) { |
1980 void checkOverride(Env<AttrContext> env, JCMethodDecl tree, MethodSymbol m) { |
1921 ClassSymbol origin = (ClassSymbol)m.owner; |
1981 ClassSymbol origin = (ClassSymbol)m.owner; |
1922 if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) |
1982 if ((origin.flags() & ENUM) != 0 && names.finalize.equals(m.name)) |
1923 if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { |
1983 if (m.overrides(syms.enumFinalFinalize, origin, types, false)) { |
1924 log.error(tree.pos(), "enum.no.finalize"); |
1984 log.error(tree.pos(), "enum.no.finalize"); |
1925 return; |
1985 return; |
1932 for (Type t2 : types.interfaces(t)) { |
1992 for (Type t2 : types.interfaces(t)) { |
1933 checkOverride(tree, t2, origin, m); |
1993 checkOverride(tree, t2, origin, m); |
1934 } |
1994 } |
1935 } |
1995 } |
1936 |
1996 |
1937 if (m.attribute(syms.overrideType.tsym) != null && !isOverrider(m)) { |
1997 // Check if this method must override a super method due to being annotated with @Override |
|
1998 // or by virtue of being a member of a diamond inferred anonymous class. Latter case is to |
|
1999 // be treated "as if as they were annotated" with @Override. |
|
2000 boolean mustOverride = m.attribute(syms.overrideType.tsym) != null || |
|
2001 (env.info.isAnonymousDiamond && !m.isConstructor() && !m.isPrivate()); |
|
2002 if (mustOverride && !isOverrider(m)) { |
1938 DiagnosticPosition pos = tree.pos(); |
2003 DiagnosticPosition pos = tree.pos(); |
1939 for (JCAnnotation a : tree.getModifiers().annotations) { |
2004 for (JCAnnotation a : tree.getModifiers().annotations) { |
1940 if (a.annotationType.type.tsym == syms.overrideType.tsym) { |
2005 if (a.annotationType.type.tsym == syms.overrideType.tsym) { |
1941 pos = a.pos(); |
2006 pos = a.pos(); |
1942 break; |
2007 break; |