diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart index f63fd3766bb4..205a82283c63 100644 --- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart +++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart @@ -396,6 +396,9 @@ class NamedTypeResolver with ScopeHelpers { importPrefixElement.getMethod(name) ?? importPrefixElement.getSetter(name); } + var elementKind = element != null + ? _ErrorHelper._getElementKindDescription(element) + : 'not a type'; var fragment = element?.firstFragment; var source = fragment?.libraryFragment?.source; var nameOffset = fragment?.nameOffset; @@ -403,7 +406,7 @@ class NamedTypeResolver with ScopeHelpers { offset: importPrefix.offset, length: nameToken.end - importPrefix.offset, diagnosticCode: diag.notAType, - arguments: ['${importPrefix.name.lexeme}.${nameToken.lexeme}'], + arguments: ['${importPrefix.name.lexeme}.${nameToken.lexeme}', elementKind], contextMessages: [ if (source != null && nameOffset != null) DiagnosticMessageImpl( @@ -663,6 +666,7 @@ class _ErrorHelper { if (element != null) { var errorRange = _getErrorRange(node); var name = node.name.lexeme; + var elementKind = _getElementKindDescription(element); var fragment = element.firstFragment; var source = fragment.libraryFragment?.source; var nameOffset = fragment.nameOffset; @@ -670,7 +674,7 @@ class _ErrorHelper { offset: errorRange.offset, length: errorRange.length, diagnosticCode: diag.notAType, - arguments: [name], + arguments: [name, elementKind], contextMessages: [ if (source != null && nameOffset != null) DiagnosticMessageImpl( @@ -758,4 +762,37 @@ class _ErrorHelper { static bool _isTypeInTypeArgumentList(NamedType node) { return node.parent is TypeArgumentList; } + + /// Returns a human-readable description of what kind of element this is. + static String _getElementKindDescription(Element element) { + if (element is PropertyAccessorElement) { + if (element.isSetter) { + return 'a setter'; + } else { + return 'a getter'; + } + } else if (element is FunctionElement) { + return 'a function'; + } else if (element is MethodElement) { + return 'a method'; + } else if (element is ConstructorElement) { + return 'a constructor'; + } else if (element is VariableElement) { + if (element is FieldElement) { + return 'a field'; + } else if (element is TopLevelVariableElement) { + return 'a top-level variable'; + } else if (element is LocalVariableElement) { + return 'a local variable'; + } else if (element is ParameterElement) { + return 'a parameter'; + } + return 'a variable'; + } else if (element is ExtensionElement) { + return 'an extension'; + } else if (element is PrefixElement) { + return 'a prefix'; + } + return 'not a type'; + } } diff --git a/pkg/analyzer/lib/src/diagnostic/diagnostic.g.dart b/pkg/analyzer/lib/src/diagnostic/diagnostic.g.dart index 7147997ab236..70ba3a4f6401 100644 --- a/pkg/analyzer/lib/src/diagnostic/diagnostic.g.dart +++ b/pkg/analyzer/lib/src/diagnostic/diagnostic.g.dart @@ -12504,18 +12504,19 @@ notAssignedPotentiallyNonNullableLocalVariable = DiagnosticWithArguments( /// Parameters: /// String p0: the name that is not a type +/// String p1: the kind of element (e.g., 'a setter', 'a function') const DiagnosticWithArguments< - LocatableDiagnostic Function({required String p0}) + LocatableDiagnostic Function({required String p0, required String p1}) > notAType = DiagnosticWithArguments( name: 'not_a_type', - problemMessage: "{0} isn't a type.", + problemMessage: "'{0}' is {1}, but a type was expected.", correctionMessage: "Try correcting the name to match an existing type.", hasPublishedDocs: true, type: DiagnosticType.COMPILE_TIME_ERROR, uniqueName: 'not_a_type', withArguments: _withArgumentsNotAType, - expectedTypes: [ExpectedType.string], + expectedTypes: [ExpectedType.string, ExpectedType.string], ); /// Parameters: @@ -20208,8 +20209,8 @@ _withArgumentsNotAssignedPotentiallyNonNullableLocalVariable({ ); } -LocatableDiagnostic _withArgumentsNotAType({required String p0}) { - return LocatableDiagnosticImpl(diag.notAType, [p0]); +LocatableDiagnostic _withArgumentsNotAType({required String p0, required String p1}) { + return LocatableDiagnosticImpl(diag.notAType, [p0, p1]); } LocatableDiagnostic _withArgumentsNotBinaryOperator({required String p0}) { diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml index c0daae5496b4..2107d1a78143 100644 --- a/pkg/analyzer/messages.yaml +++ b/pkg/analyzer/messages.yaml @@ -13427,7 +13427,8 @@ CompileTimeErrorCode: type: compileTimeError parameters: String p0: the name that is not a type - problemMessage: "#p0 isn't a type." + String p1: the kind of element (e.g., 'a setter', 'a function') + problemMessage: "'#p0' is #p1, but a type was expected." correctionMessage: Try correcting the name to match an existing type. hasPublishedDocs: true documentation: |-