8238838: spurious error message for compact constructors with throws clause
Reviewed-by: mcimadamore
This commit is contained in:
parent
f844943273
commit
4c707c1df3
@ -1086,7 +1086,7 @@ public class Attr extends JCTree.Visitor {
|
||||
TreeInfo.name(app.meth) == names._super) &&
|
||||
checkFirstConstructorStat(app, tree, false)) {
|
||||
log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
|
||||
Fragments.Canonical, tree.sym,
|
||||
Fragments.Canonical, tree.sym.name,
|
||||
Fragments.CanonicalMustNotContainExplicitConstructorInvocation));
|
||||
}
|
||||
}
|
||||
@ -1094,7 +1094,7 @@ public class Attr extends JCTree.Visitor {
|
||||
// also we want to check that no type variables have been defined
|
||||
if (!tree.typarams.isEmpty()) {
|
||||
log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
|
||||
Fragments.Canonical, tree.sym, Fragments.CanonicalMustNotDeclareTypeVariables));
|
||||
Fragments.Canonical, tree.sym.name, Fragments.CanonicalMustNotDeclareTypeVariables));
|
||||
}
|
||||
|
||||
/* and now we need to check that the constructor's arguments are exactly the same as those of the
|
||||
@ -1104,7 +1104,7 @@ public class Attr extends JCTree.Visitor {
|
||||
for (JCVariableDecl param: tree.params) {
|
||||
if (!types.isSameType(param.type, recordComponentTypes.head)) {
|
||||
log.error(param, Errors.InvalidCanonicalConstructorInRecord(
|
||||
Fragments.Canonical, tree.sym, Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
|
||||
Fragments.Canonical, tree.sym.name, Fragments.TypeMustBeIdenticalToCorrespondingRecordComponentType));
|
||||
}
|
||||
recordComponentTypes = recordComponentTypes.tail;
|
||||
}
|
||||
@ -1178,18 +1178,20 @@ public class Attr extends JCTree.Visitor {
|
||||
List<Name> initParamNames = tree.sym.params.map(p -> p.name);
|
||||
if (!initParamNames.equals(recordComponentNames)) {
|
||||
log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
|
||||
Fragments.Canonical, env.enclClass.sym, Fragments.CanonicalWithNameMismatch));
|
||||
Fragments.Canonical, env.enclClass.sym.name, Fragments.CanonicalWithNameMismatch));
|
||||
}
|
||||
if (!tree.sym.isPublic()) {
|
||||
log.error(tree, Errors.InvalidCanonicalConstructorInRecord(
|
||||
TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
|
||||
env.enclClass.sym, Fragments.CanonicalConstructorMustBePublic));
|
||||
env.enclClass.sym.name, Fragments.CanonicalConstructorMustBePublic));
|
||||
}
|
||||
if (tree.sym.type.asMethodType().thrown != null && !tree.sym.type.asMethodType().thrown.isEmpty()) {
|
||||
log.error(tree,
|
||||
Errors.InvalidCanonicalConstructorInRecord(
|
||||
TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical,
|
||||
env.enclClass.sym, Fragments.ThrowsClauseNotAllowedForCanonicalConstructor));
|
||||
env.enclClass.sym.name,
|
||||
Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(
|
||||
TreeInfo.isCompactConstructor(tree) ? Fragments.Compact : Fragments.Canonical)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2227,7 +2229,7 @@ public class Attr extends JCTree.Visitor {
|
||||
env.enclMethod != null &&
|
||||
TreeInfo.isCompactConstructor(env.enclMethod)) {
|
||||
log.error(env.enclMethod,
|
||||
Errors.InvalidCanonicalConstructorInRecord(Fragments.Compact, env.enclMethod.sym, Fragments.CanonicalCantHaveReturnStatement));
|
||||
Errors.InvalidCanonicalConstructorInRecord(Fragments.Compact, env.enclMethod.sym.name, Fragments.CanonicalCantHaveReturnStatement));
|
||||
} else {
|
||||
// Attribute return expression, if it exists, and check that
|
||||
// it conforms to result type of enclosing method.
|
||||
|
@ -4077,6 +4077,17 @@ public class JavacParser implements Parser {
|
||||
return List.of(methodDeclaratorRest(
|
||||
pos, mods, null, names.init, typarams,
|
||||
isInterface, true, isRecord, dc));
|
||||
} else if (isRecord && type.hasTag(IDENT) && token.kind == THROWS) {
|
||||
// trying to define a compact constructor with a throws clause
|
||||
log.error(DiagnosticFlag.SYNTAX, token.pos,
|
||||
Errors.InvalidCanonicalConstructorInRecord(
|
||||
Fragments.Compact,
|
||||
className,
|
||||
Fragments.ThrowsClauseNotAllowedForCanonicalConstructor(Fragments.Compact)));
|
||||
skip(false, true, false, false);
|
||||
return List.of(methodDeclaratorRest(
|
||||
pos, mods, null, names.init, typarams,
|
||||
isInterface, true, isRecord, dc));
|
||||
} else {
|
||||
pos = token.pos;
|
||||
Name name = ident();
|
||||
|
@ -3472,7 +3472,7 @@ compiler.misc.accessor.method.must.not.be.static=\
|
||||
accessor method must not be static
|
||||
|
||||
# canonical constructors
|
||||
# 0: fragment, 1: symbol, 2: fragment
|
||||
# 0: fragment, 1: name, 2: fragment
|
||||
compiler.err.invalid.canonical.constructor.in.record=\
|
||||
invalid {0} constructor in record {1}\n\
|
||||
({2})
|
||||
@ -3486,8 +3486,9 @@ compiler.misc.compact=\
|
||||
compiler.misc.canonical.constructor.must.be.public=\
|
||||
canonical constructor must be public
|
||||
|
||||
# 0: fragment
|
||||
compiler.misc.throws.clause.not.allowed.for.canonical.constructor=\
|
||||
throws clause not allowed for canonical constructor
|
||||
throws clause not allowed for {0} constructor
|
||||
|
||||
compiler.misc.canonical.with.name.mismatch=\
|
||||
invalid parameter names in canonical constructor
|
||||
|
@ -309,16 +309,26 @@ public class RecordCompilationTests extends CompilationTestCase {
|
||||
"record R(List<String> list) { # }",
|
||||
"R(List list) { this.list = list; }");
|
||||
|
||||
// ctor should not add checked exceptions
|
||||
// canonical ctor should not throw checked exceptions
|
||||
assertFail("compiler.err.invalid.canonical.constructor.in.record",
|
||||
"record R() { # }",
|
||||
"public R() throws Exception { }");
|
||||
|
||||
// not even checked exceptions
|
||||
// same for compact
|
||||
assertFail("compiler.err.invalid.canonical.constructor.in.record",
|
||||
"record R() { # }",
|
||||
"public R throws Exception { }");
|
||||
|
||||
// not even unchecked exceptions
|
||||
assertFail("compiler.err.invalid.canonical.constructor.in.record",
|
||||
"record R() { # }",
|
||||
"public R() throws IllegalArgumentException { }");
|
||||
|
||||
// ditto
|
||||
assertFail("compiler.err.invalid.canonical.constructor.in.record",
|
||||
"record R() { # }",
|
||||
"public R throws IllegalArgumentException { }");
|
||||
|
||||
// If types match, names must match
|
||||
assertFail("compiler.err.invalid.canonical.constructor.in.record",
|
||||
"record R(int x, int y) { public R(int y, int x) { this.x = this.y = 0; }}");
|
||||
|
Loading…
x
Reference in New Issue
Block a user