[analysis_server] Provide context message for duplicate definition diagnostics

Fixes https://github.com/dart-lang/sdk/issues/32762.

Change-Id: Ia2995f1065f599627d94065b2b94f0e99a7d1650
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252880
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Danny Tuppeny 2022-08-03 16:43:55 +00:00 committed by Commit Bot
parent a6f56aec88
commit e7df4c9b19
5 changed files with 323 additions and 133 deletions

View file

@ -17,6 +17,50 @@ class DiagnosticFactory {
/// Initialize a newly created diagnostic factory.
DiagnosticFactory();
/// Return a diagnostic indicating that [duplicateElement] reuses a name
/// already used by [originalElement].
AnalysisError duplicateDefinition(ErrorCode code, Element duplicateElement,
Element originalElement, List<Object> arguments) {
final duplicate = duplicateElement.nonSynthetic;
final original = originalElement.nonSynthetic;
return AnalysisError(
duplicate.source!,
duplicate.nameOffset,
duplicate.nameLength,
code,
arguments,
[
DiagnosticMessageImpl(
filePath: original.source!.fullName,
message: "The first definition of this name.",
offset: original.nameOffset,
length: original.nameLength,
url: null)
],
);
}
/// Return a diagnostic indicating that [duplicateNode] reuses a name
/// already used by [originalNode].
AnalysisError duplicateDefinitionForNodes(Source source, ErrorCode code,
AstNode duplicateNode, AstNode originalNode, List<Object> arguments) {
return AnalysisError(
source,
duplicateNode.offset,
duplicateNode.length,
code,
arguments,
[
DiagnosticMessageImpl(
filePath: source.fullName,
message: "The first definition of this name.",
offset: originalNode.offset,
length: originalNode.length,
url: null)
],
);
}
/// Return a diagnostic indicating that the [duplicateElement] (in a constant
/// set) is a duplicate of the [originalElement].
AnalysisError equalElementsInConstSet(

View file

@ -11,6 +11,7 @@ import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/diagnostic/diagnostic_factory.dart';
import 'package:analyzer/src/error/codes.dart';
class DuplicateDefinitionVerifier {
@ -18,6 +19,8 @@ class DuplicateDefinitionVerifier {
final LibraryElement _currentLibrary;
final ErrorReporter _errorReporter;
final DiagnosticFactory _diagnosticFactory = DiagnosticFactory();
DuplicateDefinitionVerifier(
this._inheritanceManager,
this._currentLibrary,
@ -31,10 +34,13 @@ class DuplicateDefinitionVerifier {
if (exceptionParameter != null && stackTraceParameter != null) {
String exceptionName = exceptionParameter.name.lexeme;
if (exceptionName == stackTraceParameter.name.lexeme) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.DUPLICATE_DEFINITION,
stackTraceParameter,
[exceptionName]);
_errorReporter.reportError(_diagnosticFactory
.duplicateDefinitionForNodes(
_errorReporter.source,
CompileTimeErrorCode.DUPLICATE_DEFINITION,
stackTraceParameter,
exceptionParameter,
[exceptionName]));
}
}
}
@ -525,11 +531,12 @@ class DuplicateDefinitionVerifier {
var previous = getterScope[name];
if (previous != null) {
if (!_isGetterSetterPair(element, previous)) {
_errorReporter.reportErrorForToken(
_errorReporter.reportError(_diagnosticFactory.duplicateDefinition(
getError(previous, element),
identifier,
element,
previous,
[name],
);
));
}
} else {
getterScope[name] = element;
@ -539,11 +546,12 @@ class DuplicateDefinitionVerifier {
if (element is PropertyAccessorElement && element.isSetter) {
previous = setterScope[name];
if (previous != null) {
_errorReporter.reportErrorForToken(
_errorReporter.reportError(_diagnosticFactory.duplicateDefinition(
getError(previous, element),
identifier,
element,
previous,
[name],
);
));
} else {
setterScope[name] = element;
}

View file

@ -22,7 +22,8 @@ class A {
A({this.a = 0, this.a = 1});
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1,
contextMessages: [message('/home/test/lib/test.dart', 29, 1)]),
]);
}
@ -33,7 +34,8 @@ class A {
A([this.a = 0, this.a = 1]);
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 41, 1,
contextMessages: [message('/home/test/lib/test.dart', 29, 1)]),
]);
}
@ -44,7 +46,8 @@ class A {
A([this.x = 1, this.x = 2]) {}
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 43, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 43, 1,
contextMessages: [message('/home/test/lib/test.dart', 31, 1)]),
]);
}
@ -55,7 +58,8 @@ class A {
A({required this.a, required this.a});
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 55, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 55, 1,
contextMessages: [message('/home/test/lib/test.dart', 38, 1)]),
]);
}
@ -66,7 +70,8 @@ class A {
A(this.a, this.a);
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 36, 1,
contextMessages: [message('/home/test/lib/test.dart', 28, 1)]),
]);
}
@ -77,7 +82,8 @@ class A {
A(this.x, this.x) {}
}
''', [
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 38, 1),
error(CompileTimeErrorCode.DUPLICATE_FIELD_FORMAL_PARAMETER, 38, 1,
contextMessages: [message('/home/test/lib/test.dart', 30, 1)]),
]);
}
}

View file

@ -25,7 +25,8 @@ import 'lib.dart' as p;
typedef p();
p.A a = p.A();
''', [
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 32, 1),
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 32, 1,
contextMessages: [message('/home/test/lib/test.dart', 21, 1)]),
]);
}
@ -53,7 +54,8 @@ import 'lib.dart' as p;
p() {}
p.A a = p.A();
''', [
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 24, 1),
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 24, 1,
contextMessages: [message('/home/test/lib/test.dart', 21, 1)]),
]);
}
@ -67,7 +69,8 @@ import 'lib.dart' as p;
var p = null;
p.A a = p.A();
''', [
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 28, 1),
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 28, 1,
contextMessages: [message('/home/test/lib/test.dart', 21, 1)]),
]);
}
@ -81,7 +84,8 @@ import 'lib.dart' as p;
class p {}
p.A a = p.A();
''', [
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 30, 1),
error(CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER, 30, 1,
contextMessages: [message('/home/test/lib/test.dart', 21, 1)]),
]);
}
}