Skip to content

Commit 76e3faa

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Resolve MethodInvocation(s) with Never and Never? receivers.
Change-Id: I7314efe7ccc352da7a407c3a657a30cc0956580b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/130180 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
1 parent d735f1f commit 76e3faa

File tree

3 files changed

+219
-124
lines changed

3 files changed

+219
-124
lines changed

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

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ class MethodInvocationResolver {
171171
return;
172172
}
173173

174-
if (receiverType == NeverTypeImpl.instance) {
175-
_reportUseOfNeverType(node, receiver);
174+
if (receiverType is NeverTypeImpl) {
175+
_resolveReceiverNever(node, receiver, receiverType);
176176
return;
177177
}
178178
}
@@ -290,14 +290,6 @@ class MethodInvocationResolver {
290290
);
291291
}
292292

293-
void _reportUseOfNeverType(MethodInvocation node, AstNode errorNode) {
294-
_setDynamicResolution(node);
295-
_resolver.errorReporter.reportErrorForNode(
296-
StaticWarningCode.INVALID_USE_OF_NEVER_VALUE,
297-
errorNode,
298-
);
299-
}
300-
301293
void _reportUseOfVoidType(MethodInvocation node, AstNode errorNode) {
302294
_setDynamicResolution(node);
303295
_resolver.errorReporter.reportErrorForNode(
@@ -306,12 +298,19 @@ class MethodInvocationResolver {
306298
);
307299
}
308300

309-
void _resolveArguments_finishInference(MethodInvocation node) {
301+
/// [InvocationExpression.staticInvokeType] has been set for the [node].
302+
/// Use it to set context for arguments, and resolve them.
303+
void _resolveArguments(MethodInvocation node) {
310304
_inferenceHelper.inferArgumentTypesForInvocation(node);
311305
node.argumentList.accept(_resolver);
306+
}
307+
308+
void _resolveArguments_finishInference(MethodInvocation node) {
309+
_resolveArguments(node);
312310

313311
_inferenceHelper.inferGenericInvocationExpression(node);
314312

313+
// TODO(scheglov) Call this only when member lookup failed?
315314
var inferred = _inferenceHelper.inferMethodInvocationObject(node);
316315

317316
if (!inferred) {
@@ -589,6 +588,49 @@ class MethodInvocationResolver {
589588
}
590589
}
591590

591+
void _resolveReceiverNever(
592+
MethodInvocation node,
593+
Expression receiver,
594+
DartType receiverType,
595+
) {
596+
_setExplicitTypeArgumentTypes();
597+
598+
if (receiverType == NeverTypeImpl.instanceNullable) {
599+
var methodName = node.methodName;
600+
var objectElement = _resolver.typeProvider.objectElement;
601+
var objectMember = objectElement.getMethod(methodName.name);
602+
if (objectMember != null) {
603+
objectMember = _resolver.toLegacyElement(objectMember);
604+
methodName.staticElement = objectMember;
605+
_setResolution(
606+
node,
607+
_elementTypeProvider.getExecutableType(objectMember),
608+
);
609+
} else {
610+
_setDynamicResolution(node);
611+
_resolver.errorReporter.reportErrorForNode(
612+
StaticWarningCode.UNCHECKED_USE_OF_NULLABLE_VALUE,
613+
receiver,
614+
);
615+
}
616+
return;
617+
}
618+
619+
if (receiverType == NeverTypeImpl.instance) {
620+
node.methodName.staticType = _dynamicType;
621+
node.staticInvokeType = _dynamicType;
622+
node.staticType = NeverTypeImpl.instance;
623+
624+
_resolveArguments(node);
625+
626+
_resolver.errorReporter.reportErrorForNode(
627+
StaticWarningCode.INVALID_USE_OF_NEVER_VALUE,
628+
receiver,
629+
);
630+
return;
631+
}
632+
}
633+
592634
void _resolveReceiverNull(
593635
MethodInvocation node, SimpleIdentifier nameNode, String name) {
594636
var element = nameScope.lookup(nameNode, _definingLibrary);
@@ -958,10 +1000,6 @@ class MethodInvocationResolver {
9581000
return _reportUseOfVoidType(node, node.methodName);
9591001
}
9601002

961-
if (type == NeverTypeImpl.instance) {
962-
return _reportUseOfNeverType(node, node.methodName);
963-
}
964-
9651003
_reportInvocationOfNonFunction(node);
9661004
}
9671005

pkg/analyzer/test/src/dart/element/nullable_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,8 @@ class IsNonNullableTest extends _NullableBase {
111111

112112
test_never() {
113113
isNonNullable(neverNone);
114+
isNotNonNullable(neverQuestion);
115+
isNonNullable(neverStar);
114116
}
115117

116118
test_null() {
@@ -238,6 +240,8 @@ class IsNullableTest extends _NullableBase {
238240

239241
test_never() {
240242
isNotNullable(neverNone);
243+
isNullable(neverQuestion);
244+
isNotNullable(neverStar);
241245
}
242246

243247
test_null() {

0 commit comments

Comments
 (0)