Skip to content

Commit 8745cd5

Browse files
committed
Use new Scope directly to simplify TypeNameResolver.
Change-Id: Ib3e78f2faca8a8cbdfb16d1a1bf5dc414cbf01ac Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/155830 Reviewed-by: Brian Wilkerson <[email protected]>
1 parent 9e1b603 commit 8745cd5

File tree

3 files changed

+111
-88
lines changed

3 files changed

+111
-88
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ class ResolutionVisitor extends RecursiveAstVisitor<void> {
109109
libraryElement.typeSystem,
110110
typeProvider,
111111
isNonNullableByDefault,
112-
libraryElement,
113112
errorReporter,
114113
);
115114

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

Lines changed: 87 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ class TypeNameResolver {
2424
final TypeSystemImpl typeSystem;
2525
final DartType dynamicType;
2626
final bool isNonNullableByDefault;
27-
final LibraryElement definingLibrary; // TODO(scheglov) remove
2827
final ErrorReporter errorReporter;
2928

3029
Scope nameScope;
@@ -52,7 +51,7 @@ class TypeNameResolver {
5251
ConstructorName rewriteResult;
5352

5453
TypeNameResolver(this.typeSystem, TypeProvider typeProvider,
55-
this.isNonNullableByDefault, this.definingLibrary, this.errorReporter)
54+
this.isNonNullableByDefault, this.errorReporter)
5655
: dynamicType = typeProvider.dynamicType;
5756

5857
NullabilitySuffix get _noneOrStarSuffix {
@@ -69,55 +68,51 @@ class TypeNameResolver {
6968
rewriteResult = null;
7069

7170
var typeIdentifier = node.name;
71+
if (typeIdentifier is PrefixedIdentifier) {
72+
var prefix = typeIdentifier.prefix;
73+
var prefixName = prefix.name;
74+
var prefixElement = nameScope.lookup2(prefixName).getter;
75+
prefix.staticElement = prefixElement;
7276

73-
if (typeIdentifier is SimpleIdentifier && typeIdentifier.name == 'void') {
74-
node.type = VoidTypeImpl.instance;
75-
return;
76-
}
77+
if (prefixElement == null) {
78+
_resolveToElement(node, null);
79+
return;
80+
}
81+
82+
if (prefixElement is ClassElement) {
83+
_rewriteToConstructorName(node, typeIdentifier);
84+
return;
85+
}
7786

78-
// TODO(scheglov) Update to use `lookup2`.
79-
var element = nameScope.lookupIdentifier(typeIdentifier);
87+
if (prefixElement is PrefixElement) {
88+
var nameNode = typeIdentifier.identifier;
89+
var name = nameNode.name;
8090

81-
// TODO(scheglov) When fixing the previous TODO, report the prefix sooner.
82-
if (typeIdentifier is PrefixedIdentifier) {
83-
var prefix = typeIdentifier.prefix;
84-
var prefixElement = prefix.staticElement;
85-
if (prefixElement != null &&
86-
prefixElement is! PrefixElement &&
87-
prefixElement is! ClassElement) {
88-
errorReporter.reportErrorForNode(
89-
CompileTimeErrorCode.PREFIX_SHADOWED_BY_LOCAL_DECLARATION,
90-
prefix,
91-
[prefix.name],
92-
);
93-
node.type = dynamicType;
91+
var element = prefixElement.scope.lookup2(name).getter;
92+
nameNode.staticElement = element;
93+
_resolveToElement(node, element);
9494
return;
9595
}
96-
}
9796

98-
if (element is MultiplyDefinedElement) {
99-
_setElement(typeIdentifier, element);
97+
errorReporter.reportErrorForNode(
98+
CompileTimeErrorCode.PREFIX_SHADOWED_BY_LOCAL_DECLARATION,
99+
prefix,
100+
[prefix.name],
101+
);
100102
node.type = dynamicType;
101-
return;
102-
}
103-
104-
if (element != null) {
105-
_setElement(typeIdentifier, element);
106-
node.type = _instantiateElement(node, element);
107-
return;
108-
}
103+
} else {
104+
var nameNode = typeIdentifier as SimpleIdentifier;
105+
var name = nameNode.name;
109106

110-
// TODO(scheglov) Can we do rewriting better with using `lookup2`?
111-
if (_rewriteToConstructorName(node)) {
112-
return;
113-
}
107+
if (name == 'void') {
108+
node.type = VoidTypeImpl.instance;
109+
return;
110+
}
114111

115-
node.type = dynamicType;
116-
if (nameScope.shouldIgnoreUndefined(typeIdentifier)) {
117-
return;
112+
var element = nameScope.lookup2(name).getter;
113+
nameNode.staticElement = element;
114+
_resolveToElement(node, element);
118115
}
119-
120-
_ErrorHelper(errorReporter).reportNullOrNonTypeElement(node, null);
121116
}
122117

123118
/// Return type arguments, exactly [parameterCount].
@@ -306,61 +301,66 @@ class TypeNameResolver {
306301
}
307302
}
308303

304+
void _resolveToElement(TypeName node, Element element) {
305+
if (element == null) {
306+
node.type = dynamicType;
307+
if (!nameScope.shouldIgnoreUndefined(node.name)) {
308+
_ErrorHelper(errorReporter).reportNullOrNonTypeElement(node, null);
309+
}
310+
return;
311+
}
312+
313+
if (element is MultiplyDefinedElement) {
314+
node.type = dynamicType;
315+
return;
316+
}
317+
318+
node.type = _instantiateElement(node, element);
319+
}
320+
309321
/// We parse `foo.bar` as `prefix.Name` with the expectation that `prefix`
310-
/// will be a [PrefixElement]. But we checked and found that `foo.bar` is
311-
/// not in the scope, so try to see if it is `Class.constructor`.
312-
///
313-
/// Return `true` if the node was rewritten as `Class.constructor`.
314-
bool _rewriteToConstructorName(TypeName node) {
315-
var typeIdentifier = node.name;
322+
/// will be a [PrefixElement]. But when we resolved the `prefix` it turned
323+
/// out to be a [ClassElement], so it is probably a `Class.constructor`.
324+
void _rewriteToConstructorName(
325+
TypeName node,
326+
PrefixedIdentifier typeIdentifier,
327+
) {
316328
var constructorName = node.parent;
317-
if (typeIdentifier is PrefixedIdentifier &&
318-
constructorName is ConstructorName &&
319-
constructorName.name == null) {
329+
if (constructorName is ConstructorName && constructorName.name == null) {
320330
var classIdentifier = typeIdentifier.prefix;
321-
var classElement = nameScope.lookupIdentifier(classIdentifier);
322-
if (classElement is ClassElement) {
323-
var constructorIdentifier = typeIdentifier.identifier;
324-
325-
var typeArguments = node.typeArguments;
326-
if (typeArguments != null) {
327-
errorReporter.reportErrorForNode(
328-
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
329-
typeArguments,
330-
[classIdentifier.name, constructorIdentifier.name],
331-
);
332-
var instanceCreation = constructorName.parent;
333-
if (instanceCreation is InstanceCreationExpressionImpl) {
334-
instanceCreation.typeArguments = typeArguments;
335-
}
331+
var constructorIdentifier = typeIdentifier.identifier;
332+
333+
var typeArguments = node.typeArguments;
334+
if (typeArguments != null) {
335+
errorReporter.reportErrorForNode(
336+
StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_CONSTRUCTOR,
337+
typeArguments,
338+
[classIdentifier.name, constructorIdentifier.name],
339+
);
340+
var instanceCreation = constructorName.parent;
341+
if (instanceCreation is InstanceCreationExpressionImpl) {
342+
instanceCreation.typeArguments = typeArguments;
336343
}
344+
}
337345

338-
node.name = classIdentifier;
339-
node.typeArguments = null;
346+
node.name = classIdentifier;
347+
node.typeArguments = null;
340348

341-
constructorName.period = typeIdentifier.period;
342-
constructorName.name = constructorIdentifier;
349+
constructorName.period = typeIdentifier.period;
350+
constructorName.name = constructorIdentifier;
343351

344-
rewriteResult = constructorName;
345-
return true;
346-
}
352+
rewriteResult = constructorName;
353+
return;
347354
}
348355

349-
return false;
350-
}
351-
352-
/// Records the new Element for a TypeName's Identifier.
353-
///
354-
/// A null may be passed in to indicate that the element can't be resolved.
355-
/// (During a re-run of a task, it's important to clear any previous value
356-
/// of the element.)
357-
void _setElement(Identifier typeName, Element element) {
358-
if (typeName is SimpleIdentifier) {
359-
typeName.staticElement = element;
360-
} else if (typeName is PrefixedIdentifier) {
361-
typeName.identifier.staticElement = element;
362-
SimpleIdentifier prefix = typeName.prefix;
363-
prefix.staticElement = nameScope.lookupIdentifier(prefix);
356+
if (_isInstanceCreation(node)) {
357+
_ErrorHelper(errorReporter).reportNewWithNonType(node);
358+
} else {
359+
errorReporter.reportErrorForNode(
360+
StaticWarningCode.NOT_A_TYPE,
361+
typeIdentifier,
362+
[typeIdentifier.name],
363+
);
364364
}
365365
}
366366

pkg/analyzer/test/src/diagnostics/not_a_type_test.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@ main() {
1515

1616
@reflectiveTest
1717
class NotATypeTest extends DriverResolutionTest {
18+
test_class_constructor() async {
19+
await assertErrorsInCode('''
20+
class A {
21+
A.foo();
22+
}
23+
24+
A.foo bar() {}
25+
''', [
26+
error(StaticWarningCode.NOT_A_TYPE, 24, 5),
27+
]);
28+
}
29+
30+
test_class_method() async {
31+
await assertErrorsInCode('''
32+
class A {
33+
static void foo() {}
34+
}
35+
36+
A.foo bar() {}
37+
''', [
38+
error(StaticWarningCode.NOT_A_TYPE, 36, 5),
39+
]);
40+
}
41+
1842
test_extension() async {
1943
await assertErrorsInCode('''
2044
extension E on int {}

0 commit comments

Comments
 (0)