CQ. ErrorReporter, use atElement() instead of reportErrorForElement()

Change-Id: Ife5f6d04ee7c15e7703db3ad81eb7707c7f00ceb
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/352053
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2024-02-13 17:16:07 +00:00 committed by Commit Queue
parent e349b3faef
commit 106db0d7b4
10 changed files with 216 additions and 141 deletions

View file

@ -65,6 +65,26 @@ class ErrorReporter {
Source get source => _source;
/// Report an error with the given [errorCode] and [arguments].
/// The [element] is used to compute the location of the error.
void atElement(
Element element,
ErrorCode errorCode, {
List<Object>? arguments,
List<DiagnosticMessage>? contextMessages,
Object? data,
}) {
var nonSynthetic = element.nonSynthetic;
atOffset(
errorCode: errorCode,
offset: nonSynthetic.nameOffset,
length: nonSynthetic.nameLength,
arguments: arguments,
contextMessages: contextMessages,
data: data,
);
}
/// Report an error with the given [errorCode] and [arguments].
/// The [node] is used to compute the location of the error.
void atNode(
@ -140,11 +160,15 @@ class ErrorReporter {
/// Report an error with the given [errorCode] and [arguments]. The [element]
/// is used to compute the location of the error.
@Deprecated('Use atElement() instead')
void reportErrorForElement(ErrorCode errorCode, Element element,
[List<Object>? arguments, List<DiagnosticMessage>? messages]) {
var nonSynthetic = element.nonSynthetic;
reportErrorForOffset(errorCode, nonSynthetic.nameOffset,
nonSynthetic.nameLength, arguments, messages);
atElement(
element,
errorCode,
arguments: arguments,
contextMessages: messages,
);
}
/// Report a diagnostic with the given [code] and [arguments]. The

View file

@ -413,8 +413,10 @@ class ConstantEvaluationEngine {
// TODO(paulberry): It would be really nice if we could extract enough
// information from the 'cycle' argument to provide the user with a
// description of the cycle.
errorReporter.reportErrorForElement(
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT, constant, []);
errorReporter.atElement(
constant,
CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT,
);
(constant as VariableElementImpl).evaluationResult =
InvalidConstant.forElement(
constant, CompileTimeErrorCode.RECURSIVE_COMPILE_TIME_CONSTANT);

View file

@ -109,10 +109,10 @@ class SharedTypeAnalyzerErrors
required PromotableElement variable,
required PromotableElement component,
}) {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.INCONSISTENT_PATTERN_VARIABLE_LOGICAL_OR,
_errorReporter.atElement(
component,
[variable.name],
CompileTimeErrorCode.INCONSISTENT_PATTERN_VARIABLE_LOGICAL_OR,
arguments: [variable.name],
);
}

View file

@ -241,22 +241,30 @@ class BaseOrFinalTypeVerifier {
? CompileTimeErrorCode.MIXIN_SUBTYPE_OF_FINAL_IS_NOT_BASE
: CompileTimeErrorCode
.SUBTYPE_OF_FINAL_IS_NOT_BASE_FINAL_OR_SEALED;
_errorReporter.reportErrorForElement(
errorCode,
element,
[element.displayName, baseOrFinalSuperElement.displayName],
superElement.isSealed ? contextMessages : null);
_errorReporter.atElement(
element,
errorCode,
arguments: [
element.displayName,
baseOrFinalSuperElement.displayName,
],
contextMessages: superElement.isSealed ? contextMessages : null,
);
return true;
} else if (baseOrFinalSuperElement.isBase) {
final errorCode = element is MixinElement
? CompileTimeErrorCode.MIXIN_SUBTYPE_OF_BASE_IS_NOT_BASE
: CompileTimeErrorCode
.SUBTYPE_OF_BASE_IS_NOT_BASE_FINAL_OR_SEALED;
_errorReporter.reportErrorForElement(
errorCode,
element,
[element.displayName, baseOrFinalSuperElement.displayName],
superElement.isSealed ? contextMessages : null);
_errorReporter.atElement(
element,
errorCode,
arguments: [
element.displayName,
baseOrFinalSuperElement.displayName,
],
contextMessages: superElement.isSealed ? contextMessages : null,
);
return true;
}
}

View file

@ -137,19 +137,19 @@ class DuplicateDefinitionVerifier {
if (accessor.isStatic) {
var instance = _getInterfaceMember(enumElement, baseName);
if (instance != null && baseName != 'values') {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
_errorReporter.atElement(
accessor,
[enumName, baseName, enumName],
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [enumName, baseName, enumName],
);
}
} else {
var inherited = _getInheritedMember(enumElement, baseName);
if (inherited is MethodElement) {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD,
_errorReporter.atElement(
accessor,
[
CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD,
arguments: [
enumElement.displayName,
baseName,
inherited.enclosingElement.displayName,
@ -164,19 +164,19 @@ class DuplicateDefinitionVerifier {
if (method.isStatic) {
var instance = _getInterfaceMember(enumElement, baseName);
if (instance != null) {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
_errorReporter.atElement(
method,
[enumName, baseName, enumName],
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [enumName, baseName, enumName],
);
}
} else {
var inherited = _getInheritedMember(enumElement, baseName);
if (inherited is PropertyAccessorElement) {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD,
_errorReporter.atElement(
method,
[
CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD,
arguments: [
enumElement.displayName,
baseName,
inherited.enclosingElement.displayName,
@ -514,12 +514,16 @@ class DuplicateDefinitionVerifier {
errorCode =
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_SETTER;
}
_errorReporter.reportErrorForElement(errorCode, constructor, [name]);
} else if (staticMember is MethodElement) {
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
_errorReporter.atElement(
constructor,
[name],
errorCode,
arguments: [name],
);
} else if (staticMember is MethodElement) {
_errorReporter.atElement(
constructor,
CompileTimeErrorCode.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD,
arguments: [name],
);
}
}

View file

@ -74,10 +74,10 @@ class GetterSetterTypesVerifier {
setterName = '$setterClassName.$setterName';
}
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.GETTER_NOT_SUBTYPE_SETTER_TYPES,
_errorReporter.atElement(
errorElement,
[getterName, getterType, setterType, setterName],
CompileTimeErrorCode.GETTER_NOT_SUBTYPE_SETTER_TYPES,
arguments: [getterName, getterType, setterType, setterName],
);
}
}
@ -102,10 +102,10 @@ class GetterSetterTypesVerifier {
if (setterType != null) {
if (!_typeSystem.isSubtypeOf(getterType, setterType)) {
var name = getter.name;
_errorReporter.reportErrorForElement(
CompileTimeErrorCode.GETTER_NOT_SUBTYPE_SETTER_TYPES,
_errorReporter.atElement(
getter,
[name, getterType, setterType, name],
CompileTimeErrorCode.GETTER_NOT_SUBTYPE_SETTER_TYPES,
arguments: [name, getterType, setterType, name],
);
}
}

View file

@ -529,18 +529,22 @@ class _ClassVerifier {
buffer.write(separator);
}
buffer.write(element.displayName);
reporter.reportErrorForElement(
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
classElement,
[className, buffer.toString()]);
reporter.atElement(
classElement,
CompileTimeErrorCode.RECURSIVE_INTERFACE_INHERITANCE,
arguments: [className, buffer.toString()],
);
return true;
} else {
// RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_EXTENDS or
// RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_IMPLEMENTS or
// RECURSIVE_INTERFACE_INHERITANCE_ON or
// RECURSIVE_INTERFACE_INHERITANCE_BASE_CASE_WITH
reporter.reportErrorForElement(
_getRecursiveErrorCode(element), classElement, [className]);
reporter.atElement(
classElement,
_getRecursiveErrorCode(element),
arguments: [className],
);
return true;
}
}

View file

@ -2015,12 +2015,15 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
if (method.isStatic) {
void reportStaticConflict(ExecutableElement inherited) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, method, [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName,
]);
errorReporter.atElement(
method,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName,
],
);
}
if (getter != null) {
@ -2040,12 +2043,15 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
}
void reportFieldConflict(PropertyAccessorElement inherited) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD, method, [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName
]);
errorReporter.atElement(
method,
CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD,
arguments: [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName
],
);
}
if (getter is PropertyAccessorElement) {
@ -2070,24 +2076,30 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
enclosingClass, Name(libraryUri, '$name='));
if (accessor.isStatic && inherited != null) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, accessor, [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName,
]);
errorReporter.atElement(
accessor,
CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
arguments: [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName,
],
);
conflictingDeclaredNames.add(name);
} else if (inherited is MethodElement) {
// Extension type accessors preclude inherited accessors/methods.
if (enclosingClass is ExtensionTypeElement) {
continue;
}
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD, accessor, [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName
]);
errorReporter.atElement(
accessor,
CompileTimeErrorCode.CONFLICTING_FIELD_AND_METHOD,
arguments: [
enclosingClass.displayName,
name,
inherited.enclosingElement.displayName
],
);
conflictingDeclaredNames.add(name);
}
}
@ -2104,15 +2116,15 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
final setterName = methodName.forSetter;
final setter = inherited[setterName];
if (setter is PropertyAccessorElement) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_INHERITED_METHOD_AND_SETTER,
errorReporter.atElement(
enclosingClass,
[
CompileTimeErrorCode.CONFLICTING_INHERITED_METHOD_AND_SETTER,
arguments: [
enclosingClass.kind.displayName,
enclosingClass.displayName,
methodName.name,
],
[
contextMessages: [
DiagnosticMessageImpl(
filePath: method.source.fullName,
message: formatList(
@ -2156,7 +2168,11 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
var code = enclosingClass is MixinElement
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
errorReporter.atElement(
typeParameter,
code,
arguments: [name],
);
}
// check members
if (enclosingClass.getNamedConstructor(name) != null ||
@ -2166,7 +2182,11 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
var code = enclosingClass is MixinElement
? CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_MIXIN
: CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_CLASS;
errorReporter.reportErrorForElement(code, typeParameter, [name]);
errorReporter.atElement(
typeParameter,
code,
arguments: [name],
);
}
}
}
@ -2178,20 +2198,20 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
var name = typeParameter.name;
// name is same as the name of the enclosing enum
if (element.name == name) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_ENUM,
errorReporter.atElement(
typeParameter,
[name],
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_ENUM,
arguments: [name],
);
}
// check members
if (element.getMethod(name) != null ||
element.getGetter(name) != null ||
element.getSetter(name) != null) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM,
errorReporter.atElement(
typeParameter,
[name],
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_ENUM,
arguments: [name],
);
}
}
@ -2204,21 +2224,23 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
var name = typeParameter.name;
// name is same as the name of the enclosing class
if (element.name == name) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE,
typeParameter,
[name]);
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION_TYPE,
arguments: [name],
);
}
// check members
if (element.getNamedConstructor(name) != null ||
element.getMethod(name) != null ||
element.getGetter(name) != null ||
element.getSetter(name) != null) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode
.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE,
typeParameter,
[name]);
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode
.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION_TYPE,
arguments: [name],
);
}
}
}
@ -2233,19 +2255,21 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
String name = typeParameter.name;
// name is same as the name of the enclosing class
if (_enclosingExtension!.name == name) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
typeParameter,
[name]);
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_EXTENSION,
arguments: [name],
);
}
// check members
if (_enclosingExtension!.getMethod(name) != null ||
_enclosingExtension!.getGetter(name) != null ||
_enclosingExtension!.getSetter(name) != null) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
typeParameter,
[name]);
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode.CONFLICTING_TYPE_VARIABLE_AND_MEMBER_EXTENSION,
arguments: [name],
);
}
}
}
@ -4239,10 +4263,14 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
var superUnnamedConstructor = superElement.unnamedConstructor;
if (superUnnamedConstructor != null) {
if (superUnnamedConstructor.isFactory) {
errorReporter.reportErrorForElement(
CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
errorReporter.atElement(
element,
[superElement.name, element.name, superUnnamedConstructor],
CompileTimeErrorCode.NON_GENERATIVE_IMPLICIT_CONSTRUCTOR,
arguments: [
superElement.name,
element.name,
superUnnamedConstructor,
],
);
return;
}
@ -4254,10 +4282,10 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
if (!_typeProvider.isNonSubtypableClass(superType.element)) {
// Don't report this diagnostic for non-subtypable classes because the
// real problem was already reported.
errorReporter.reportErrorForElement(
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
errorReporter.atElement(
element,
[superType, element.displayName],
CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
arguments: [superType, element.displayName],
);
}
}
@ -5518,23 +5546,23 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
if (!superVariance
.greaterThanOrEqual(typeParameterElementImpl.variance)) {
if (!typeParameterElementImpl.isLegacyCovariant) {
errorReporter.reportErrorForElement(
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode
.WRONG_EXPLICIT_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
typeParameter,
[
arguments: [
typeParameter.name,
typeParameterElementImpl.variance.toKeywordString(),
superVariance.toKeywordString(),
superInterface
superInterface,
],
);
} else {
errorReporter.reportErrorForElement(
errorReporter.atElement(
typeParameter,
CompileTimeErrorCode
.WRONG_TYPE_PARAMETER_VARIANCE_IN_SUPERINTERFACE,
typeParameter,
[typeParameter.name, superInterface],
arguments: [typeParameter.name, superInterface],
);
}
}
@ -6191,11 +6219,11 @@ class _MacroDiagnosticsReporter {
contextMessages: _convertMessages(diagnostic),
);
case ElementMacroDiagnosticTarget():
errorReporter.reportErrorForElement(
errorCode,
errorReporter.atElement(
target.element,
[diagnostic.message.message],
_convertMessages(diagnostic),
errorCode,
arguments: [diagnostic.message.message],
contextMessages: _convertMessages(diagnostic),
);
case TypeAnnotationMacroDiagnosticTarget():
var nodeLocation = _MacroTypeAnnotationLocationConverter(

View file

@ -22,27 +22,21 @@ main() {
class ErrorReporterTest extends PubPackageResolutionTest {
var listener = GatheringErrorListener();
test_creation() async {
var source = TestSource();
var reporter = ErrorReporter(listener, source);
expect(reporter, isNotNull);
}
test_reportErrorForElement_named() async {
test_atElement_named() async {
await resolveTestCode('class A {}');
var element = findElement.class_('A');
var reporter = ErrorReporter(listener, element.source);
reporter.reportErrorForElement(
CompileTimeErrorCode.CAST_TO_NON_TYPE,
reporter.atElement(
element,
['A'],
CompileTimeErrorCode.CAST_TO_NON_TYPE,
arguments: ['A'],
);
var error = listener.errors[0];
expect(error.offset, element.nameOffset);
}
test_reportErrorForElement_unnamed() async {
test_atElement_unnamed() async {
await resolveTestCode(r'''
import 'dart:async';
import 'dart:math';
@ -50,17 +44,17 @@ import 'dart:math';
var element = findElement.import('dart:math');
var reporter = ErrorReporter(listener, element.source);
reporter.reportErrorForElement(
CompileTimeErrorCode.CAST_TO_NON_TYPE,
reporter.atElement(
element,
['A'],
CompileTimeErrorCode.CAST_TO_NON_TYPE,
arguments: ['A'],
);
var error = listener.errors[0];
expect(error.offset, element.nameOffset);
}
test_reportErrorForNode_types_differentNames() async {
test_atNode_types_differentNames() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
newFile('$testPackageLibPath/b.dart', 'class B {}');
await resolveTestCode(r'''
@ -95,7 +89,7 @@ main() {
expect(error.message, isNot(contains('(')));
}
test_reportErrorForNode_types_sameName() async {
test_atNode_types_sameName() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
newFile('$testPackageLibPath/b.dart', 'class A {}');
await resolveTestCode(r'''
@ -129,7 +123,7 @@ main() {
expect(error.message, contains('('));
}
test_reportErrorForNode_types_sameName_functionType() async {
test_atNode_types_sameName_functionType() async {
newFile('$testPackageLibPath/a.dart', 'class A{}');
newFile('$testPackageLibPath/b.dart', 'class A{}');
await resolveTestCode(r'''
@ -159,7 +153,7 @@ main() {
expect(error.message, contains('b.dart'));
}
test_reportErrorForNode_types_sameName_nested() async {
test_atNode_types_sameName_nested() async {
newFile('$testPackageLibPath/a.dart', 'class A{}');
newFile('$testPackageLibPath/b.dart', 'class A{}');
await resolveTestCode(r'''
@ -190,6 +184,12 @@ main() {
expect(error.message, contains('b.dart'));
}
test_creation() async {
var source = TestSource();
var reporter = ErrorReporter(listener, source);
expect(reporter, isNotNull);
}
test_reportErrorForSpan() async {
var source = TestSource();
var reporter = ErrorReporter(listener, source);

View file

@ -75,6 +75,17 @@ class CollectingReporter extends ErrorReporter {
CollectingReporter(super.listener, super.source);
@override
void atElement(
Element element,
ErrorCode errorCode, {
List<Object>? arguments,
List<DiagnosticMessage>? contextMessages,
Object? data,
}) {
code = errorCode;
}
@override
void atNode(
AstNode node,
@ -97,12 +108,6 @@ class CollectingReporter extends ErrorReporter {
code = errorCode;
}
@override
void reportErrorForElement(ErrorCode errorCode, Element element,
[List<Object?>? arguments, List<DiagnosticMessage>? messages]) {
code = errorCode;
}
@Deprecated('Use atNode() instead')
@override
void reportErrorForNode(