Skip to content

Commit bdcf4c1

Browse files
author
mcimadamore
committed
8189749: Devise strategy for making source level checks more uniform
Summary: Create a 'feature' enum which is responsible for handling source version checks and related diagnostic generation Reviewed-by: jjg, jlahoda
1 parent 13fd11a commit bdcf4c1

File tree

84 files changed

+475
-586
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

84 files changed

+475
-586
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ protected Lint(Context context) {
115115
values = EnumSet.noneOf(LintCategory.class);
116116

117117
Source source = Source.instance(context);
118-
if (source.compareTo(Source.JDK1_9) >= 0) {
118+
if (source.compareTo(Source.JDK9) >= 0) {
119119
values.add(LintCategory.DEP_ANN);
120120
}
121121
values.add(LintCategory.REQUIRES_TRANSITIVE_AUTOMATIC);

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Source.java

+121-122
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,12 @@
3131
import static javax.lang.model.SourceVersion.*;
3232

3333
import com.sun.tools.javac.jvm.Target;
34+
import com.sun.tools.javac.resources.CompilerProperties.Errors;
35+
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
3436
import com.sun.tools.javac.util.*;
37+
import com.sun.tools.javac.util.JCDiagnostic.Error;
38+
import com.sun.tools.javac.util.JCDiagnostic.Fragment;
39+
3540
import static com.sun.tools.javac.main.Option.*;
3641

3742
/** The source language version accepted.
@@ -59,22 +64,22 @@ public enum Source {
5964

6065
/** 1.5 introduced generics, attributes, foreach, boxing, static import,
6166
* covariant return, enums, varargs, et al. */
62-
JDK1_5("1.5"),
67+
JDK5("5"),
6368

6469
/** 1.6 reports encoding problems as errors instead of warnings. */
65-
JDK1_6("1.6"),
70+
JDK6("6"),
6671

6772
/** 1.7 introduced try-with-resources, multi-catch, string switch, etc. */
68-
JDK1_7("1.7"),
73+
JDK7("7"),
6974

7075
/** 1.8 lambda expressions and default methods. */
71-
JDK1_8("1.8"),
76+
JDK8("8"),
7277

7378
/** 1.9 modularity. */
74-
JDK1_9("1.9"),
79+
JDK9("9"),
7580

7681
/** 1.10 covers the to be determined language features that will be added in JDK 10. */
77-
JDK1_10("1.10");
82+
JDK10("10");
7883

7984
private static final Context.Key<Source> sourceKey = new Context.Key<>();
8085

@@ -97,19 +102,19 @@ public static Source instance(Context context) {
97102
for (Source s : values()) {
98103
tab.put(s.name, s);
99104
}
100-
tab.put("5", JDK1_5); // Make 5 an alias for 1.5
101-
tab.put("6", JDK1_6); // Make 6 an alias for 1.6
102-
tab.put("7", JDK1_7); // Make 7 an alias for 1.7
103-
tab.put("8", JDK1_8); // Make 8 an alias for 1.8
104-
tab.put("9", JDK1_9); // Make 9 an alias for 1.9
105-
tab.put("10", JDK1_10); // Make 10 an alias for 1.10
105+
tab.put("1.5", JDK5); // Make 5 an alias for 1.5
106+
tab.put("1.6", JDK6); // Make 6 an alias for 1.6
107+
tab.put("1.7", JDK7); // Make 7 an alias for 1.7
108+
tab.put("1.8", JDK8); // Make 8 an alias for 1.8
109+
tab.put("1.9", JDK9); // Make 9 an alias for 1.9
110+
tab.put("1.10", JDK10); // Make 10 an alias for 1.10
106111
}
107112

108113
private Source(String name) {
109114
this.name = name;
110115
}
111116

112-
public static final Source MIN = Source.JDK1_6;
117+
public static final Source MIN = Source.JDK6;
113118

114119
private static final Source MAX = values()[values().length - 1];
115120

@@ -120,114 +125,108 @@ public static Source lookup(String name) {
120125
}
121126

122127
public Target requiredTarget() {
123-
if (this.compareTo(JDK1_10) >= 0) return Target.JDK1_10;
124-
if (this.compareTo(JDK1_9) >= 0) return Target.JDK1_9;
125-
if (this.compareTo(JDK1_8) >= 0) return Target.JDK1_8;
126-
if (this.compareTo(JDK1_7) >= 0) return Target.JDK1_7;
127-
if (this.compareTo(JDK1_6) >= 0) return Target.JDK1_6;
128-
if (this.compareTo(JDK1_5) >= 0) return Target.JDK1_5;
128+
if (this.compareTo(JDK10) >= 0) return Target.JDK1_10;
129+
if (this.compareTo(JDK9) >= 0) return Target.JDK1_9;
130+
if (this.compareTo(JDK8) >= 0) return Target.JDK1_8;
131+
if (this.compareTo(JDK7) >= 0) return Target.JDK1_7;
132+
if (this.compareTo(JDK6) >= 0) return Target.JDK1_6;
133+
if (this.compareTo(JDK5) >= 0) return Target.JDK1_5;
129134
if (this.compareTo(JDK1_4) >= 0) return Target.JDK1_4;
130135
return Target.JDK1_1;
131136
}
132137

133-
public boolean allowDiamond() {
134-
return compareTo(JDK1_7) >= 0;
135-
}
136-
public boolean allowMulticatch() {
137-
return compareTo(JDK1_7) >= 0;
138-
}
139-
public boolean allowImprovedRethrowAnalysis() {
140-
return compareTo(JDK1_7) >= 0;
141-
}
142-
public boolean allowImprovedCatchAnalysis() {
143-
return compareTo(JDK1_7) >= 0;
144-
}
145-
public boolean allowModules() {
146-
return compareTo(JDK1_9) >= 0;
147-
}
148-
public boolean allowTryWithResources() {
149-
return compareTo(JDK1_7) >= 0;
150-
}
151-
public boolean allowEffectivelyFinalVariablesInTryWithResources() {
152-
return compareTo(JDK1_9) >= 0;
153-
}
154-
public boolean allowBinaryLiterals() {
155-
return compareTo(JDK1_7) >= 0;
156-
}
157-
public boolean allowUnderscoresInLiterals() {
158-
return compareTo(JDK1_7) >= 0;
159-
}
160-
public boolean allowStringsInSwitch() {
161-
return compareTo(JDK1_7) >= 0;
162-
}
163-
public boolean allowDeprecationOnImport() {
164-
return compareTo(JDK1_9) < 0;
165-
}
166-
public boolean allowSimplifiedVarargs() {
167-
return compareTo(JDK1_7) >= 0;
168-
}
169-
public boolean allowObjectToPrimitiveCast() {
170-
return compareTo(JDK1_7) >= 0;
171-
}
172-
public boolean enforceThisDotInit() {
173-
return compareTo(JDK1_7) >= 0;
174-
}
175-
public boolean allowPoly() {
176-
return compareTo(JDK1_8) >= 0;
177-
}
178-
public boolean allowLambda() {
179-
return compareTo(JDK1_8) >= 0;
180-
}
181-
public boolean allowMethodReferences() {
182-
return compareTo(JDK1_8) >= 0;
183-
}
184-
public boolean allowDefaultMethods() {
185-
return compareTo(JDK1_8) >= 0;
186-
}
187-
public boolean allowStaticInterfaceMethods() {
188-
return compareTo(JDK1_8) >= 0;
189-
}
190-
public boolean allowStrictMethodClashCheck() {
191-
return compareTo(JDK1_8) >= 0;
192-
}
193-
public boolean allowEffectivelyFinalInInnerClasses() {
194-
return compareTo(JDK1_8) >= 0;
195-
}
196-
public boolean allowTypeAnnotations() {
197-
return compareTo(JDK1_8) >= 0;
198-
}
199-
public boolean allowAnnotationsAfterTypeParams() {
200-
return compareTo(JDK1_8) >= 0;
201-
}
202-
public boolean allowRepeatedAnnotations() {
203-
return compareTo(JDK1_8) >= 0;
204-
}
205-
public boolean allowIntersectionTypesInCast() {
206-
return compareTo(JDK1_8) >= 0;
207-
}
208-
public boolean allowGraphInference() {
209-
return compareTo(JDK1_8) >= 0;
210-
}
211-
public boolean allowFunctionalInterfaceMostSpecific() {
212-
return compareTo(JDK1_8) >= 0;
213-
}
214-
public boolean allowPostApplicabilityVarargsAccessCheck() {
215-
return compareTo(JDK1_8) >= 0;
216-
}
217-
public boolean mapCapturesToBounds() {
218-
return compareTo(JDK1_8) < 0;
219-
}
220-
public boolean allowPrivateSafeVarargs() {
221-
return compareTo(JDK1_9) >= 0;
222-
}
223-
public boolean allowDiamondWithAnonymousClassCreation() {
224-
return compareTo(JDK1_9) >= 0;
225-
}
226-
public boolean allowUnderscoreIdentifier() {
227-
return compareTo(JDK1_8) <= 0;
138+
/**
139+
* Models a feature of the Java programming language. Each feature can be associated with a
140+
* minimum source level, a maximum source level and a diagnostic fragment describing the feature,
141+
* which is used to generate error messages of the kind {@code feature XYZ not supported in source N}.
142+
*/
143+
public enum Feature {
144+
145+
DIAMOND(JDK7, Fragments.FeatureDiamond, DiagKind.NORMAL),
146+
MULTICATCH(JDK7, Fragments.FeatureMulticatch, DiagKind.PLURAL),
147+
IMPROVED_RETHROW_ANALYSIS(JDK7),
148+
IMPROVED_CATCH_ANALYSIS(JDK7),
149+
MODULES(JDK9, Fragments.FeatureModules, DiagKind.PLURAL),
150+
TRY_WITH_RESOURCES(JDK7, Fragments.FeatureTryWithResources, DiagKind.NORMAL),
151+
EFFECTIVELY_FINAL_VARIABLES_IN_TRY_WITH_RESOURCES(JDK9, Fragments.FeatureVarInTryWithResources, DiagKind.PLURAL),
152+
BINARY_LITERALS(JDK7, Fragments.FeatureBinaryLit, DiagKind.PLURAL),
153+
UNDERSCORES_IN_LITERALS(JDK7, Fragments.FeatureUnderscoreLit, DiagKind.PLURAL),
154+
STRINGS_IN_SWITCH(JDK7, Fragments.FeatureStringSwitch, DiagKind.PLURAL),
155+
DEPRECATION_ON_IMPORT(MIN, JDK9),
156+
SIMPLIFIED_VARARGS(JDK7),
157+
OBJECT_TO_PRIMITIVE_CAST(JDK7),
158+
ENFORCE_THIS_DOT_INIT(JDK7),
159+
POLY(JDK8),
160+
LAMBDA(JDK8, Fragments.FeatureLambda, DiagKind.PLURAL),
161+
METHOD_REFERENCES(JDK8, Fragments.FeatureMethodReferences, DiagKind.PLURAL),
162+
DEFAULT_METHODS(JDK8, Fragments.FeatureDefaultMethods, DiagKind.PLURAL),
163+
STATIC_INTERFACE_METHODS(JDK8, Fragments.FeatureStaticIntfMethods, DiagKind.PLURAL),
164+
STATIC_INTERFACE_METHODS_INVOKE(JDK8, Fragments.FeatureStaticIntfMethodInvoke, DiagKind.PLURAL),
165+
STRICT_METHOD_CLASH_CHECK(JDK8),
166+
EFFECTIVELY_FINAL_IN_INNER_CLASSES(JDK8),
167+
TYPE_ANNOTATIONS(JDK8, Fragments.FeatureTypeAnnotations, DiagKind.PLURAL),
168+
ANNOTATIONS_AFTER_TYPE_PARAMS(JDK8, Fragments.FeatureAnnotationsAfterTypeParams, DiagKind.PLURAL),
169+
REPEATED_ANNOTATIONS(JDK8, Fragments.FeatureRepeatableAnnotations, DiagKind.PLURAL),
170+
INTERSECTION_TYPES_IN_CAST(JDK8, Fragments.FeatureIntersectionTypesInCast, DiagKind.PLURAL),
171+
GRAPH_INFERENCE(JDK8),
172+
FUNCTIONAL_INTERFACE_MOST_SPECIFIC(JDK8),
173+
POST_APPLICABILITY_VARARGS_ACCESS_CHECK(JDK8),
174+
MAP_CAPTURES_TO_BOUNDS(MIN, JDK7),
175+
PRIVATE_SAFE_VARARGS(JDK9),
176+
DIAMOND_WITH_ANONYMOUS_CLASS_CREATION(JDK9, Fragments.FeatureDiamondAndAnonClass, DiagKind.NORMAL),
177+
UNDERSCORE_IDENTIFIER(MIN, JDK8),
178+
PRIVATE_INTERFACE_METHODS(JDK9, Fragments.FeaturePrivateIntfMethods, DiagKind.PLURAL),
179+
LOCAL_VARIABLE_TYPE_INFERENCE(JDK10);
180+
181+
enum DiagKind {
182+
NORMAL,
183+
PLURAL;
184+
}
185+
186+
private final Source minLevel;
187+
private final Source maxLevel;
188+
private final Fragment optFragment;
189+
private final DiagKind optKind;
190+
191+
Feature(Source minLevel) {
192+
this(minLevel, null, null);
193+
}
194+
195+
Feature(Source minLevel, Fragment optFragment, DiagKind optKind) {
196+
this(minLevel, MAX, optFragment, optKind);
197+
}
198+
199+
Feature(Source minLevel, Source maxLevel) {
200+
this(minLevel, maxLevel, null, null);
201+
}
202+
203+
Feature(Source minLevel, Source maxLevel, Fragment optFragment, DiagKind optKind) {
204+
this.minLevel = minLevel;
205+
this.maxLevel = maxLevel;
206+
this.optFragment = optFragment;
207+
this.optKind = optKind;
208+
}
209+
210+
public boolean allowedInSource(Source source) {
211+
return source.compareTo(minLevel) >= 0 &&
212+
source.compareTo(maxLevel) <= 0;
213+
}
214+
215+
public Fragment fragment(String sourceName) {
216+
Assert.checkNonNull(optFragment);
217+
return optKind == DiagKind.NORMAL ?
218+
Fragments.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) :
219+
Fragments.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name);
220+
}
221+
222+
public Error error(String sourceName) {
223+
Assert.checkNonNull(optFragment);
224+
return optKind == DiagKind.NORMAL ?
225+
Errors.FeatureNotSupportedInSource(optFragment, sourceName, minLevel.name) :
226+
Errors.FeatureNotSupportedInSourcePlural(optFragment, sourceName, minLevel.name);
227+
}
228228
}
229-
public boolean allowPrivateInterfaceMethods() { return compareTo(JDK1_9) >= 0; }
230-
public boolean allowLocalVariableTypeInference() { return compareTo(JDK1_10) >= 0; }
229+
231230
public static SourceVersion toSourceVersion(Source source) {
232231
switch(source) {
233232
case JDK1_2:
@@ -236,17 +235,17 @@ public static SourceVersion toSourceVersion(Source source) {
236235
return RELEASE_3;
237236
case JDK1_4:
238237
return RELEASE_4;
239-
case JDK1_5:
238+
case JDK5:
240239
return RELEASE_5;
241-
case JDK1_6:
240+
case JDK6:
242241
return RELEASE_6;
243-
case JDK1_7:
242+
case JDK7:
244243
return RELEASE_7;
245-
case JDK1_8:
244+
case JDK8:
246245
return RELEASE_8;
247-
case JDK1_9:
246+
case JDK9:
248247
return RELEASE_9;
249-
case JDK1_10:
248+
case JDK10:
250249
return RELEASE_10;
251250
default:
252251
return null;

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import javax.lang.model.element.ElementVisitor;
3636

3737
import com.sun.tools.javac.code.Scope.WriteableScope;
38+
import com.sun.tools.javac.code.Source.Feature;
3839
import com.sun.tools.javac.code.Symbol.ClassSymbol;
3940
import com.sun.tools.javac.code.Symbol.Completer;
4041
import com.sun.tools.javac.code.Symbol.CompletionFailure;
@@ -468,7 +469,7 @@ public <R, P> R accept(ElementVisitor<R, P> v, P p) {
468469
scope.enter(errSymbol);
469470

470471
Source source = Source.instance(context);
471-
if (source.allowModules()) {
472+
if (Feature.MODULES.allowedInSource(source)) {
472473
java_base = enterModule(names.java_base);
473474
//avoid completing java.base during the Symtab initialization
474475
java_base.completer = Completer.NULL_COMPLETER;

src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141

4242
import com.sun.tools.javac.code.Attribute.RetentionPolicy;
4343
import com.sun.tools.javac.code.Lint.LintCategory;
44+
import com.sun.tools.javac.code.Source.Feature;
4445
import com.sun.tools.javac.code.Type.UndetVar.InferenceBound;
4546
import com.sun.tools.javac.code.TypeMetadata.Entry.Kind;
4647
import com.sun.tools.javac.comp.AttrContext;
@@ -113,9 +114,9 @@ protected Types(Context context) {
113114
syms = Symtab.instance(context);
114115
names = Names.instance(context);
115116
Source source = Source.instance(context);
116-
allowObjectToPrimitiveCast = source.allowObjectToPrimitiveCast();
117-
allowDefaultMethods = source.allowDefaultMethods();
118-
mapCapturesToBounds = source.mapCapturesToBounds();
117+
allowObjectToPrimitiveCast = Feature.OBJECT_TO_PRIMITIVE_CAST.allowedInSource(source);
118+
allowDefaultMethods = Feature.DEFAULT_METHODS.allowedInSource(source);
119+
mapCapturesToBounds = Feature.MAP_CAPTURES_TO_BOUNDS.allowedInSource(source);
119120
chk = Check.instance(context);
120121
enter = Enter.instance(context);
121122
capturedName = names.fromString("<captured wildcard>");

0 commit comments

Comments
 (0)