Skip to content

Commit 09a7387

Browse files
author
Brian Slesinsky
committed
Clear stale elements in an unresolved TypeName
BUG=#25855 [email protected] Review URL: https://codereview.chromium.org/1745413002 .
1 parent 7adcf94 commit 09a7387

File tree

2 files changed

+50
-17
lines changed

2 files changed

+50
-17
lines changed

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

+9-17
Original file line numberDiff line numberDiff line change
@@ -11633,6 +11633,7 @@ class TypeResolverVisitor extends ScopedVisitor {
1163311633
Object visitTypeName(TypeName node) {
1163411634
super.visitTypeName(node);
1163511635
Identifier typeName = node.name;
11636+
_setElement(typeName, null); // Clear old Elements from previous run.
1163611637
TypeArgumentList argumentList = node.typeArguments;
1163711638
Element element = nameScope.lookup(typeName, definingLibrary);
1163811639
if (element == null) {
@@ -11781,8 +11782,6 @@ class TypeResolverVisitor extends ScopedVisitor {
1178111782
if (!elementValid) {
1178211783
if (element is MultiplyDefinedElement) {
1178311784
_setElement(typeName, element);
11784-
} else {
11785-
_setElement(typeName, null);
1178611785
}
1178711786
typeName.staticType = _undefinedType;
1178811787
node.type = _undefinedType;
@@ -11847,7 +11846,6 @@ class TypeResolverVisitor extends ScopedVisitor {
1184711846
StaticWarningCode.NOT_A_TYPE, typeName, [typeName.name]);
1184811847
}
1184911848
}
11850-
_setElement(typeName, null);
1185111849
typeName.staticType = _dynamicType;
1185211850
node.type = _dynamicType;
1185311851
return null;
@@ -12348,25 +12346,19 @@ class TypeResolverVisitor extends ScopedVisitor {
1234812346
}
1234912347

1235012348
/**
12351-
* If the given [element] is not `null`, set `staticElement` of the
12352-
* [typeName] to it. If the [typeName] is a prefixed identifier, and the
12353-
* prefix can be resolved to a not `null` element, set also the
12354-
* `staticElement` of the prefix.
12349+
* Records the new Element for a TypeName's Identifier.
12350+
*
12351+
* A null may be passed in to indicate that the element can't be resolved.
12352+
* (During a re-run of a task, it's important to clear any previous value
12353+
* of the element.)
1235512354
*/
1235612355
void _setElement(Identifier typeName, Element element) {
1235712356
if (typeName is SimpleIdentifier) {
12358-
if (element != null) {
12359-
typeName.staticElement = element;
12360-
}
12357+
typeName.staticElement = element;
1236112358
} else if (typeName is PrefixedIdentifier) {
12362-
if (element != null) {
12363-
typeName.identifier.staticElement = element;
12364-
}
12359+
typeName.identifier.staticElement = element;
1236512360
SimpleIdentifier prefix = typeName.prefix;
12366-
Element prefixElement = nameScope.lookup(prefix, definingLibrary);
12367-
if (prefixElement != null) {
12368-
prefix.staticElement = prefixElement;
12369-
}
12361+
prefix.staticElement = nameScope.lookup(prefix, definingLibrary);
1237012362
}
1237112363
}
1237212364

pkg/analyzer/test/generated/resolver_test.dart

+41
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'package:analyzer/dart/ast/visitor.dart';
1212
import 'package:analyzer/dart/element/element.dart';
1313
import 'package:analyzer/dart/element/type.dart';
1414
import 'package:analyzer/src/context/context.dart';
15+
import 'package:analyzer/src/dart/ast/ast.dart'
16+
show SimpleIdentifierImpl, PrefixedIdentifierImpl;
1517
import 'package:analyzer/src/dart/element/element.dart';
1618
import 'package:analyzer/src/dart/element/member.dart';
1719
import 'package:analyzer/src/dart/element/type.dart';
@@ -17074,6 +17076,30 @@ class TypeResolverVisitorTest {
1707417076
_listener.assertNoErrors();
1707517077
}
1707617078

17079+
void test_visitTypeName_noParameters_noArguments_undefined() {
17080+
SimpleIdentifier id = AstFactory.identifier3("unknown")
17081+
..staticElement = new _StaleElement();
17082+
TypeName typeName = new TypeName(id, null);
17083+
_resolveNode(typeName, []);
17084+
expect(typeName.type, UndefinedTypeImpl.instance);
17085+
expect(typeName.name.staticElement, null);
17086+
_listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]);
17087+
}
17088+
17089+
void test_visitTypeName_prefixed_noParameters_noArguments_undefined() {
17090+
SimpleIdentifier prefix = AstFactory.identifier3("unknownPrefix")
17091+
..staticElement = new _StaleElement();
17092+
SimpleIdentifier suffix = AstFactory.identifier3("unknownSuffix")
17093+
..staticElement = new _StaleElement();
17094+
TypeName typeName =
17095+
new TypeName(AstFactory.identifier(prefix, suffix), null);
17096+
_resolveNode(typeName, []);
17097+
expect(typeName.type, UndefinedTypeImpl.instance);
17098+
expect(prefix.staticElement, null);
17099+
expect(suffix.staticElement, null);
17100+
_listener.assertErrorsWithCodes([StaticWarningCode.UNDEFINED_CLASS]);
17101+
}
17102+
1707717103
void test_visitTypeName_parameters_arguments() {
1707817104
ClassElement classA = ElementFactory.classElement2("A", ["E"]);
1707917105
ClassElement classB = ElementFactory.classElement2("B");
@@ -17233,6 +17259,21 @@ class _SimpleResolverTest_localVariable_types_invoked
1723317259
}
1723417260
}
1723517261

17262+
/**
17263+
* Represents an element left over from a previous resolver run.
17264+
*
17265+
* A _StaleElement should always be replaced with either null or a new Element.
17266+
*/
17267+
class _StaleElement extends ElementImpl {
17268+
_StaleElement() : super("_StaleElement", -1);
17269+
17270+
@override
17271+
accept(_) => throw "_StaleElement shouldn't be visited";
17272+
17273+
@override
17274+
get kind => throw "_StaleElement's kind shouldn't be accessed";
17275+
}
17276+
1723617277
/**
1723717278
* Shared infrastructure for [StaticTypeAnalyzer2Test] and
1723817279
* [StrongModeStaticTypeAnalyzer2Test].

0 commit comments

Comments
 (0)