Skip to content

Commit 1a2411e

Browse files
johnniwintherCommit Queue
authored andcommitted
[cfe] Make IfNullIndexSet and CompoundIndexSet null-aware
This makes IfNullIndexSet and CompoundIndexSet null-aware to avoid lowerings during body building. Inference visit methods visitIfNullPropertySet, visitIfNullSuperIndexSet, visitNullAwareCompoundSet, and visitNullAwareIfNullSet are updated to align with null-aware approach to lowering. Change-Id: I9678191dae7ab014bfdacb2b39d271fdc852dbfc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/446041 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent a79b7c6 commit 1a2411e

File tree

36 files changed

+392
-532
lines changed

36 files changed

+392
-532
lines changed

pkg/front_end/lib/src/kernel/expression_generator.dart

Lines changed: 21 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -524,7 +524,10 @@ class PropertyAccessGenerator extends Generator {
524524
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
525525
{bool voidContext = false}) {
526526
return new IfNullPropertySet(receiver, name, value,
527-
forEffect: voidContext, readOffset: fileOffset, writeOffset: fileOffset)
527+
forEffect: voidContext,
528+
readOffset: fileOffset,
529+
writeOffset: fileOffset,
530+
isNullAware: false)
528531
..fileOffset = offset;
529532
}
530533

@@ -765,11 +768,11 @@ class NullAwarePropertyAccessGenerator extends Generator {
765768
@override
766769
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
767770
{bool voidContext = false}) {
768-
return new NullAwareIfNullSet(receiver, name, value,
771+
return new IfNullPropertySet(receiver, name, value,
769772
forEffect: voidContext,
770773
readOffset: fileOffset,
771-
testOffset: offset,
772-
writeOffset: fileOffset)
774+
writeOffset: fileOffset,
775+
isNullAware: true)
773776
..fileOffset = offset;
774777
}
775778

@@ -982,27 +985,13 @@ class IndexedAccessGenerator extends Generator {
982985
@override
983986
Expression buildIfNullAssignment(Expression value, DartType type, int offset,
984987
{bool voidContext = false}) {
985-
VariableDeclarationImpl? variable;
986-
Expression receiverValue;
987-
if (isNullAware) {
988-
variable = _helper.createVariableDeclarationForValue(receiver);
989-
receiverValue = _helper.createVariableGet(variable, fileOffset,
990-
forNullGuardedAccess: true);
991-
} else {
992-
receiverValue = receiver;
993-
}
994-
995-
Expression result = new IfNullIndexSet(receiverValue, index, value,
988+
return new IfNullIndexSet(receiver, index, value,
996989
readOffset: fileOffset,
997990
testOffset: offset,
998991
writeOffset: fileOffset,
999-
forEffect: voidContext)
992+
forEffect: voidContext,
993+
isNullAware: isNullAware)
1000994
..fileOffset = offset;
1001-
if (isNullAware) {
1002-
result = new NullAwareMethodInvocation(variable!, result)
1003-
..fileOffset = fileOffset;
1004-
}
1005-
return result;
1006995
}
1007996

1008997
@override
@@ -1011,28 +1000,14 @@ class IndexedAccessGenerator extends Generator {
10111000
bool voidContext = false,
10121001
bool isPreIncDec = false,
10131002
bool isPostIncDec = false}) {
1014-
VariableDeclarationImpl? variable;
1015-
Expression receiverValue;
1016-
if (isNullAware) {
1017-
variable = _helper.createVariableDeclarationForValue(receiver);
1018-
receiverValue = _helper.createVariableGet(variable, fileOffset,
1019-
forNullGuardedAccess: true);
1020-
} else {
1021-
receiverValue = receiver;
1022-
}
1023-
1024-
Expression result = new CompoundIndexSet(
1025-
receiverValue, index, binaryOperator, value,
1003+
return new CompoundIndexSet(receiver, index, binaryOperator, value,
10261004
readOffset: fileOffset,
10271005
binaryOffset: offset,
10281006
writeOffset: fileOffset,
10291007
forEffect: voidContext,
1030-
forPostIncDec: isPostIncDec);
1031-
if (isNullAware) {
1032-
result = new NullAwareMethodInvocation(variable!, result)
1033-
..fileOffset = fileOffset;
1034-
}
1035-
return result;
1008+
forPostIncDec: isPostIncDec,
1009+
isNullAware: isNullAware)
1010+
..fileOffset = offset;
10361011
}
10371012

10381013
@override
@@ -1127,7 +1102,8 @@ class ThisIndexedAccessGenerator extends Generator {
11271102
readOffset: fileOffset,
11281103
testOffset: offset,
11291104
writeOffset: fileOffset,
1130-
forEffect: voidContext)
1105+
forEffect: voidContext,
1106+
isNullAware: isNullAware)
11311107
..fileOffset = offset;
11321108
}
11331109

@@ -1143,7 +1119,9 @@ class ThisIndexedAccessGenerator extends Generator {
11431119
binaryOffset: offset,
11441120
writeOffset: fileOffset,
11451121
forEffect: voidContext,
1146-
forPostIncDec: isPostIncDec);
1122+
forPostIncDec: isPostIncDec,
1123+
isNullAware: isNullAware)
1124+
..fileOffset = offset;
11471125
}
11481126

11491127
@override
@@ -2077,7 +2055,8 @@ class ExplicitExtensionInstanceAccessGenerator extends Generator {
20772055
return new IfNullPropertySet(receiver, targetName, value,
20782056
forEffect: voidContext,
20792057
readOffset: fileOffset,
2080-
writeOffset: fileOffset)
2058+
writeOffset: fileOffset,
2059+
isNullAware: false)
20812060
..fileOffset = offset;
20822061
}
20832062
}

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

Lines changed: 21 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,10 +1253,14 @@ class IfNullPropertySet extends InternalExpression {
12531253
/// The file offset for the write operation.
12541254
final int writeOffset;
12551255

1256+
/// `true` if the access is null-aware, i.e. of the form `o?.a ??= b`.
1257+
final bool isNullAware;
1258+
12561259
IfNullPropertySet(this.receiver, this.propertyName, this.rhs,
12571260
{required this.forEffect,
12581261
required this.readOffset,
1259-
required this.writeOffset}) {
1262+
required this.writeOffset,
1263+
required this.isNullAware}) {
12601264
receiver.parent = this;
12611265
rhs.parent = this;
12621266
}
@@ -1276,6 +1280,9 @@ class IfNullPropertySet extends InternalExpression {
12761280
// Coverage-ignore(suite): Not run.
12771281
void toTextInternal(AstPrinter printer) {
12781282
printer.writeExpression(receiver);
1283+
if (isNullAware) {
1284+
printer.write('?');
1285+
}
12791286
printer.write('.');
12801287
printer.writeName(propertyName);
12811288
printer.write(' ??= ');
@@ -1857,11 +1864,15 @@ class IfNullIndexSet extends InternalExpression {
18571864
/// If `true`, the expression is only need for effect and not for its value.
18581865
final bool forEffect;
18591866

1867+
/// `true` if the access is null-aware, i.e. of the form `o?[a] ??= b`.
1868+
final bool isNullAware;
1869+
18601870
IfNullIndexSet(this.receiver, this.index, this.value,
18611871
{required this.readOffset,
18621872
required this.testOffset,
18631873
required this.writeOffset,
1864-
required this.forEffect}) {
1874+
required this.forEffect,
1875+
required this.isNullAware}) {
18651876
receiver.parent = this;
18661877
index.parent = this;
18671878
value.parent = this;
@@ -2062,12 +2073,16 @@ class CompoundIndexSet extends InternalExpression {
20622073
/// If `true`, the expression is a post-fix inc/dec expression.
20632074
final bool forPostIncDec;
20642075

2076+
/// `true` if the access is null-aware, i.e. of the form `o?[a] += b`.
2077+
final bool isNullAware;
2078+
20652079
CompoundIndexSet(this.receiver, this.index, this.binaryName, this.rhs,
20662080
{required this.readOffset,
20672081
required this.binaryOffset,
20682082
required this.writeOffset,
20692083
required this.forEffect,
2070-
required this.forPostIncDec}) {
2084+
required this.forPostIncDec,
2085+
required this.isNullAware}) {
20712086
receiver.parent = this;
20722087
index.parent = this;
20732088
rhs.parent = this;
@@ -2089,6 +2104,9 @@ class CompoundIndexSet extends InternalExpression {
20892104
// Coverage-ignore(suite): Not run.
20902105
void toTextInternal(AstPrinter printer) {
20912106
printer.writeExpression(receiver);
2107+
if (isNullAware) {
2108+
printer.write('?');
2109+
}
20922110
printer.write('[');
20932111
printer.writeExpression(index);
20942112
printer.write(']');
@@ -2218,81 +2236,6 @@ class NullAwareCompoundSet extends InternalExpression {
22182236
}
22192237
}
22202238

2221-
/// Internal expression representing an null-aware if-null property set.
2222-
///
2223-
/// A null-aware if-null property set of the form
2224-
///
2225-
/// receiver?.name ??= value
2226-
///
2227-
/// is, if used for value, encoded as the expression:
2228-
///
2229-
/// let receiverVariable = receiver in
2230-
/// receiverVariable == null ? null :
2231-
/// (let readVariable = receiverVariable.name in
2232-
/// readVariable == null ?
2233-
/// receiverVariable.name = value : readVariable)
2234-
///
2235-
/// and, if used for effect, encoded as the expression:
2236-
///
2237-
/// let receiverVariable = receiver in
2238-
/// receiverVariable == null ? null :
2239-
/// (receiverVariable.name == null ?
2240-
/// receiverVariable.name = value : null)
2241-
///
2242-
///
2243-
class NullAwareIfNullSet extends InternalExpression {
2244-
/// The synthetic variable whose initializer hold the receiver.
2245-
Expression receiver;
2246-
2247-
/// The expression that reads the property from [variable].
2248-
Name name;
2249-
2250-
/// The expression that writes the value to the property on [variable].
2251-
Expression value;
2252-
2253-
/// The file offset for the read operation.
2254-
final int readOffset;
2255-
2256-
/// The file offset for the write operation.
2257-
final int writeOffset;
2258-
2259-
/// The file offset for the == operation.
2260-
final int testOffset;
2261-
2262-
/// If `true`, the expression is only need for effect and not for its value.
2263-
final bool forEffect;
2264-
2265-
NullAwareIfNullSet(this.receiver, this.name, this.value,
2266-
{required this.readOffset,
2267-
required this.writeOffset,
2268-
required this.testOffset,
2269-
required this.forEffect}) {
2270-
receiver.parent = this;
2271-
value.parent = this;
2272-
}
2273-
2274-
@override
2275-
ExpressionInferenceResult acceptInference(
2276-
InferenceVisitorImpl visitor, DartType typeContext) {
2277-
return visitor.visitNullAwareIfNullSet(this, typeContext);
2278-
}
2279-
2280-
@override
2281-
String toString() {
2282-
return "NullAwareIfNullSet(${toStringInternal()})";
2283-
}
2284-
2285-
@override
2286-
// Coverage-ignore(suite): Not run.
2287-
void toTextInternal(AstPrinter printer) {
2288-
printer.writeExpression(receiver);
2289-
printer.write('?.');
2290-
printer.writeName(name);
2291-
printer.write(' ??= ');
2292-
printer.writeExpression(value);
2293-
}
2294-
}
2295-
22962239
/// Internal expression representing a compound super index assignment.
22972240
///
22982241
/// An if-null index assignment of the form `super[a] += b` is, if used for

0 commit comments

Comments
 (0)