Skip to content

Commit b97e5b9

Browse files
chloestefantsovaCommit Queue
authored and
Commit Queue
committed
[cfe] Implement the desugaring for NullAssertPattern
Part of #49749 Change-Id: I56ac79a98eb4306daabec05d95f09bb18d248825 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/268961 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Chloe Stefantsova <[email protected]>
1 parent 3fe82b7 commit b97e5b9

6 files changed

+54
-13
lines changed

pkg/front_end/lib/src/fasta/kernel/internal_ast.dart

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5417,15 +5417,56 @@ class NullAssertPattern extends Pattern {
54175417
@override
54185418
Expression? makeCondition(VariableDeclaration matchedExpressionVariable,
54195419
InferenceVisitorBase inferenceVisitor) {
5420-
return new InvalidExpression(
5421-
"Unimplemented NullAssertPattern.makeCondition");
5420+
// nullCheckCondition: `matchedExpressionVariable`!
5421+
Expression nullCheckExpression = inferenceVisitor.engine.forest
5422+
.createNullCheck(
5423+
fileOffset,
5424+
inferenceVisitor.engine.forest
5425+
.createVariableGet(fileOffset, matchedExpressionVariable));
5426+
5427+
DartType typeWithoutNullabilityMarkers =
5428+
matchedExpressionVariable.type.toNonNull();
5429+
5430+
// intermediateVariable: `typeWithoutNullabilityMarkers` VAR =
5431+
// `nullCheckExpression`;
5432+
// ==> `typeWithoutNullabilityMarkers` VAR = `matchedExpressionVariable`!;
5433+
VariableDeclaration intermediateVariable = inferenceVisitor.engine.forest
5434+
.createVariableDeclarationForValue(nullCheckExpression,
5435+
type: typeWithoutNullabilityMarkers);
5436+
5437+
Expression? patternCondition =
5438+
pattern.makeCondition(intermediateVariable, inferenceVisitor);
5439+
if (patternCondition == null) {
5440+
// TODO(cstefantsova): As an optimization of the generated code size and
5441+
// the number of runtime checks, the null check in this case can be
5442+
// removed if any variable is initialized via this pattern, and therefore
5443+
// will have the cast in its initializer expression.
5444+
5445+
// return: let `intermediateVariable` in true
5446+
// ==> let `typeWithoutNullabilityMarkers` VAR =
5447+
// `matchedExpressionVariable`! in
5448+
// true
5449+
return inferenceVisitor.engine.forest.createLet(intermediateVariable,
5450+
inferenceVisitor.engine.forest.createBoolLiteral(fileOffset, true));
5451+
} else {
5452+
// return: let `intermediateVariable` in `patternCondition`
5453+
// ==> let `typeWithoutNullabilityMarkers` VAR =
5454+
// `matchedExpressionVariable`! in
5455+
// `patternCondition`
5456+
return inferenceVisitor.engine.forest
5457+
.createLet(intermediateVariable, patternCondition);
5458+
}
54225459
}
54235460

54245461
@override
54255462
void createDeclaredVariableInitializers(Expression matchedExpression,
54265463
DartType matchedType, InferenceVisitorBase inferenceVisitor) {
5464+
DartType matchedTypeWithoutNullabilityMarkers = matchedType.toNonNull();
54275465
pattern.createDeclaredVariableInitializers(
5428-
matchedExpression, matchedType, inferenceVisitor);
5466+
inferenceVisitor.engine.forest
5467+
.createNullCheck(fileOffset, matchedExpression),
5468+
matchedTypeWithoutNullabilityMarkers,
5469+
inferenceVisitor);
54295470
}
54305471

54315472
@override

pkg/front_end/testcases/patterns/null_assert_inside_if_case.dart.strong.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import self as self;
33

44
static method test(dynamic x) → dynamic {
55
final dynamic #t1 = x;
6-
if(invalid-expression "Unimplemented NullAssertPattern.makeCondition") {
7-
dynamic y = #t1;
6+
if(let final dynamic #t2 = #t1! in true) {
7+
dynamic y = #t1!;
88
{}
99
}
1010
}

pkg/front_end/testcases/patterns/null_assert_inside_if_case.dart.strong.transformed.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import self as self;
33

44
static method test(dynamic x) → dynamic {
55
final dynamic #t1 = x;
6-
if(invalid-expression "Unimplemented NullAssertPattern.makeCondition") {
7-
dynamic y = #t1;
6+
if(let final dynamic #t2 = #t1! in true) {
7+
dynamic y = #t1!;
88
{}
99
}
1010
}

pkg/front_end/testcases/patterns/null_assert_inside_if_case.dart.weak.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import self as self;
33

44
static method test(dynamic x) → dynamic {
55
final dynamic #t1 = x;
6-
if(invalid-expression "Unimplemented NullAssertPattern.makeCondition") {
7-
dynamic y = #t1;
6+
if(let final dynamic #t2 = #t1! in true) {
7+
dynamic y = #t1!;
88
{}
99
}
1010
}

pkg/front_end/testcases/patterns/null_assert_inside_if_case.dart.weak.modular.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import self as self;
33

44
static method test(dynamic x) → dynamic {
55
final dynamic #t1 = x;
6-
if(invalid-expression "Unimplemented NullAssertPattern.makeCondition") {
7-
dynamic y = #t1;
6+
if(let final dynamic #t2 = #t1! in true) {
7+
dynamic y = #t1!;
88
{}
99
}
1010
}

pkg/front_end/testcases/patterns/null_assert_inside_if_case.dart.weak.transformed.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import self as self;
33

44
static method test(dynamic x) → dynamic {
55
final dynamic #t1 = x;
6-
if(invalid-expression "Unimplemented NullAssertPattern.makeCondition") {
7-
dynamic y = #t1;
6+
if(let final dynamic #t2 = #t1! in true) {
7+
dynamic y = #t1!;
88
{}
99
}
1010
}

0 commit comments

Comments
 (0)