1818import com .sun .tools .javac .code .Source ;
1919import com .sun .tools .javac .resources .CompilerProperties ;
2020import com .sun .tools .javac .util .JCDiagnostic ;
21+ import java .lang .reflect .Method ;
22+ import java .lang .reflect .Modifier ;
23+ import java .util .Arrays ;
2124import java .util .Collections ;
2225import java .util .HashMap ;
2326import java .util .HashSet ;
2427import java .util .Map ;
2528import java .util .Set ;
29+ import java .util .function .Consumer ;
30+ import java .util .logging .Level ;
31+ import java .util .logging .Logger ;
2632
2733class JavaLangFeatures {
34+ private static final Logger LOG = Logger .getLogger (JavaLangFeatures .class .getName ());
2835
2936 public static boolean isDiagnosticForUnsupportedFeatures (String diagnosticCode ) {
3037 return Singleton .javacParentDiagnosticKeys .contains (diagnosticCode );
@@ -47,45 +54,98 @@ private static class Singleton {
4754 static {
4855 Map <String , Source .Feature > featureFragments = new HashMap <>();
4956 Set <String > parentDiagnosticKeys = new HashSet <>();
50- String prefix = "compiler.misc." ;
57+ String prefix = null ;
5158 try {
52- final JCDiagnostic .Fragment fragment = CompilerProperties .Fragments .FeatureNotSupportedInSource ((JCDiagnostic ) null , null , null );
53- final String fragmentKey = fragment .key ();
54- final String fragmentCode = fragment .getCode ();
55- if (fragmentKey .startsWith (fragmentCode )) {
56- prefix = fragmentKey .substring (fragmentCode .length ());
57- }
58-
59- parentDiagnosticKeys .add (fragmentKey );
60- parentDiagnosticKeys .add (CompilerProperties .Fragments .FeatureNotSupportedInSourcePlural ((JCDiagnostic ) null , null , null ).key ());
61- parentDiagnosticKeys .add (CompilerProperties .Errors .FeatureNotSupportedInSource ((JCDiagnostic ) null , null , null ).key ());
62- parentDiagnosticKeys .add (CompilerProperties .Errors .FeatureNotSupportedInSourcePlural ((JCDiagnostic ) null , null , null ).key ());
63-
64- parentDiagnosticKeys .add (CompilerProperties .Errors .PreviewFeatureDisabled ((JCDiagnostic ) null ).key ());
65- parentDiagnosticKeys .add (CompilerProperties .Errors .PreviewFeatureDisabledPlural ((JCDiagnostic ) null ).key ());
66- parentDiagnosticKeys .add (CompilerProperties .Warnings .PreviewFeatureUse ((JCDiagnostic ) null ).key ());
67- parentDiagnosticKeys .add (CompilerProperties .Warnings .PreviewFeatureUsePlural ((JCDiagnostic ) null ).key ());
68-
69- parentDiagnosticKeys .add (CompilerProperties .Errors .IsPreview (null ).key ());
70- parentDiagnosticKeys .add (CompilerProperties .Warnings .IsPreview (null ).key ());
71- parentDiagnosticKeys .add (CompilerProperties .Warnings .IsPreviewReflective (null ).key ());
72-
7359 for (Source .Feature f : Source .Feature .values ()) {
7460 try {
75- featureFragments .put (f .nameFragment ().getCode (), f );
61+ JCDiagnostic .Fragment nameFragment = f .nameFragment ();
62+ featureFragments .put (nameFragment .getCode (), f );
63+
64+ if (prefix == null ) {
65+ final String fragmentKey = nameFragment .key ();
66+ final String fragmentCode = nameFragment .getCode ();
67+ if (fragmentCode .length () > 0 && fragmentKey .endsWith (fragmentCode )) {
68+ prefix = fragmentKey .substring (0 , fragmentKey .length () - fragmentCode .length ());
69+ }
70+ }
7671 } catch (AssertionError | NullPointerException e ) {
7772 // In case no error message code has been registered; for example: LOCAL_VARIABLE_TYPE_INFERENCE
7873 featureFragments .put (f .name (), f );
7974 }
8075 }
76+
77+ Set <String > diagnosticMethodNames = new HashSet <>(Arrays .asList (
78+ "FeatureNotSupportedInSource" ,
79+ "FeatureNotSupportedInSourcePlural" ,
80+ "PreviewFeatureDisabled" ,
81+ "PreviewFeatureDisabledPlural" ,
82+ "PreviewFeatureUse" ,
83+ "PreviewFeatureUsePlural" ,
84+ "IsPreview" ,
85+ "IsPreviewReflective"
86+ ));
87+ supplyKeyForEachDiagnosticName (diagnosticMethodNames , parentDiagnosticKeys ::add );
8188 } catch (VirtualMachineError e ) {
8289 throw e ;
83- } catch (Throwable ignore ) {
90+ } catch (Throwable e ) {
91+ try {
92+ LOG .log (Level .CONFIG , "Unexpected error initialising Java Language features and parent diagnostic codes: {0}" , (Object ) e );
93+ } catch (Throwable ignore ) {
94+ }
8495 }
85- javacFragmentCodePrefix = prefix ;
96+ javacFragmentCodePrefix = prefix == null ? "compiler.misc." : prefix ;
8697 javacParentDiagnosticKeys = parentDiagnosticKeys .isEmpty () ? Collections .emptySet () : Collections .unmodifiableSet (parentDiagnosticKeys );
8798 fragmentCodeToFeature = featureFragments .isEmpty () ? Collections .emptyMap () : Collections .unmodifiableMap (featureFragments );
8899 }
100+
101+ private static void supplyKeyForEachDiagnosticName (Set <String > methodNames , Consumer <String > action ) {
102+ if (methodNames == null || methodNames .isEmpty ()) return ;
103+ final Object [][] emptyArgs = new Object [6 ][];
104+ for (int i = 0 ; i < emptyArgs .length ; i ++) {
105+ emptyArgs [i ] = new Object [i ];
106+ }
107+ int numInitErrors = 0 ;
108+ Class <?>[] classes = CompilerProperties .class .getClasses ();
109+ for (Class <?> nestedClass : classes ) {
110+ Method [] methods = Modifier .isStatic (nestedClass .getModifiers ()) ? nestedClass .getMethods () : null ;
111+ if (methods == null || methods .length == 0 ) {
112+ continue ;
113+ }
114+ for (Method m : methods ) {
115+ try {
116+ if (Modifier .isStatic (m .getModifiers ())
117+ && JCDiagnostic .DiagnosticInfo .class .isAssignableFrom (m .getReturnType ())
118+ && methodNames .contains (m .getName ())) {
119+ int numParams = m .getParameterCount ();
120+ JCDiagnostic .DiagnosticInfo diag = (JCDiagnostic .DiagnosticInfo ) m .invoke (null , numParams < emptyArgs .length ? emptyArgs [numParams ] : Arrays .copyOf (emptyArgs [0 ], numParams ));
121+ if (diag != null ) {
122+ action .accept (diag .key ());
123+ }
124+ }
125+ } catch (VirtualMachineError e ) {
126+ throw e ;
127+ } catch (Throwable e ) {
128+ numInitErrors ++;
129+ try {
130+ String name = null ;
131+ try {
132+ name = m .getName ();
133+ } catch (Throwable ignore ) {
134+ }
135+ LOG .log (Level .FINE , "Unexpected error initialising diagnostic key for method \" {1}\" , related to Java Language features: {0}" ,
136+ name == null ? new Object []{e , m } : new Object []{e , name });
137+ } catch (Throwable ignore ) {
138+ }
139+ }
140+ }
141+ }
142+ if (numInitErrors > 0 && !LOG .isLoggable (Level .FINE )) {
143+ try {
144+ LOG .log (Level .CONFIG , "Unexpected {0} error(s) initialising diagnostic keys for methods related to Java Language features." , numInitErrors );
145+ } catch (Throwable ignore ) {
146+ }
147+ }
148+ }
89149 }
90150
91151}
0 commit comments