@@ -68,13 +68,15 @@ Statement continue_(BranchTargetPlaceholder branchTargetPlaceholder) =>
68
68
new _Continue (branchTargetPlaceholder);
69
69
70
70
Statement declare (Var variable,
71
- {required bool initialized, bool isFinal = false }) =>
72
- new _Declare (
73
- variable, initialized ? expr (variable.type.type) : null , isFinal);
71
+ {required bool initialized,
72
+ bool isFinal = false ,
73
+ bool isLate = false }) =>
74
+ new _Declare (variable, initialized ? expr (variable.type.type) : null ,
75
+ isFinal, isLate);
74
76
75
77
Statement declareInitialized (Var variable, Expression initializer,
76
- {bool isFinal = false }) =>
77
- new _Declare (variable, initializer, isFinal);
78
+ {bool isFinal = false , bool isLate = false }) =>
79
+ new _Declare (variable, initializer, isFinal, isLate );
78
80
79
81
Statement do_ (List <Statement > body, Expression condition) =>
80
82
_Do (body, condition);
@@ -211,6 +213,9 @@ abstract class Expression implements _Visitable<Type> {
211
213
/// If `this` is an expression `x` , creates the expression `x!` .
212
214
Expression get nonNullAssert => new _NonNullAssert (this );
213
215
216
+ /// If `this` is an expression `x` , creates the expression `!x` .
217
+ Expression get not => new _Not (this );
218
+
214
219
/// If `this` is an expression `x` , creates the expression `(x)` .
215
220
Expression get parenthesized => new _ParenthesizedExpression (this );
216
221
@@ -231,6 +236,15 @@ abstract class Expression implements _Visitable<Type> {
231
236
/// If `this` is an expression `x` , creates the expression `x == other` .
232
237
Expression eq (Expression other) => new _Equal (this , other, false );
233
238
239
+ /// Creates an [Expression] that, when analyzed, will behave the same as
240
+ /// `this` , but after visiting it, will cause [callback] to be passed the
241
+ /// [ExpressionInfo] associated with it. If the expression has no flow
242
+ /// analysis information associated with it, `null` will be passed to
243
+ /// [callback] .
244
+ Expression getExpressionInfo (
245
+ void Function (ExpressionInfo <Var , Type >? ) callback) =>
246
+ new _GetExpressionInfo (this , callback);
247
+
234
248
/// If `this` is an expression `x` , creates the expression `x ?? other` .
235
249
Expression ifNull (Expression other) => new _IfNull (this , other);
236
250
@@ -520,7 +534,8 @@ class SsaNodeHarness {
520
534
521
535
/// Gets the SSA node associated with [variable] at the current point in
522
536
/// control flow, or `null` if the variable has been write captured.
523
- SsaNode ? operator [](Var variable) => _flow.ssaNodeForTesting (variable);
537
+ SsaNode <Var , Type >? operator [](Var variable) =>
538
+ _flow.ssaNodeForTesting (variable);
524
539
}
525
540
526
541
/// Representation of a statement in the pseudo-Dart language used for flow
@@ -591,7 +606,7 @@ class Var {
591
606
String toString () => '$type $name ' ;
592
607
593
608
/// Creates an expression representing a write to this variable.
594
- Expression write (Expression value) => new _Write (this , value);
609
+ Expression write (Expression ? value) => new _Write (this , value);
595
610
}
596
611
597
612
class _As extends Expression {
@@ -848,14 +863,17 @@ class _Declare extends Statement {
848
863
final Var variable;
849
864
final Expression ? initializer;
850
865
final bool isFinal;
866
+ final bool isLate;
851
867
852
- _Declare (this .variable, this .initializer, this .isFinal) : super ._();
868
+ _Declare (this .variable, this .initializer, this .isFinal, this .isLate)
869
+ : super ._();
853
870
854
871
@override
855
872
String toString () {
873
+ var latePart = isLate ? 'late ' : '' ;
856
874
var finalPart = isFinal ? 'final ' : '' ;
857
875
var initializerPart = initializer != null ? ' = $initializer ' : '' ;
858
- return '$finalPart $variable ${initializerPart };' ;
876
+ return '$latePart $ finalPart $variable ${initializerPart };' ;
859
877
}
860
878
861
879
@override
@@ -870,8 +888,10 @@ class _Declare extends Statement {
870
888
if (initializer == null ) {
871
889
flow.declare (variable, false );
872
890
} else {
873
- initializer._visit (h, flow);
891
+ var initializerType = initializer._visit (h, flow);
874
892
flow.declare (variable, true );
893
+ flow.initialize (variable, initializerType, initializer,
894
+ isFinal: isFinal, isLate: isLate);
875
895
}
876
896
}
877
897
}
@@ -1053,6 +1073,28 @@ class _ForEach extends Statement {
1053
1073
}
1054
1074
}
1055
1075
1076
+ class _GetExpressionInfo extends Expression {
1077
+ final Expression target;
1078
+
1079
+ final void Function (ExpressionInfo <Var , Type >? ) callback;
1080
+
1081
+ _GetExpressionInfo (this .target, this .callback);
1082
+
1083
+ @override
1084
+ void _preVisit (AssignedVariables <Node , Var > assignedVariables) {
1085
+ target._preVisit (assignedVariables);
1086
+ }
1087
+
1088
+ @override
1089
+ Type _visit (
1090
+ Harness h, FlowAnalysis <Node , Statement , Expression , Var , Type > flow) {
1091
+ var type = target._visit (h, flow);
1092
+ flow.forwardExpression (this , target);
1093
+ callback (flow.expressionInfoForTesting (this ));
1094
+ return type;
1095
+ }
1096
+ }
1097
+
1056
1098
class _GetSsaNodes extends Statement {
1057
1099
final void Function (SsaNodeHarness ) callback;
1058
1100
@@ -1246,6 +1288,27 @@ class _NonNullAssert extends Expression {
1246
1288
}
1247
1289
}
1248
1290
1291
+ class _Not extends Expression {
1292
+ final Expression operand;
1293
+
1294
+ _Not (this .operand);
1295
+
1296
+ @override
1297
+ String toString () => '!$operand ' ;
1298
+
1299
+ @override
1300
+ void _preVisit (AssignedVariables <Node , Var > assignedVariables) {
1301
+ operand._preVisit (assignedVariables);
1302
+ }
1303
+
1304
+ @override
1305
+ Type _visit (
1306
+ Harness h, FlowAnalysis <Node , Statement , Expression , Var , Type > flow) {
1307
+ flow.logicalNot_end (this , operand.._visit (h, flow));
1308
+ return Type ('bool' );
1309
+ }
1310
+ }
1311
+
1249
1312
class _NullAwareAccess extends Expression {
1250
1313
final Expression lhs;
1251
1314
final Expression rhs;
@@ -1540,7 +1603,7 @@ class _WrappedExpression extends Expression {
1540
1603
1541
1604
class _Write extends Expression {
1542
1605
final Var variable;
1543
- final Expression rhs;
1606
+ final Expression ? rhs;
1544
1607
1545
1608
_Write (this .variable, this .rhs);
1546
1609
@@ -1550,14 +1613,15 @@ class _Write extends Expression {
1550
1613
@override
1551
1614
void _preVisit (AssignedVariables <Node , Var > assignedVariables) {
1552
1615
assignedVariables.write (variable);
1553
- rhs._preVisit (assignedVariables);
1616
+ rhs? ._preVisit (assignedVariables);
1554
1617
}
1555
1618
1556
1619
@override
1557
1620
Type _visit (
1558
1621
Harness h, FlowAnalysis <Node , Statement , Expression , Var , Type > flow) {
1559
- var type = rhs._visit (h, flow);
1560
- flow.write (variable, type);
1622
+ var rhs = this .rhs;
1623
+ var type = rhs == null ? variable.type : rhs._visit (h, flow);
1624
+ flow.write (variable, type, rhs);
1561
1625
return type;
1562
1626
}
1563
1627
}
0 commit comments