8240454: incorrect error message: as of release 13, 'record' is a restricted type name

Reviewed-by: jlahoda
This commit is contained in:
Vicente Romero 2020-03-05 16:46:24 -05:00
parent 3607ddd55a
commit 4a32eda417
6 changed files with 57 additions and 14 deletions

View File

@ -3262,7 +3262,7 @@ public class JavacParser implements Parser {
int startPos = Position.NOPOS; int startPos = Position.NOPOS;
if (elemType.hasTag(IDENT)) { if (elemType.hasTag(IDENT)) {
Name typeName = ((JCIdent)elemType).name; Name typeName = ((JCIdent)elemType).name;
if (isRestrictedTypeName(typeName, pos, !compound && localDecl)) { if (restrictedTypeNameStartingAtSource(typeName, pos, !compound && localDecl) != null) {
if (type.hasTag(TYPEARRAY) && !compound) { if (type.hasTag(TYPEARRAY) && !compound) {
//error - 'var' and arrays //error - 'var' and arrays
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedArray(typeName)); reportSyntaxError(pos, Errors.RestrictedTypeNotAllowedArray(typeName));
@ -3288,7 +3288,7 @@ public class JavacParser implements Parser {
Name restrictedTypeName(JCExpression e, boolean shouldWarn) { Name restrictedTypeName(JCExpression e, boolean shouldWarn) {
switch (e.getTag()) { switch (e.getTag()) {
case IDENT: case IDENT:
return isRestrictedTypeName(((JCIdent)e).name, e.pos, shouldWarn) ? ((JCIdent)e).name : null; return restrictedTypeNameStartingAtSource(((JCIdent)e).name, e.pos, shouldWarn) != null ? ((JCIdent)e).name : null;
case TYPEARRAY: case TYPEARRAY:
return restrictedTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn); return restrictedTypeName(((JCArrayTypeTree)e).elemtype, shouldWarn);
default: default:
@ -3296,29 +3296,29 @@ public class JavacParser implements Parser {
} }
} }
boolean isRestrictedTypeName(Name name, int pos, boolean shouldWarn) { Source restrictedTypeNameStartingAtSource(Name name, int pos, boolean shouldWarn) {
if (name == names.var) { if (name == names.var) {
if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) { if (Feature.LOCAL_VARIABLE_TYPE_INFERENCE.allowedInSource(source)) {
return true; return Source.JDK10;
} else if (shouldWarn) { } else if (shouldWarn) {
log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10)); log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK10));
} }
} }
if (name == names.yield) { if (name == names.yield) {
if (allowYieldStatement) { if (allowYieldStatement) {
return true; return Source.JDK14;
} else if (shouldWarn) { } else if (shouldWarn) {
log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14)); log.warning(pos, Warnings.RestrictedTypeNotAllowed(name, Source.JDK14));
} }
} }
if (name == names.record) { if (name == names.record) {
if (allowRecords) { if (allowRecords) {
return true; return Source.JDK14;
} else if (shouldWarn) { } else if (shouldWarn) {
log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14)); log.warning(pos, Warnings.RestrictedTypeNotAllowedPreview(name, Source.JDK14));
} }
} }
return false; return null;
} }
/** VariableDeclaratorId = Ident BracketsOpt /** VariableDeclaratorId = Ident BracketsOpt
@ -3766,8 +3766,9 @@ public class JavacParser implements Parser {
Name typeName() { Name typeName() {
int pos = token.pos; int pos = token.pos;
Name name = ident(); Name name = ident();
if (isRestrictedTypeName(name, pos, true)) { Source source = restrictedTypeNameStartingAtSource(name, pos, true);
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowed(name, name == names.var ? Source.JDK10 : Source.JDK13)); if (source != null) {
reportSyntaxError(pos, Errors.RestrictedTypeNotAllowed(name, source));
} }
return name; return name;
} }

View File

@ -27,6 +27,10 @@ package tools.javac.combo;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.function.Consumer;
import javax.tools.Diagnostic;
import org.testng.ITestResult; import org.testng.ITestResult;
import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test; import org.testng.annotations.Test;
@ -100,4 +104,8 @@ public class CompilationTestCase extends JavacTemplateTestBase {
protected void assertFail(String expectedDiag, String... constructs) { protected void assertFail(String expectedDiag, String... constructs) {
assertCompile(expandMarkers(constructs), () -> assertCompileFailed(expectedDiag), false); assertCompile(expandMarkers(constructs), () -> assertCompileFailed(expectedDiag), false);
} }
protected void assertFail(String expectedDiag, Consumer<Diagnostic<?>> diagConsumer, String... constructs) {
assertCompile(expandMarkers(constructs), () -> assertCompileFailed(expectedDiag, diagConsumer), false);
}
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -57,6 +57,15 @@ public class Diagnostics implements javax.tools.DiagnosticListener<JavaFileObjec
.collect(toList()); .collect(toList());
} }
public Diagnostic<?> getDiagWithKey(String key) {
for (Diagnostic<?> d : diags) {
if (d.getCode().equals(key)) {
return d;
}
}
return null;
}
/** Do the diagnostics contain the specified error key? */ /** Do the diagnostics contain the specified error key? */
public boolean containsErrorKey(String key) { public boolean containsErrorKey(String key) {
return diags.stream() return diags.stream()

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -38,6 +38,8 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import javax.tools.Diagnostic;
import javax.tools.JavaCompiler; import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject; import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject; import javax.tools.SimpleJavaFileObject;
@ -204,8 +206,20 @@ public abstract class JavacTemplateTestBase {
protected void assertCompileFailed(String key) { protected void assertCompileFailed(String key) {
if (!diags.errorsFound()) if (!diags.errorsFound())
fail("Expected failed compilation: " + key); fail("Expected failed compilation: " + key);
if (!diags.containsErrorKey(key)) if (!diags.containsErrorKey(key)) {
fail(String.format("Expected compilation error with %s, found %s", key, diags.keys())); fail(String.format("Expected compilation error with %s, found %s", key, diags.keys()));
}
}
protected void assertCompileFailed(String key, Consumer<Diagnostic<?>> diagConsumer) {
if (!diags.errorsFound())
fail("Expected failed compilation: " + key);
if (!diags.containsErrorKey(key)) {
fail(String.format("Expected compilation error with %s, found %s", key, diags.keys()));
} else {
// for additional checks
diagConsumer.accept(diags.getDiagWithKey(key));
}
} }
/** Assert that a previous call to compile() failed with a specific error key */ /** Assert that a previous call to compile() failed with a specific error key */

View File

@ -30,6 +30,7 @@
* @summary Negative compilation tests, and positive compilation (smoke) tests for records * @summary Negative compilation tests, and positive compilation (smoke) tests for records
* @library /lib/combo /tools/lib /tools/javac/lib * @library /lib/combo /tools/lib /tools/javac/lib
* @modules * @modules
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.code * jdk.compiler/com.sun.tools.javac.code
* jdk.compiler/com.sun.tools.javac.util * jdk.compiler/com.sun.tools.javac.util
* jdk.jdeps/com.sun.tools.classfile * jdk.jdeps/com.sun.tools.classfile
@ -86,9 +87,11 @@ import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute; import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
import com.sun.tools.classfile.TypeAnnotation; import com.sun.tools.classfile.TypeAnnotation;
import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper;
import com.sun.tools.javac.code.Attribute.TypeCompound; import com.sun.tools.javac.code.Attribute.TypeCompound;
import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol;
import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol;
import com.sun.tools.javac.util.JCDiagnostic;
import org.testng.annotations.Test; import org.testng.annotations.Test;
import tools.javac.combo.CompilationTestCase; import tools.javac.combo.CompilationTestCase;
@ -169,7 +172,15 @@ public class RecordCompilationTests extends CompilationTestCase {
"record record(int x) { }", "record record(int x) { }",
"enum record { A, B }", "enum record { A, B }",
"class R<record> { }")) { "class R<record> { }")) {
assertFail("compiler.err.restricted.type.not.allowed", s); assertFail(
"compiler.err.restricted.type.not.allowed",
diagWrapper -> {
JCDiagnostic diagnostic = ((DiagnosticSourceUnwrapper)diagWrapper).d;
Object[] args = diagnostic.getArgs();
Assert.check(args.length == 2);
Assert.check(args[1].toString().equals("JDK14"));
},
s);
} }
} }

View File

@ -1,4 +1,4 @@
WrongYieldTest.java:39:11: compiler.err.restricted.type.not.allowed: yield, 13 WrongYieldTest.java:39:11: compiler.err.restricted.type.not.allowed: yield, 14
WrongYieldTest.java:45:5: compiler.err.restricted.type.not.allowed.here: yield WrongYieldTest.java:45:5: compiler.err.restricted.type.not.allowed.here: yield
WrongYieldTest.java:123:15: compiler.err.restricted.type.not.allowed.here: yield WrongYieldTest.java:123:15: compiler.err.restricted.type.not.allowed.here: yield
WrongYieldTest.java:136:9: compiler.err.invalid.yield WrongYieldTest.java:136:9: compiler.err.invalid.yield