Consistency in messages about duplication

Change-Id: I2d29c4f08d55d97453cc44344036c54e70e8a155
Reviewed-on: https://dart-review.googlesource.com/75900
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Peter von der Ahé <ahe@google.com>
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
index 2838eb7..355da1a 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_library_builder.dart
@@ -23,7 +23,7 @@
 import '../fasta_codes.dart'
     show
         Message,
-        templateDuplicatedDefinition,
+        templateDuplicatedDeclaration,
         templateTypeNotFound,
         templateUnspecified;
 
@@ -154,7 +154,7 @@
     if (builder.parent == this) return builder;
     return new KernelInvalidTypeBuilder(
         name,
-        templateDuplicatedDefinition
+        templateDuplicatedDeclaration
             .withArguments(name)
             .withLocation(fileUri, charOffset, name.length));
   }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 03735bf..71abcf1 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1977,22 +1977,62 @@
     tip: r"""Try removing all but one prefix.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templateDuplicatedDefinition =
+const Template<Message Function(String name)> templateDuplicatedDeclaration =
     const Template<Message Function(String name)>(
-        messageTemplate: r"""Duplicated definition of '#name'.""",
-        withArguments: _withArgumentsDuplicatedDefinition);
+        messageTemplate: r"""'#name' is already declared in this scope.""",
+        withArguments: _withArgumentsDuplicatedDeclaration);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeDuplicatedDefinition =
+const Code<Message Function(String name)> codeDuplicatedDeclaration =
     const Code<Message Function(String name)>(
-  "DuplicatedDefinition",
-  templateDuplicatedDefinition,
+        "DuplicatedDeclaration", templateDuplicatedDeclaration,
+        analyzerCode: "DUPLICATE_DEFINITION");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedDeclaration(String name) {
+  return new Message(codeDuplicatedDeclaration,
+      message: """'${name}' is already declared in this scope.""",
+      arguments: {'name': name});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name)>
+    templateDuplicatedDeclarationCause =
+    const Template<Message Function(String name)>(
+        messageTemplate: r"""Previous declaration of '#name'.""",
+        withArguments: _withArgumentsDuplicatedDeclarationCause);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedDeclarationCause =
+    const Code<Message Function(String name)>(
+        "DuplicatedDeclarationCause", templateDuplicatedDeclarationCause,
+        severity: Severity.context);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsDuplicatedDeclarationCause(String name) {
+  return new Message(codeDuplicatedDeclarationCause,
+      message: """Previous declaration of '${name}'.""",
+      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)>(
+        messageTemplate:
+            r"""Can't use '#name' because it is declared more than once.""",
+        withArguments: _withArgumentsDuplicatedDeclarationUse);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name)> codeDuplicatedDeclarationUse =
+    const Code<Message Function(String name)>(
+  "DuplicatedDeclarationUse",
+  templateDuplicatedDeclarationUse,
 );
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsDuplicatedDefinition(String name) {
-  return new Message(codeDuplicatedDefinition,
-      message: """Duplicated definition of '${name}'.""",
+Message _withArgumentsDuplicatedDeclarationUse(String name) {
+  return new Message(codeDuplicatedDeclarationUse,
+      message: """Can't use '${name}' because it is declared more than once.""",
       arguments: {'name': name});
 }
 
@@ -2116,44 +2156,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templateDuplicatedName =
-    const Template<Message Function(String name)>(
-        messageTemplate: r"""'#name' is already declared in this scope.""",
-        withArguments: _withArgumentsDuplicatedName);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeDuplicatedName =
-    const Code<Message Function(String name)>(
-        "DuplicatedName", templateDuplicatedName,
-        analyzerCode: "DUPLICATE_DEFINITION");
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsDuplicatedName(String name) {
-  return new Message(codeDuplicatedName,
-      message: """'${name}' is already declared in this scope.""",
-      arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<Message Function(String name)> templateDuplicatedNameCause =
-    const Template<Message Function(String name)>(
-        messageTemplate: r"""Previous declaration of '#name'.""",
-        withArguments: _withArgumentsDuplicatedNameCause);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeDuplicatedNameCause =
-    const Code<Message Function(String name)>(
-        "DuplicatedNameCause", templateDuplicatedNameCause,
-        severity: Severity.context);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsDuplicatedNameCause(String name) {
-  return new Message(codeDuplicatedNameCause,
-      message: """Previous declaration of '${name}'.""",
-      arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         String
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 87570fa..adf249b 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -386,8 +386,8 @@
       // This reports an error for duplicated declarations in the same scope:
       // `{ var x; var x; }`
       wrapVariableInitializerInError(
-          variable, fasta.templateDuplicatedName, <LocatedMessage>[
-        fasta.templateDuplicatedNameCause
+          variable, fasta.templateDuplicatedDeclaration, <LocatedMessage>[
+        fasta.templateDuplicatedDeclarationCause
             .withArguments(name)
             .withLocation(uri, existing.charOffset, name.length)
       ]);
@@ -2309,10 +2309,7 @@
         if (existing == null) {
           scopeBuilder.addMember(name, builder);
         } else {
-          addProblem(fasta.templateDuplicatedName.withArguments(name),
-              builder.charOffset, name.length);
-          addProblem(fasta.templateDuplicatedNameCause.withArguments(name),
-              existing.charOffset, name.length);
+          reportDuplicatedDeclaration(existing, name, builder.charOffset);
         }
       }
     }
@@ -3290,10 +3287,12 @@
         forSyntheticToken: nameToken.isSynthetic,
         isFinal: true,
         isLocalFunction: true)
-      ..fileOffset = offsetForToken(nameToken);
-    if (scope.local[variable.name] != null) {
-      addProblem(fasta.templateDuplicatedName.withArguments(variable.name),
-          name.charOffset, nameToken.length);
+      ..fileOffset = name.charOffset;
+    // TODO(ahe): Why are we looking up in local scope, but declaring in parent
+    // scope?
+    Declaration existing = scope.local[name.name];
+    if (existing != null) {
+      reportDuplicatedDeclaration(existing, name.name, name.charOffset);
     }
     push(new FunctionDeclarationJudgment(
         variable,
@@ -4443,6 +4442,22 @@
   }
 
   @override
+  void reportDuplicatedDeclaration(
+      Declaration existing, String name, int charOffset) {
+    List<LocatedMessage> context = existing.isSynthetic
+        ? null
+        : <LocatedMessage>[
+            fasta.templateDuplicatedDeclarationCause
+                .withArguments(name)
+                .withLocation(
+                    existing.fileUri, existing.charOffset, name.length)
+          ];
+    addProblem(fasta.templateDuplicatedDeclaration.withArguments(name),
+        charOffset, name.length,
+        context: context);
+  }
+
+  @override
   void debugEvent(String name) {
     // printEvent('BodyBuilder: $name');
   }
@@ -4701,16 +4716,8 @@
     for (KernelFormalParameterBuilder parameter in parameters) {
       Declaration existing = local[parameter.name];
       if (existing != null) {
-        helper.addProblem(
-            fasta.templateDuplicatedName.withArguments(parameter.name),
-            parameter.charOffset,
-            parameter.name.length,
-            context: <LocatedMessage>[
-              fasta.templateDuplicatedNameCause
-                  .withArguments(parameter.name)
-                  .withLocation(existing.fileUri, existing.charOffset,
-                      parameter.name.length)
-            ]);
+        helper.reportDuplicatedDeclaration(
+            existing, parameter.name, parameter.charOffset);
       } else {
         local[parameter.name] = parameter;
       }
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 4c8a138..6629dba 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -23,7 +23,7 @@
 import 'forest.dart' show Forest;
 
 import 'kernel_builder.dart'
-    show KernelTypeBuilder, PrefixBuilder, UnresolvedType;
+    show Declaration, KernelTypeBuilder, PrefixBuilder, UnresolvedType;
 
 import 'kernel_ast_api.dart'
     show
@@ -150,4 +150,7 @@
 
   List<DartType> buildDartTypeArguments(
       List<UnresolvedType<KernelTypeBuilder>> unresolvedTypes);
+
+  void reportDuplicatedDeclaration(
+      Declaration existing, String name, int charOffset);
 }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
index 1efee63..208c345 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_enum_builder.dart
@@ -30,9 +30,10 @@
 
 import '../fasta_codes.dart'
     show
+        LocatedMessage,
         messageNoUnnamedConstructorInObject,
-        noLength,
-        templateDuplicatedName,
+        templateDuplicatedDeclaration,
+        templateDuplicatedDeclarationCause,
         templateEnumConstantSameNameAsEnclosing;
 
 import '../modifier.dart' show constMask, finalMask, staticMask;
@@ -171,9 +172,19 @@
         String name = enumConstantInfo.name;
         int charOffset = enumConstantInfo.charOffset;
         String documentationComment = enumConstantInfo.documentationComment;
-        if (members.containsKey(name)) {
-          parent.addProblem(templateDuplicatedName.withArguments(name),
-              charOffset, noLength, parent.fileUri);
+        MemberBuilder existing = members[name];
+        if (existing != null) {
+          List<LocatedMessage> context = existing.isSynthetic
+              ? null
+              : <LocatedMessage>[
+                  templateDuplicatedDeclarationCause
+                      .withArguments(name)
+                      .withLocation(
+                          parent.fileUri, existing.charOffset, name.length)
+                ];
+          parent.addProblem(templateDuplicatedDeclaration.withArguments(name),
+              charOffset, name.length, parent.fileUri,
+              context: context);
           enumConstantInfos[i] = null;
           continue;
         }
@@ -181,7 +192,7 @@
           parent.addProblem(
               templateEnumConstantSameNameAsEnclosing.withArguments(name),
               charOffset,
-              noLength,
+              name.length,
               parent.fileUri);
           enumConstantInfos[i] = null;
           continue;
@@ -288,7 +299,8 @@
       // unnamed constructor requires no arguments. But that information isn't
       // always available at this point, and it's not really a situation that
       // can happen unless you start modifying the SDK sources.
-      addProblem(messageNoUnnamedConstructorInObject, -1, noLength);
+      library.addProblem(messageNoUnnamedConstructorInObject,
+          objectClass.charOffset, objectClass.name.length, objectClass.fileUri);
     } else {
       constructor.initializers.add(
           new SuperInitializer(superConstructor.target, new Arguments.empty())
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index a03b174..42dc27d 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -12,7 +12,7 @@
         Message,
         messageInternalProblemExtendingUnmodifiableScope,
         templateAccessError,
-        templateDuplicatedName,
+        templateDuplicatedDeclarationUse,
         templateDuplicatedNamePreviouslyUsedCause;
 
 import 'problems.dart' show internalProblem, unsupported;
@@ -351,5 +351,7 @@
 
   Declaration get parent => null;
 
-  Message get message => templateDuplicatedName.withArguments(name);
+  Message get message => templateDuplicatedDeclarationUse.withArguments(name);
+
+  // TODO(ahe): Also provide context.
 }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index 5ffbc32..10a1746 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -58,7 +58,8 @@
         templateCouldNotParseUri,
         templateDeferredPrefixDuplicated,
         templateDeferredPrefixDuplicatedCause,
-        templateDuplicatedDefinition,
+        templateDuplicatedDeclaration,
+        templateDuplicatedDeclarationCause,
         templateMissingPartOf,
         templateNotAPrefixInTypeAnnotation,
         templatePartOfInLibrary,
@@ -529,14 +530,18 @@
           return computeAmbiguousDeclaration(
               name, existing, member, charOffset);
         });
-    } else if (isDuplicatedDefinition(existing, declaration)) {
-      addProblem(templateDuplicatedDefinition.withArguments(name), charOffset,
-          noLength, fileUri);
+    } else if (isDuplicatedDeclaration(existing, declaration)) {
+      addProblem(templateDuplicatedDeclaration.withArguments(name), charOffset,
+          name.length, fileUri,
+          context: <LocatedMessage>[
+            templateDuplicatedDeclarationCause.withArguments(name).withLocation(
+                existing.fileUri, existing.charOffset, name.length)
+          ]);
     }
     return members[name] = declaration;
   }
 
-  bool isDuplicatedDefinition(Declaration existing, Declaration other) {
+  bool isDuplicatedDeclaration(Declaration existing, Declaration other) {
     if (existing == null) return false;
     Declaration next = existing.next;
     if (next == null) {
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 96ef8c84..10fc532 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -99,6 +99,10 @@
 DirectiveAfterDeclaration/script2: Fail
 DuplicateDeferred/example: Fail
 DuplicatePrefix/example: Fail
+DuplicatedDeclaration/script: Fail
+DuplicatedDeclarationUse/analyzerCode: Fail # No corresponding analyzer code.
+DuplicatedDeclarationUse/script1: Fail # This test can't pass.
+DuplicatedDeclarationUse/script2: Fail # Wrong error.
 DuplicatedDefinition/analyzerCode: Fail
 DuplicatedDefinition/example: Fail
 DuplicatedExportInType/analyzerCode: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 5504e4b..9f85ec7 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2094,17 +2094,60 @@
   script:
     - "dynamic<T>(x) => 0"
 
-DuplicatedDefinition:
-  template: "Duplicated definition of '#name'."
-
-DuplicatedName:
+# Use this message when a duplicated declaration is introduced.  For example:
+#
+#    class C {} // First declaration (related information points here).
+#    class C {} // Duplicated declaration (error here).
+#    main() {
+#      new C(); // Use of duplicated declaration.
+#    }
+#
+# We follow the convention from C that a definition is the unique element that
+# provides the implementation of a name, and a declaration may not be unique
+# (for example, forward declaration). Using this terminology, one could argue
+# that a method that is abstract or external is a declaration, not a
+# definition. Similarly, imported names are declarations, not
+# definitions. Consequently, it is more convenient to use the word
+# "declaration" instead of "definition" as the former implies less.
+DuplicatedDeclaration:
   template: "'#name' is already declared in this scope."
   analyzerCode: DUPLICATE_DEFINITION
+  script: |
+    class C {} // First declaration (related information points here).
+    class C {} // Duplicated declaration (error here).
+    main() {
+      // The following line is commented out as it would lead to an extraneous
+      // diagnostic.
+      // new C(); // Use of duplicated declaration.
+    }
 
-DuplicatedNameCause:
+DuplicatedDeclarationCause:
   template: "Previous declaration of '#name'."
   severity: CONTEXT
 
+# Use this message when a duplicated declaration is used.
+DuplicatedDeclarationUse:
+  template: "Can't use '#name' because it is declared more than once."
+  script:
+    - main.dart: |
+        // This test can't pass as tests must produce only one error message.
+        class C {} // First declaration (related information points here).
+        class C {} // Duplicated declaration (error here).
+        main() {
+          new C(); // Use of duplicated declaration.
+        }
+    - main.dart: |
+        import 'lib1.dart';
+        import 'lib2.dart';
+
+        main() {
+          new C(); // Use of duplicated declaration.
+        }
+      lib1.dart: |
+        class C {}
+      lib2.dart: |
+        class C {}
+
 DuplicatedNamePreviouslyUsed:
   template: "Can't declare '#name' because it was already used in this scope."
   analyzerCode: REFERENCED_BEFORE_DECLARATION
diff --git a/pkg/front_end/testcases/bug31124.dart.direct.expect b/pkg/front_end/testcases/bug31124.dart.direct.expect
index 0bbc4a3..f2376e3 100644
--- a/pkg/front_end/testcases/bug31124.dart.direct.expect
+++ b/pkg/front_end/testcases/bug31124.dart.direct.expect
@@ -5,9 +5,12 @@
 // var a = () => 'b';a();
 //                      ^
 //
-// pkg/front_end/testcases/bug31124.dart:1:19: Error: Duplicated definition of 'a'.
+// pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
 // var a = () => 'b';a();
 //                   ^
+// pkg/front_end/testcases/bug31124.dart:1:5: Error: Previous declaration of 'a'.
+// var a = () => 'b';a();
+//     ^
 //
 // pkg/front_end/testcases/bug31124.dart:1:1: Error: Duplicated name: a
 // var a = () => 'b';a();
diff --git a/pkg/front_end/testcases/bug31124.dart.outline.expect b/pkg/front_end/testcases/bug31124.dart.outline.expect
index 9a100eb..768d9ef 100644
--- a/pkg/front_end/testcases/bug31124.dart.outline.expect
+++ b/pkg/front_end/testcases/bug31124.dart.outline.expect
@@ -5,9 +5,12 @@
 // var a = () => 'b';a();
 //                      ^
 //
-// pkg/front_end/testcases/bug31124.dart:1:19: Error: Duplicated definition of 'a'.
+// pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
 // var a = () => 'b';a();
 //                   ^
+// pkg/front_end/testcases/bug31124.dart:1:5: Error: Previous declaration of 'a'.
+// var a = () => 'b';a();
+//     ^
 
 library;
 import self as self;
diff --git a/pkg/front_end/testcases/bug31124.dart.strong.expect b/pkg/front_end/testcases/bug31124.dart.strong.expect
index 0bbc4a3..f2376e3 100644
--- a/pkg/front_end/testcases/bug31124.dart.strong.expect
+++ b/pkg/front_end/testcases/bug31124.dart.strong.expect
@@ -5,9 +5,12 @@
 // var a = () => 'b';a();
 //                      ^
 //
-// pkg/front_end/testcases/bug31124.dart:1:19: Error: Duplicated definition of 'a'.
+// pkg/front_end/testcases/bug31124.dart:1:19: Error: 'a' is already declared in this scope.
 // var a = () => 'b';a();
 //                   ^
+// pkg/front_end/testcases/bug31124.dart:1:5: Error: Previous declaration of 'a'.
+// var a = () => 'b';a();
+//     ^
 //
 // pkg/front_end/testcases/bug31124.dart:1:1: Error: Duplicated name: a
 // var a = () => 'b';a();
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect
index 6e74253..408963b 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect
@@ -4,9 +4,12 @@
 // class B {}
 // ^^^^^
 //
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: Duplicated definition of 'A'.
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
 // A()
 // ^
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Error: Previous declaration of 'A'.
+// class A {
+//       ^
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A
 // class A {
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
index 7a7b6ce..d0250ed 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
@@ -4,9 +4,12 @@
 // class B {}
 // ^^^^^
 //
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: Duplicated definition of 'A'.
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
 // A()
 // ^
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Error: Previous declaration of 'A'.
+// class A {
+//       ^
 
 library;
 import self as self;
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
index 6e74253..408963b 100644
--- a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
@@ -4,9 +4,12 @@
 // class B {}
 // ^^^^^
 //
-// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: Duplicated definition of 'A'.
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:20:1: Error: 'A' is already declared in this scope.
 // A()
 // ^
+// pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:7: Error: Previous declaration of 'A'.
+// class A {
+//       ^
 //
 // pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A
 // class A {
diff --git a/pkg/front_end/testcases/named_function_scope.dart b/pkg/front_end/testcases/named_function_scope.dart
index 010ffc7..97888e3 100644
--- a/pkg/front_end/testcases/named_function_scope.dart
+++ b/pkg/front_end/testcases/named_function_scope.dart
@@ -58,8 +58,8 @@
     // the function-type scope.
     var x =
         /*@error=NamedFunctionExpression*/
-        /*@error=DuplicatedName*/
-        T< /*@context=DuplicatedNameCause*/ T>() {};
+        /*@error=DuplicatedDeclaration*/
+        T< /*@context=DuplicatedDeclarationCause*/ T>() {};
   }
   {
     /*@context=DuplicatedNamePreviouslyUsedCause*/
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
index f991ae7..6a0a469 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.expect
@@ -37,15 +37,15 @@
 //     ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
-// pkg/front_end/testcases/named_function_scope.dart:62:45: Error: Previous declaration of 'T'.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
-//                                             ^
+// pkg/front_end/testcases/named_function_scope.dart:62:52: Error: Previous declaration of 'T'.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//                                                    ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:67:47: Error: Can't declare 'T' because it was already used in this scope.
 //     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
@@ -90,7 +90,7 @@
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 
 library;
@@ -144,7 +144,7 @@
   }
   {
     dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-        T< /*@context=DuplicatedNameCause*/ T>() {};
+        T< /*@context=DuplicatedDeclarationCause*/ T>() {};
         ^" in let final <T extends core::Object = dynamic>() → dynamic T = <T extends core::Object = dynamic>() → dynamic {} in T;
   }
   {
diff --git a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
index 0d95379..02bf73d 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.direct.transformed.expect
@@ -9,7 +9,7 @@
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 
 library;
@@ -63,7 +63,7 @@
   }
   {
     dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-        T< /*@context=DuplicatedNameCause*/ T>() {};
+        T< /*@context=DuplicatedDeclarationCause*/ T>() {};
         ^" in let final <T extends core::Object = dynamic>() → dynamic T = <T extends core::Object = dynamic>() → dynamic {} in T;
   }
   {
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
index b780412..38d058b 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.expect
@@ -37,15 +37,15 @@
 //     ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
-// pkg/front_end/testcases/named_function_scope.dart:62:45: Error: Previous declaration of 'T'.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
-//                                             ^
+// pkg/front_end/testcases/named_function_scope.dart:62:52: Error: Previous declaration of 'T'.
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
+//                                                    ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:67:47: Error: Can't declare 'T' because it was already used in this scope.
 //     T /*@error=DuplicatedNamePreviouslyUsed*/ T() {}
@@ -90,7 +90,7 @@
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:83:32: Error: 'T' isn't a type.
@@ -148,7 +148,7 @@
   }
   {
     dynamic x = let final dynamic #t4 = let dynamic _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-        T< /*@context=DuplicatedNameCause*/ T>() {};
+        T< /*@context=DuplicatedDeclarationCause*/ T>() {};
         ^" in let final <T extends core::Object = dynamic>() → dynamic T = <T extends core::Object = dynamic>() → dynamic {} in T;
   }
   {
diff --git a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
index 7df51d2..bffb97c 100644
--- a/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/named_function_scope.dart.strong.transformed.expect
@@ -9,7 +9,7 @@
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:62:9: Error: A function expression can't have a name.
-//         T< /*@context=DuplicatedNameCause*/ T>() {};
+//         T< /*@context=DuplicatedDeclarationCause*/ T>() {};
 //         ^
 //
 // pkg/front_end/testcases/named_function_scope.dart:83:32: Error: 'T' isn't a type.
@@ -67,7 +67,7 @@
   }
   {
     dynamic x = let final dynamic #t4 = let<BottomType> _ = null in invalid-expression "pkg/front_end/testcases/named_function_scope.dart:62:9: Error: 'T' is already declared in this scope.
-        T< /*@context=DuplicatedNameCause*/ T>() {};
+        T< /*@context=DuplicatedDeclarationCause*/ T>() {};
         ^" in let final <T extends core::Object = dynamic>() → dynamic T = <T extends core::Object = dynamic>() → dynamic {} in T;
   }
   {
diff --git a/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect b/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
index 8d6a922..6573f56 100644
--- a/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_29975.dart.outline.expect
@@ -1,6 +1,9 @@
 // Formatted problems:
 //
-// pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: Duplicated definition of 'F'.
+// pkg/front_end/testcases/regress/issue_29975.dart:6:14: Error: 'F' is already declared in this scope.
+// typedef void F();
+//              ^
+// pkg/front_end/testcases/regress/issue_29975.dart:5:14: Error: Previous declaration of 'F'.
 // typedef void F();
 //              ^