8078561: Error message should be generated once when -source 6 is specified

Code to avoid duplicated errors about features not supported in the current source level moved to Log

Reviewed-by: jjg
This commit is contained in:
Jan Lahoda 2016-08-16 16:43:00 +02:00
parent f6fc6ee2b8
commit d103a19b3a
29 changed files with 188 additions and 108 deletions

View File

@ -54,6 +54,7 @@ import static com.sun.tools.javac.tree.JCTree.Tag.ANNOTATION;
import static com.sun.tools.javac.tree.JCTree.Tag.ASSIGN;
import static com.sun.tools.javac.tree.JCTree.Tag.IDENT;
import static com.sun.tools.javac.tree.JCTree.Tag.NEWARRAY;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
/** Enter annotations onto symbols and types (and trees).
*
@ -302,7 +303,6 @@ public class Annotate {
{
Map<TypeSymbol, ListBuffer<T>> annotated = new LinkedHashMap<>();
Map<T, DiagnosticPosition> pos = new HashMap<>();
boolean allowRepeatedAnnos = this.allowRepeatedAnnos;
for (List<JCAnnotation> al = withAnnotations; !al.isEmpty(); al = al.tail) {
JCAnnotation a = al.head;
@ -322,8 +322,7 @@ public class Annotate {
if (annotated.containsKey(a.type.tsym)) {
if (!allowRepeatedAnnos) {
log.error(a.pos(), "repeatable.annotations.not.supported.in.source");
allowRepeatedAnnos = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, a.pos(), "repeatable.annotations.not.supported.in.source");
}
ListBuffer<T> l = annotated.get(a.type.tsym);
l = l.append(c);

View File

@ -70,6 +70,7 @@ import static com.sun.tools.javac.code.Kinds.Kind.*;
import static com.sun.tools.javac.code.TypeTag.*;
import static com.sun.tools.javac.code.TypeTag.WILDCARD;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
/** This is the main context-dependent analysis phase in GJC. It
* encompasses name resolution, type checking and constant folding as
@ -1282,13 +1283,9 @@ public class Attr extends JCTree.Visitor {
try {
boolean enumSwitch = (seltype.tsym.flags() & Flags.ENUM) != 0;
boolean stringSwitch = false;
if (types.isSameType(seltype, syms.stringType)) {
if (allowStringsInSwitch) {
stringSwitch = true;
} else {
log.error(tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
}
boolean stringSwitch = types.isSameType(seltype, syms.stringType);
if (stringSwitch && !allowStringsInSwitch) {
log.error(DiagnosticFlag.SOURCE_LEVEL, tree.selector.pos(), "string.switch.not.supported.in.source", sourceName);
}
if (!enumSwitch && !stringSwitch)
seltype = chk.checkType(tree.selector.pos(), seltype, syms.intType);
@ -3484,7 +3481,7 @@ public class Attr extends JCTree.Visitor {
}
if (!allowStaticInterfaceMethods && sitesym.isInterface() &&
sym.isStatic() && sym.kind == MTH) {
log.error(tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName);
log.error(DiagnosticFlag.SOURCE_LEVEL, tree.pos(), "static.intf.method.invoke.not.supported.in.source", sourceName);
}
} else if (sym.kind != ERR &&
(sym.flags() & STATIC) != 0 &&

View File

@ -789,23 +789,25 @@ public class Check {
if (!TreeInfo.isDiamond(tree) ||
t.isErroneous()) {
return checkClassType(tree.clazz.pos(), t, true);
} else if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
log.error(tree.clazz.pos(),
Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
return types.createErrorType(t);
} else if (t.tsym.type.getTypeArguments().isEmpty()) {
log.error(tree.clazz.pos(),
"cant.apply.diamond.1",
t, diags.fragment("diamond.non.generic", t));
return types.createErrorType(t);
} else if (tree.typeargs != null &&
tree.typeargs.nonEmpty()) {
log.error(tree.clazz.pos(),
"cant.apply.diamond.1",
t, diags.fragment("diamond.and.explicit.params", t));
return types.createErrorType(t);
} else {
return t;
if (tree.def != null && !allowDiamondWithAnonymousClassCreation) {
log.error(DiagnosticFlag.SOURCE_LEVEL, tree.clazz.pos(),
Errors.CantApplyDiamond1(t, Fragments.DiamondAndAnonClassNotSupportedInSource(source.name)));
}
if (t.tsym.type.getTypeArguments().isEmpty()) {
log.error(tree.clazz.pos(),
"cant.apply.diamond.1",
t, diags.fragment("diamond.non.generic", t));
return types.createErrorType(t);
} else if (tree.typeargs != null &&
tree.typeargs.nonEmpty()) {
log.error(tree.clazz.pos(),
"cant.apply.diamond.1",
t, diags.fragment("diamond.and.explicit.params", t));
return types.createErrorType(t);
} else {
return t;
}
}
}

View File

@ -51,6 +51,7 @@ import static com.sun.tools.javac.parser.Tokens.TokenKind.GT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.IMPORT;
import static com.sun.tools.javac.parser.Tokens.TokenKind.LT;
import static com.sun.tools.javac.tree.JCTree.Tag.*;
import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
/** The parser maps a token sequence into an abstract syntax
* tree. It operates by recursive descent, with code derived
@ -2536,11 +2537,13 @@ public class JavacParser implements Parser {
finalizer = block();
}
} else {
if (allowTWR) {
if (resources.isEmpty())
if (resources.isEmpty()) {
if (allowTWR) {
error(pos, "try.without.catch.finally.or.resource.decls");
} else
error(pos, "try.without.catch.or.finally");
} else {
error(pos, "try.without.catch.or.finally");
}
}
}
return F.at(pos).Try(resources, body, catchers.toList(), finalizer);
}
@ -4082,74 +4085,62 @@ public class JavacParser implements Parser {
void checkDiamond() {
if (!allowDiamond) {
error(token.pos, "diamond.not.supported.in.source", source.name);
allowDiamond = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "diamond.not.supported.in.source", source.name);
}
}
void checkMulticatch() {
if (!allowMulticatch) {
error(token.pos, "multicatch.not.supported.in.source", source.name);
allowMulticatch = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "multicatch.not.supported.in.source", source.name);
}
}
void checkTryWithResources() {
if (!allowTWR) {
error(token.pos, "try.with.resources.not.supported.in.source", source.name);
allowTWR = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "try.with.resources.not.supported.in.source", source.name);
}
}
void checkVariableInTryWithResources(int startPos) {
if (!allowEffectivelyFinalVariablesInTWR) {
error(startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
allowEffectivelyFinalVariablesInTWR = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, startPos, "var.in.try.with.resources.not.supported.in.source", source.name);
}
}
void checkLambda() {
if (!allowLambda) {
log.error(token.pos, "lambda.not.supported.in.source", source.name);
allowLambda = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "lambda.not.supported.in.source", source.name);
}
}
void checkMethodReferences() {
if (!allowMethodReferences) {
log.error(token.pos, "method.references.not.supported.in.source", source.name);
allowMethodReferences = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "method.references.not.supported.in.source", source.name);
}
}
void checkDefaultMethods() {
if (!allowDefaultMethods) {
log.error(token.pos, "default.methods.not.supported.in.source", source.name);
allowDefaultMethods = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "default.methods.not.supported.in.source", source.name);
}
}
void checkIntersectionTypesInCast() {
if (!allowIntersectionTypesInCast) {
log.error(token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
allowIntersectionTypesInCast = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "intersection.types.in.cast.not.supported.in.source", source.name);
}
}
void checkStaticInterfaceMethods() {
if (!allowStaticInterfaceMethods) {
log.error(token.pos, "static.intf.methods.not.supported.in.source", source.name);
allowStaticInterfaceMethods = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "static.intf.methods.not.supported.in.source", source.name);
}
}
void checkTypeAnnotations() {
if (!allowTypeAnnotations) {
log.error(token.pos, "type.annotations.not.supported.in.source", source.name);
allowTypeAnnotations = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, "type.annotations.not.supported.in.source", source.name);
}
}
void checkPrivateInterfaceMethods() {
if (!allowPrivateInterfaceMethods) {
log.error(token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
allowPrivateInterfaceMethods = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, CompilerProperties.Errors.PrivateIntfMethodsNotSupportedInSource(source.name));
}
}
protected void checkAnnotationsAfterTypeParams(int pos) {
if (!allowAnnotationsAfterTypeParams) {
log.error(pos, "annotations.after.type.params.not.supported.in.source", source.name);
allowAnnotationsAfterTypeParams = true;
log.error(DiagnosticFlag.SOURCE_LEVEL, pos, "annotations.after.type.params.not.supported.in.source", source.name);
}
}

View File

@ -435,7 +435,10 @@ public class JCDiagnostic implements Diagnostic<JavaFileObject> {
COMPRESSED,
/** Print multiple errors for same source locations.
*/
MULTIPLE;
MULTIPLE,
/** Flag for not-supported-in-source-X errors.
*/
SOURCE_LEVEL;
}
private final DiagnosticSource source;

View File

@ -428,6 +428,11 @@ public class Log extends AbstractLog {
*/
protected Set<Pair<JavaFileObject, Integer>> recorded = new HashSet<>();
/** A set of "not-supported-in-source-X" errors produced so far. This is used to only generate
* one such error per file.
*/
protected Set<Pair<JavaFileObject, String>> recordedSourceLevelErrors = new HashSet<>();
public boolean hasDiagnosticListener() {
return diagListener != null;
}
@ -507,6 +512,27 @@ public class Log extends AbstractLog {
return shouldReport;
}
/** Returns true if a diagnostics needs to be reported.
*/
private boolean shouldReport(JCDiagnostic d) {
JavaFileObject file = d.getSource();
if (file == null)
return true;
if (!shouldReport(file, d.getIntPosition()))
return false;
if (!d.isFlagSet(DiagnosticFlag.SOURCE_LEVEL))
return true;
Pair<JavaFileObject, String> coords = new Pair<>(file, d.getCode());
boolean shouldReport = !recordedSourceLevelErrors.contains(coords);
if (shouldReport)
recordedSourceLevelErrors.add(coords);
return shouldReport;
}
/** Prompt user after an error.
*/
public void prompt() {
@ -671,7 +697,7 @@ public class Log extends AbstractLog {
case ERROR:
if (nerrors < MaxErrors &&
(diagnostic.isFlagSet(DiagnosticFlag.MULTIPLE) ||
shouldReport(diagnostic.getSource(), diagnostic.getIntPosition()))) {
shouldReport(diagnostic))) {
writeDiagnostic(diagnostic);
nerrors++;
}

View File

@ -2,5 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
BadlyTypedLabel1.java:10:15: compiler.err.string.switch.not.supported.in.source: 1.6
1 error
BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: int, java.lang.String)
2 errors
3 warnings

View File

@ -2,6 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
BadlyTypedLabel2.java:12:15: compiler.err.string.switch.not.supported.in.source: 1.6
BadlyTypedLabel2.java:15:14: compiler.err.const.expr.req
BadlyTypedLabel2.java:15:14: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.math.RoundingMode, java.lang.String)
2 errors
3 warnings

View File

@ -2,6 +2,6 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
NonConstantLabel.java:11:15: compiler.err.string.switch.not.supported.in.source: 1.6
NonConstantLabel.java:14:14: compiler.err.const.expr.req
NonConstantLabel.java:14:14: compiler.err.string.const.req
2 errors
3 warnings

View File

@ -1,6 +1,6 @@
/*
* @test /nodynamiccopyright/
* @bug 6827009
* @bug 6827009 8078561
* @summary Positive tests for strings in switch with few alternatives.
* @compile/fail/ref=OneCaseSwitches.out -XDrawDiagnostics -source 6 OneCaseSwitches.java
* @compile OneCaseSwitches.java

View File

@ -2,13 +2,5 @@
- compiler.warn.option.obsolete.source: 1.6
- compiler.warn.option.obsolete.suppression
OneCaseSwitches.java:23:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:33:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:52:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:66:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:85:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:99:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:119:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:130:15: compiler.err.string.switch.not.supported.in.source: 1.6
OneCaseSwitches.java:242:16: compiler.err.string.switch.not.supported.in.source: 1.6
9 errors
3 warnings
1 error
3 warnings

View File

@ -1,15 +0,0 @@
/* @test /nodynamiccopyright/
* @bug 8037385
* @summary Must not allow static interface method invocation in legacy code
* @compile -source 8 -Xlint:-options StaticInvoke.java
* @compile/fail/ref=StaticInvoke7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
* @compile/fail/ref=StaticInvoke6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvoke.java
*/
import java.util.stream.Stream;
class StaticInvoke {
void test() {
Stream.empty();
java.util.stream.Stream.empty();
}
}

View File

@ -1,3 +0,0 @@
StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
2 errors

View File

@ -1,3 +0,0 @@
StaticInvoke.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
StaticInvoke.java:13:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
2 errors

View File

@ -0,0 +1,13 @@
/* @test /nodynamiccopyright/
* @bug 8037385
* @summary Must not allow static interface method invocation in legacy code
* @compile -source 8 -Xlint:-options StaticInvokeQualified.java
* @compile/fail/ref=StaticInvokeQualified7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvokeQualified.java
* @compile/fail/ref=StaticInvokeQualified6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvokeQualified.java
*/
class StaticInvokeQualified {
void test() {
java.util.stream.Stream.empty();
}
}

View File

@ -0,0 +1,2 @@
StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
1 error

View File

@ -0,0 +1,2 @@
StaticInvokeQualified.java:11:32: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
1 error

View File

@ -0,0 +1,14 @@
/* @test /nodynamiccopyright/
* @bug 8037385
* @summary Must not allow static interface method invocation in legacy code
* @compile -source 8 -Xlint:-options StaticInvokeSimple.java
* @compile/fail/ref=StaticInvokeSimple7.out -source 7 -Xlint:-options -XDrawDiagnostics StaticInvokeSimple.java
* @compile/fail/ref=StaticInvokeSimple6.out -source 6 -Xlint:-options -XDrawDiagnostics StaticInvokeSimple.java
*/
import java.util.stream.Stream;
class StaticInvokeSimple {
void test() {
Stream.empty();
}
}

View File

@ -0,0 +1,2 @@
StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.6
1 error

View File

@ -0,0 +1,2 @@
StaticInvokeSimple.java:12:15: compiler.err.static.intf.method.invoke.not.supported.in.source: 1.7
1 error

View File

@ -1,7 +0,0 @@
- compiler.warn.source.no.bootclasspath: 1.8
Neg09.java:17:34: compiler.err.cant.apply.diamond.1: Neg09.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
Neg09.java:18:34: compiler.err.cant.apply.diamond.1: Neg09.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
Neg09.java:22:39: compiler.err.cant.apply.diamond.1: Neg09.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
Neg09.java:23:40: compiler.err.cant.apply.diamond.1: Neg09.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
4 errors
1 warning

View File

@ -0,0 +1,17 @@
/*
* @test /nodynamiccopyright/
* @bug 7020044 8062373
*
* @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
* @author Maurizio Cimadamore
* @compile/fail/ref=Neg09a.out Neg09a.java -source 8 -XDrawDiagnostics
*
*/
class Neg09a {
class Member<X> {}
void testSimple() {
Member<?> m1 = new Member<>() {};
}
}

View File

@ -0,0 +1,4 @@
- compiler.warn.source.no.bootclasspath: 1.8
Neg09a.java:15:34: compiler.err.cant.apply.diamond.1: Neg09a.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
1 error
1 warning

View File

@ -0,0 +1,19 @@
/*
* @test /nodynamiccopyright/
* @bug 7020044 8062373
*
* @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
* @author Maurizio Cimadamore
* @compile/fail/ref=Neg09b.out Neg09b.java -source 8 -XDrawDiagnostics
*
*/
class Neg09b {
static class Nested<X> {}
void testSimple() {
Nested<?> m2 = new Nested<>() {};
}
}

View File

@ -0,0 +1,4 @@
- compiler.warn.source.no.bootclasspath: 1.8
Neg09b.java:16:34: compiler.err.cant.apply.diamond.1: Neg09b.Nested<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
1 error
1 warning

View File

@ -0,0 +1,17 @@
/*
* @test /nodynamiccopyright/
* @bug 7020044 8062373
*
* @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
* @author Maurizio Cimadamore
* @compile/fail/ref=Neg09c.out Neg09c.java -source 8 -XDrawDiagnostics
*
*/
class Neg09c {
class Member<X> {}
void testQualified() {
Member<?> m1 = this.new Member<>() {};
}
}

View File

@ -0,0 +1,4 @@
- compiler.warn.source.no.bootclasspath: 1.8
Neg09c.java:15:39: compiler.err.cant.apply.diamond.1: Neg09c.Member<X>, (compiler.misc.diamond.and.anon.class.not.supported.in.source: 1.8)
1 error
1 warning

View File

@ -4,22 +4,15 @@
*
* @summary Check that diamond is not allowed with anonymous inner class expressions at source < 9
* @author Maurizio Cimadamore
* @compile/fail/ref=Neg09.out Neg09.java -source 8 -XDrawDiagnostics
* @compile/fail/ref=Neg09d.out Neg09d.java -source 8 -XDrawDiagnostics
*
*/
class Neg09 {
class Member<X> {}
class Neg09d {
static class Nested<X> {}
void testSimple() {
Member<?> m1 = new Member<>() {};
Nested<?> m2 = new Nested<>() {};
}
void testQualified() {
Member<?> m1 = this.new Member<>() {};
Nested<?> m2 = new Neg09.Nested<>() {};
}
}

View File

@ -0,0 +1,4 @@
- compiler.warn.source.no.bootclasspath: 1.8
Neg09d.java:16:33: compiler.err.doesnt.exist: Neg09
1 error
1 warning