Details
-
Enhancement
-
Resolution: Fixed
-
P4
-
10
-
b35
Description
javac has several resource keys that are related to source level checks - e.g. checking that a sufficient source level is used when compiling source code with given feature. Examples:
# 0: string
compiler.misc.diamond.and.anon.class.not.supported.in.source=\
cannot use ''<>'' with anonymous inner classes in -source {0}\n\
(use -source 9 or higher to enable ''<>'' with anonymous inner classes)
# 0: string
compiler.err.unsupported.binary.lit=\
binary literals are not supported in -source {0}\n\
(use -source 7 or higher to enable binary literals)
# 0: string
compiler.err.unsupported.underscore.lit=\
underscores in literals are not supported in -source {0}\n\
(use -source 7 or higher to enable underscores in literals)
This is bad because (i) it essentially promotes a copy/paste activity, which can sometimes lead to mistakes and (ii) diagnostics that are meant to model morally equivalent situations can be render in slighty different ways (see the first example, which differ from the others).
Moreover, the Source class is littered with predicates of the kind:
public boolean allowBinaryLiterals() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowUnderscoresInLiterals() {
return compareTo(JDK1_7) >= 0;
}
And again this encourages cut and paste which is then a source of errors. Same level of replication is found in the parser, where for most features we have both a field and a corresponding check method:
/** Switch: should we allow private (instance) methods in interfaces?
*/
boolean allowPrivateInterfaceMethods;
/** Switch: should we allow intersection types in cast?
*/
boolean allowIntersectionTypesInCast;
...
void checkPrivateInterfaceMethods() {
if (!allowPrivateInterfaceMethods) {
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
}
}
void checkIntersectionTypesInCast() {
if (!allowIntersectionTypesInCast) {
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name));
}
}
Overall, this is a lot of replication, and all this cut and paste has to be repeated every time a new feature is added to the compiler; this is not sustainable in the long run, and bound to be more costly under the faster release cadence.
# 0: string
compiler.misc.diamond.and.anon.class.not.supported.in.source=\
cannot use ''<>'' with anonymous inner classes in -source {0}\n\
(use -source 9 or higher to enable ''<>'' with anonymous inner classes)
# 0: string
compiler.err.unsupported.binary.lit=\
binary literals are not supported in -source {0}\n\
(use -source 7 or higher to enable binary literals)
# 0: string
compiler.err.unsupported.underscore.lit=\
underscores in literals are not supported in -source {0}\n\
(use -source 7 or higher to enable underscores in literals)
This is bad because (i) it essentially promotes a copy/paste activity, which can sometimes lead to mistakes and (ii) diagnostics that are meant to model morally equivalent situations can be render in slighty different ways (see the first example, which differ from the others).
Moreover, the Source class is littered with predicates of the kind:
public boolean allowBinaryLiterals() {
return compareTo(JDK1_7) >= 0;
}
public boolean allowUnderscoresInLiterals() {
return compareTo(JDK1_7) >= 0;
}
And again this encourages cut and paste which is then a source of errors. Same level of replication is found in the parser, where for most features we have both a field and a corresponding check method:
/** Switch: should we allow private (instance) methods in interfaces?
*/
boolean allowPrivateInterfaceMethods;
/** Switch: should we allow intersection types in cast?
*/
boolean allowIntersectionTypesInCast;
...
void checkPrivateInterfaceMethods() {
if (!allowPrivateInterfaceMethods) {
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
}
}
void checkIntersectionTypesInCast() {
if (!allowIntersectionTypesInCast) {
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name));
}
}
Overall, this is a lot of replication, and all this cut and paste has to be repeated every time a new feature is added to the compiler; this is not sustainable in the long run, and bound to be more costly under the faster release cadence.