Skip to content

Commit 4af0918

Browse files
johnniwintherCommit Queue
authored andcommitted
[analyzer] Report error on the first unresolved identifier
When reporting the "The name 'X' isn't a class." error in instance creation expressions, the mentioned name was the last name even when the previous name was unresolved. This lead to the misleading message the "The name 'named' isn't a class." for `new Class.named()` when `Class` was *not* resolved. This changes the messaging to handle the case where a prefix of the instance creation is not resolved and report "Undefined name 'X'." in such cases, since we don't know whether 'X' was meant to be a class or just a prefix. Change-Id: I57ef1dfa229647424855b1f9f8d43e1890094563 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/448301 Reviewed-by: Brian Wilkerson <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Erik Ernst <[email protected]>
1 parent 1484ea4 commit 4af0918

File tree

7 files changed

+1400
-15
lines changed

7 files changed

+1400
-15
lines changed

pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -538,14 +538,32 @@ class _ErrorHelper {
538538
var instanceCreation = constructorName.parent;
539539
if (instanceCreation is InstanceCreationExpression) {
540540
var errorRange = _getErrorRange(node, skipImportPrefix: true);
541-
diagnosticReporter.atOffset(
542-
offset: errorRange.offset,
543-
length: errorRange.length,
544-
diagnosticCode: instanceCreation.isConst
545-
? CompileTimeErrorCode.constWithNonType
546-
: CompileTimeErrorCode.newWithNonType,
547-
arguments: [node.name.lexeme],
548-
);
541+
var importPrefix = node.importPrefix;
542+
if (importPrefix != null && importPrefix.element == null) {
543+
// The constructor name is in two or three parts and the first part,
544+
// which is either a prefix or a class name, is unresolved. In this
545+
// case, report that the first name is undefined, instead of reporting
546+
// that the last name is not a class.
547+
// TODO(johnniwinther): We could report "Undefined prefix 'x'." when
548+
// we know it can only be a prefix, for instance in `x.y.z()`.
549+
String prefixOrClassName = importPrefix.name.lexeme;
550+
diagnosticReporter.atOffset(
551+
offset: errorRange.offset,
552+
length: errorRange.length,
553+
diagnosticCode: CompileTimeErrorCode.undefinedIdentifier,
554+
arguments: [prefixOrClassName],
555+
);
556+
} else {
557+
String className = node.name.lexeme;
558+
diagnosticReporter.atOffset(
559+
offset: errorRange.offset,
560+
length: errorRange.length,
561+
diagnosticCode: instanceCreation.isConst
562+
? CompileTimeErrorCode.constWithNonType
563+
: CompileTimeErrorCode.newWithNonType,
564+
arguments: [className],
565+
);
566+
}
549567
return true;
550568
}
551569
}

pkg/analyzer/test/src/dart/resolution/instance_creation_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,7 +2540,7 @@ void f() {
25402540
}
25412541
25422542
''',
2543-
[error(CompileTimeErrorCode.newWithNonType, 17, 16)],
2543+
[error(CompileTimeErrorCode.undefinedIdentifier, 17, 16)],
25442544
);
25452545

25462546
var node = findNode.singleInstanceCreationExpression;
@@ -2577,7 +2577,7 @@ void f() {
25772577
}
25782578
25792579
''',
2580-
[error(CompileTimeErrorCode.newWithNonType, 17, 14)],
2580+
[error(CompileTimeErrorCode.undefinedIdentifier, 17, 14)],
25812581
);
25822582

25832583
var node = findNode.singleInstanceCreationExpression;

0 commit comments

Comments
 (0)