18
18
import com .sun .tools .javac .code .Source ;
19
19
import com .sun .tools .javac .resources .CompilerProperties ;
20
20
import com .sun .tools .javac .util .JCDiagnostic ;
21
+ import java .lang .reflect .Method ;
22
+ import java .lang .reflect .Modifier ;
23
+ import java .util .Arrays ;
21
24
import java .util .Collections ;
22
25
import java .util .HashMap ;
23
26
import java .util .HashSet ;
24
27
import java .util .Map ;
25
28
import java .util .Set ;
29
+ import java .util .function .Consumer ;
30
+ import java .util .logging .Level ;
31
+ import java .util .logging .Logger ;
26
32
27
33
class JavaLangFeatures {
34
+ private static final Logger LOG = Logger .getLogger (JavaLangFeatures .class .getName ());
28
35
29
36
public static boolean isDiagnosticForUnsupportedFeatures (String diagnosticCode ) {
30
37
return Singleton .javacParentDiagnosticKeys .contains (diagnosticCode );
@@ -47,45 +54,98 @@ private static class Singleton {
47
54
static {
48
55
Map <String , Source .Feature > featureFragments = new HashMap <>();
49
56
Set <String > parentDiagnosticKeys = new HashSet <>();
50
- String prefix = "compiler.misc." ;
57
+ String prefix = null ;
51
58
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
-
73
59
for (Source .Feature f : Source .Feature .values ()) {
74
60
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
+ }
76
71
} catch (AssertionError | NullPointerException e ) {
77
72
// In case no error message code has been registered; for example: LOCAL_VARIABLE_TYPE_INFERENCE
78
73
featureFragments .put (f .name (), f );
79
74
}
80
75
}
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 );
81
88
} catch (VirtualMachineError e ) {
82
89
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
+ }
84
95
}
85
- javacFragmentCodePrefix = prefix ;
96
+ javacFragmentCodePrefix = prefix == null ? "compiler.misc." : prefix ;
86
97
javacParentDiagnosticKeys = parentDiagnosticKeys .isEmpty () ? Collections .emptySet () : Collections .unmodifiableSet (parentDiagnosticKeys );
87
98
fragmentCodeToFeature = featureFragments .isEmpty () ? Collections .emptyMap () : Collections .unmodifiableMap (featureFragments );
88
99
}
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
+ }
89
149
}
90
150
91
151
}
0 commit comments