Improve diagnostics about duplication in enums

Change-Id: I20f8ab79a8dbe6f2604f64cc26c2a91f46fcd2c2
Reviewed-on: https://dart-review.googlesource.com/76600
Commit-Queue: Aske Simon Christensen <askesc@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Auto-Submit: Peter von der Ahé <ahe@google.com>
This commit is contained in:
Peter von der Ahé 2018-09-28 12:36:55 +00:00 committed by commit-bot@chromium.org
parent 8bf0e8e434
commit 3f1955a97b
6 changed files with 68 additions and 30 deletions

View file

@ -2087,6 +2087,32 @@ Message _withArgumentsDuplicatedDeclarationCause(String name) {
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(
String
name)> templateDuplicatedDeclarationSyntheticCause = const Template<
Message Function(String name)>(
messageTemplate:
r"""Previous declaration of '#name' is implied by this definition.""",
withArguments: _withArgumentsDuplicatedDeclarationSyntheticCause);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name)>
codeDuplicatedDeclarationSyntheticCause =
const Code<Message Function(String name)>(
"DuplicatedDeclarationSyntheticCause",
templateDuplicatedDeclarationSyntheticCause,
severity: Severity.context);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsDuplicatedDeclarationSyntheticCause(String name) {
return new Message(codeDuplicatedDeclarationSyntheticCause,
message:
"""Previous declaration of '${name}' is implied by this definition.""",
arguments: {'name': name});
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name)> templateDuplicatedDeclarationUse =
const Template<Message Function(String name)>(

View file

@ -34,6 +34,7 @@ import '../fasta_codes.dart'
messageNoUnnamedConstructorInObject,
templateDuplicatedDeclaration,
templateDuplicatedDeclarationCause,
templateDuplicatedDeclarationSyntheticCause,
templateEnumConstantSameNameAsEnclosing;
import '../modifier.dart' show constMask, finalMask, staticMask;
@ -170,12 +171,19 @@ class KernelEnumBuilder extends SourceClassBuilder
EnumConstantInfo enumConstantInfo = enumConstantInfos[i];
List<MetadataBuilder> metadata = enumConstantInfo.metadata;
String name = enumConstantInfo.name;
int charOffset = enumConstantInfo.charOffset;
String documentationComment = enumConstantInfo.documentationComment;
MemberBuilder existing = members[name];
if (existing != null) {
List<LocatedMessage> context = existing.isSynthetic
? null
// The existing declaration is synthetic if it has the same
// charOffset as the enclosing enum.
bool isSynthetic = existing.charOffset == charOffset;
List<LocatedMessage> context = isSynthetic
? <LocatedMessage>[
templateDuplicatedDeclarationSyntheticCause
.withArguments(name)
.withLocation(
parent.fileUri, charOffset, className.length)
]
: <LocatedMessage>[
templateDuplicatedDeclarationCause
.withArguments(name)
@ -183,13 +191,13 @@ class KernelEnumBuilder extends SourceClassBuilder
parent.fileUri, existing.charOffset, name.length)
];
parent.addProblem(templateDuplicatedDeclaration.withArguments(name),
charOffset, name.length, parent.fileUri,
enumConstantInfo.charOffset, name.length, parent.fileUri,
context: context);
enumConstantInfos[i] = null;
} else if (name == className) {
parent.addProblem(
templateEnumConstantSameNameAsEnclosing.withArguments(name),
charOffset,
enumConstantInfo.charOffset,
name.length,
parent.fileUri);
}
@ -199,7 +207,7 @@ class KernelEnumBuilder extends SourceClassBuilder
name,
constMask | staticMask,
parent,
charOffset,
enumConstantInfo.charOffset,
null,
true);
metadataCollector?.setDocumentationComment(

View file

@ -2203,6 +2203,10 @@ DuplicatedDeclarationCause:
template: "Previous declaration of '#name'."
severity: CONTEXT
DuplicatedDeclarationSyntheticCause:
template: "Previous declaration of '#name' is implied by this definition."
severity: CONTEXT
# Use this message when a duplicated declaration is used.
DuplicatedDeclarationUse:
template: "Can't use '#name' because it is declared more than once."

View file

@ -84,30 +84,30 @@
// pkg/front_end/testcases/duplicated_declarations.dart:83:3: Error: '_name' is already declared in this scope.
// _name,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:84:3: Error: 'index' is already declared in this scope.
// index,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:85:3: Error: 'toString' is already declared in this scope.
// toString,
// ^^^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:86:3: Error: 'values' is already declared in this scope.
// values,
// ^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:57:19: Error: Type 'C' not found.
// class Sub extends C {

View file

@ -84,30 +84,30 @@
// pkg/front_end/testcases/duplicated_declarations.dart:83:3: Error: '_name' is already declared in this scope.
// _name,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:84:3: Error: 'index' is already declared in this scope.
// index,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:85:3: Error: 'toString' is already declared in this scope.
// toString,
// ^^^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:86:3: Error: 'values' is already declared in this scope.
// values,
// ^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:57:19: Error: Type 'C' not found.
// class Sub extends C {

View file

@ -84,30 +84,30 @@
// pkg/front_end/testcases/duplicated_declarations.dart:83:3: Error: '_name' is already declared in this scope.
// _name,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of '_name' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:84:3: Error: 'index' is already declared in this scope.
// index,
// ^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'index' is implied by this definition.
// enum AnotherEnum {
// ^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:85:3: Error: 'toString' is already declared in this scope.
// toString,
// ^^^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'toString' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:86:3: Error: 'values' is already declared in this scope.
// values,
// ^^^^^^
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values'.
// pkg/front_end/testcases/duplicated_declarations.dart:79:6: Error: Previous declaration of 'values' is implied by this definition.
// enum AnotherEnum {
// ^^^^^^
// ^^^^^^^^^^^
//
// pkg/front_end/testcases/duplicated_declarations.dart:57:19: Error: Type 'C' not found.
// class Sub extends C {