Skip to content

Commit

Permalink
Use nullable context type for operand of null-check operator. (2)
Browse files Browse the repository at this point in the history
Initial: https://dart-review.googlesource.com/c/sdk/+/131343
Reverted: https://dart-review.googlesource.com/c/sdk/+/131461

Bug: dart-lang/sdk#39694
Change-Id: I6287338ce347ddc45d6cc1f3cb16fdccbc75c891
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132200
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
  • Loading branch information
scheglov authored and commit-bot@chromium.org committed Jan 16, 2020
1 parent 05632be commit 445c084
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,18 @@ class PostfixExpressionResolver {
TypeSystemImpl get _typeSystem => _resolver.typeSystem;

void resolve(PostfixExpressionImpl node) {
if (node.operator.type == TokenType.BANG) {
_resolveNullCheck(node);
return;
}

node.operand.accept(_resolver);

var receiverType = getReadType(
node.operand,
elementTypeProvider: _elementTypeProvider,
);

if (node.operator.type == TokenType.BANG) {
_resolveNullCheck(node, receiverType);
return;
}

_assignmentShared.checkLateFinalAlreadyAssigned(node.operand);

_resolve1(node, receiverType);
Expand Down Expand Up @@ -197,11 +197,29 @@ class PostfixExpressionResolver {
_inferenceHelper.recordStaticType(node, receiverType);
}

void _resolveNullCheck(PostfixExpressionImpl node, DartType operandType) {
void _resolveNullCheck(PostfixExpressionImpl node) {
var operand = node.operand;

var contextType = InferenceContext.getContext(node);
if (contextType != null) {
if (_isNonNullableByDefault) {
contextType = _typeSystem.makeNullable(contextType);
}
InferenceContext.setType(operand, contextType);
}

operand.accept(_resolver);
operand = node.operand;

var operandType = getReadType(
operand,
elementTypeProvider: _elementTypeProvider,
);

var type = _typeSystem.promoteToNonNull(operandType);
_inferenceHelper.recordStaticType(node, type);

_flowAnalysis?.flow?.nonNullAssert_end(node.operand);
_flowAnalysis?.flow?.nonNullAssert_end(operand);
}

/// Return `true` if we should report an error for the lookup [result] on
Expand Down
30 changes: 30 additions & 0 deletions pkg/analyzer/test/src/dart/resolution/postfix_expression_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ f(int? x) {
);
}

test_nullCheck_functionExpressionInvocation_rewrite() async {
await assertNoErrorsInCode(r'''
main(Function f2) {
f2(42)!;
}
''');
}

test_nullCheck_null() async {
await assertNoErrorsInCode('''
main(Null x) {
Expand All @@ -129,6 +137,28 @@ main(Null x) {
assertType(findNode.postfix('x!'), 'Never');
}

test_nullCheck_nullableContext() async {
await assertNoErrorsInCode(r'''
T f<T>(T t) => t;
int g() => f(null)!;
''');

assertMethodInvocation2(
findNode.methodInvocation('f(null)'),
element: findElement.topFunction('f'),
typeArgumentTypes: ['int?'],
invokeType: 'int? Function(int?)',
type: 'int?',
);

assertPostfixExpression(
findNode.postfix('f(null)!'),
element: null,
type: 'int',
);
}

test_nullCheck_typeParameter() async {
await assertNoErrorsInCode(r'''
f<T>(T? x) {
Expand Down

0 comments on commit 445c084

Please sign in to comment.