Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d332017

Browse files
author
Dart CI
committed
Version 2.13.0-87.0.dev
Merge commit '46434442051eb8c112da536cb4e485ba8b745f09' into 'dev'
2 parents 632ae0d + 4643444 commit d332017

File tree

22 files changed

+893
-304
lines changed

22 files changed

+893
-304
lines changed

DEPS

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,13 +143,13 @@ vars = {
143143
"shelf_static_rev": "bafde9eaddb5d02040a614e41deddd971b4d67e6",
144144
"shelf_packages_handler_rev": "78302e67c035047e6348e692b0c1182131f0fe35",
145145
"shelf_proxy_tag": "0.1.0+7",
146-
"shelf_rev": "fa5afaa38bd51dedeeaa25b7bfd8822cabbcc57f",
147-
"shelf_web_socket_rev": "091d2ed2105827b7f376668fafc88b2b8c845d71",
146+
"shelf_rev": "e9294125f0c1fc2049c958577cd586ca2395168f",
147+
"shelf_web_socket_rev": "aa312d3cdeef96fb64bc3e602bc354a05a995624",
148148
"source_map_stack_trace_rev": "1c3026f69d9771acf2f8c176a1ab750463309cce",
149149
"source_maps-0.9.4_rev": "38524",
150150
"source_maps_rev": "53eb92ccfe6e64924054f83038a534b959b12b3e",
151151
"source_span_rev": "1be3c44045a06dff840d2ed3a13e6082d7a03a23",
152-
"sse_tag": "8add37c0ec0419ce28153a03f299d44ce006a975",
152+
"sse_tag": "5da8fedcdc56f306933d202e2d204753eecefd36",
153153
"stack_trace_tag": "6788afc61875079b71b3d1c3e65aeaa6a25cbc2f",
154154
"stagehand_rev": "e64ac90cac508981011299c4ceb819149e71f1bd",
155155
"stream_channel_tag": "d7251e61253ec389ee6e045ee1042311bced8f1d",
@@ -229,6 +229,13 @@ deps = {
229229
}],
230230
"dep_type": "cipd",
231231
},
232+
Var("dart_root") + "/third_party/devtools": {
233+
"packages": [{
234+
"package": "dart/third_party/flutter/devtools",
235+
"version": "revision:6729ec62c3548839018c32fa711756202431ccf7",
236+
}],
237+
"dep_type": "cipd",
238+
},
232239
Var("dart_root") + "/tests/co19/src": {
233240
"packages": [{
234241
"package": "dart/third_party/co19",

pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart

Lines changed: 36 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@
44

55
import 'package:meta/meta.dart';
66

7-
/// Set this boolean to `true` to permanently enable the feature of allowing
8-
/// local boolean variables to influence promotion (see
9-
/// https://github.com/dart-lang/language/issues/1274). While this boolean is
10-
/// `false`, the feature remains experimental and can be activated via an
11-
/// optional boolean parameter to the [FlowAnalysis] constructor.
12-
///
13-
/// Changing this value to `true` will cause some dead code warnings to appear
14-
/// for code that only exists to support the old behavior.
15-
const bool allowLocalBooleanVarsToPromoteByDefault = true;
16-
177
/// [AssignedVariables] is a helper class capable of computing the set of
188
/// variables that are potentially written to, and potentially captured by
199
/// closures, at various locations inside the code being analyzed. This class
@@ -242,6 +232,11 @@ class AssignedVariables<Node extends Object, Variable extends Object> {
242232
'{${_info.keys.map((k) => '$k (${k.hashCode})').join(',')}}'));
243233
}
244234

235+
/// Indicates whether information is stored for the given [node].
236+
bool _hasInfoForNode(Node node) {
237+
return _info[node] != null;
238+
}
239+
245240
void _printOn(StringBuffer sb) {
246241
sb.write('_info=$_info,');
247242
sb.write('_stack=$_stack,');
@@ -402,10 +397,8 @@ class ExpressionInfo<Variable extends Object, Type extends Object> {
402397
abstract class FlowAnalysis<Node extends Object, Statement extends Node,
403398
Expression extends Object, Variable extends Object, Type extends Object> {
404399
factory FlowAnalysis(TypeOperations<Variable, Type> typeOperations,
405-
AssignedVariables<Node, Variable> assignedVariables,
406-
{bool allowLocalBooleanVarsToPromote = false}) {
407-
return new _FlowAnalysisImpl(typeOperations, assignedVariables,
408-
allowLocalBooleanVarsToPromote: allowLocalBooleanVarsToPromote);
400+
AssignedVariables<Node, Variable> assignedVariables) {
401+
return new _FlowAnalysisImpl(typeOperations, assignedVariables);
409402
}
410403

411404
factory FlowAnalysis.legacy(TypeOperations<Variable, Type> typeOperations,
@@ -935,6 +928,8 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
935928
/// promotion, to retrieve information about why [target] was not promoted.
936929
/// This call must be made right after visiting [target].
937930
///
931+
/// If [target] is `null` it is assumed to be an implicit reference to `this`.
932+
///
938933
/// The returned value is a map whose keys are types that the user might have
939934
/// been expecting the target to be promoted to, and whose values are reasons
940935
/// why the corresponding promotion did not occur. The caller is expected to
@@ -943,7 +938,7 @@ abstract class FlowAnalysis<Node extends Object, Statement extends Node,
943938
/// occurs due to the target having a nullable type, the caller should report
944939
/// a non-promotion reason associated with non-promotion to a non-nullable
945940
/// type).
946-
Map<Type, NonPromotionReason> whyNotPromoted(Expression target);
941+
Map<Type, NonPromotionReason> whyNotPromoted(Expression? target);
947942

948943
/// Register write of the given [variable] in the current state.
949944
/// [writtenType] should be the type of the value that was written.
@@ -974,12 +969,10 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
974969
bool _exceptionOccurred = false;
975970

976971
factory FlowAnalysisDebug(TypeOperations<Variable, Type> typeOperations,
977-
AssignedVariables<Node, Variable> assignedVariables,
978-
{bool allowLocalBooleanVarsToPromote = false}) {
972+
AssignedVariables<Node, Variable> assignedVariables) {
979973
print('FlowAnalysisDebug()');
980-
return new FlowAnalysisDebug._(new _FlowAnalysisImpl(
981-
typeOperations, assignedVariables,
982-
allowLocalBooleanVarsToPromote: allowLocalBooleanVarsToPromote));
974+
return new FlowAnalysisDebug._(
975+
new _FlowAnalysisImpl(typeOperations, assignedVariables));
983976
}
984977

985978
factory FlowAnalysisDebug.legacy(
@@ -1460,7 +1453,7 @@ class FlowAnalysisDebug<Node extends Object, Statement extends Node,
14601453
}
14611454

14621455
@override
1463-
Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
1456+
Map<Type, NonPromotionReason> whyNotPromoted(Expression? target) {
14641457
return _wrap(
14651458
'whyNotPromoted($target)', () => _wrapped.whyNotPromoted(target),
14661459
isQuery: true);
@@ -1879,79 +1872,6 @@ class FlowModel<Variable extends Object, Type extends Object> {
18791872
return _identicalOrNew(this, base, newReachable, newVariableInfo);
18801873
}
18811874

1882-
/// Updates the state to reflect a control path that is known to have
1883-
/// previously passed through some [other] state.
1884-
///
1885-
/// Approximately, this method forms the union of the definite assignments and
1886-
/// promotions in `this` state and the [other] state. More precisely:
1887-
///
1888-
/// The control flow path is considered reachable if both this state and the
1889-
/// other state are reachable. Variables are considered definitely assigned
1890-
/// if they were definitely assigned in either this state or the other state.
1891-
/// Variable type promotions are taken from this state, unless the promotion
1892-
/// in the other state is more specific, and the variable is "safe". A
1893-
/// variable is considered safe if there is no chance that it was assigned
1894-
/// more recently than the "other" state.
1895-
///
1896-
/// This is used after a `try/finally` statement to combine the promotions and
1897-
/// definite assignments that occurred in the `try` and `finally` blocks
1898-
/// (where `this` is the state from the `finally` block and `other` is the
1899-
/// state from the `try` block). Variables that are assigned in the `finally`
1900-
/// block are considered "unsafe" because the assignment might have cancelled
1901-
/// the effect of any promotion that occurred inside the `try` block.
1902-
FlowModel<Variable, Type> restrict(
1903-
TypeOperations<Variable, Type> typeOperations,
1904-
FlowModel<Variable, Type> other,
1905-
Set<Variable> unsafe) {
1906-
if (allowLocalBooleanVarsToPromoteByDefault) {
1907-
// TODO(paulberry): when we hardcode
1908-
// allowLocalBooleanVarsToPromoteByDefault to `true`, we should remove
1909-
// this method entirely.
1910-
throw new StateError('This method should not be called anymore');
1911-
}
1912-
Reachability newReachable =
1913-
Reachability.restrict(reachable, other.reachable);
1914-
1915-
Map<Variable?, VariableModel<Variable, Type>> newVariableInfo =
1916-
<Variable?, VariableModel<Variable, Type>>{};
1917-
bool variableInfoMatchesThis = true;
1918-
bool variableInfoMatchesOther = true;
1919-
for (MapEntry<Variable?, VariableModel<Variable, Type>> entry
1920-
in variableInfo.entries) {
1921-
Variable? variable = entry.key;
1922-
VariableModel<Variable, Type> thisModel = entry.value;
1923-
VariableModel<Variable, Type>? otherModel = other.variableInfo[variable];
1924-
if (otherModel == null) {
1925-
variableInfoMatchesThis = false;
1926-
continue;
1927-
}
1928-
VariableModel<Variable, Type> restricted = thisModel.restrict(
1929-
typeOperations, otherModel, unsafe.contains(variable));
1930-
newVariableInfo[variable] = restricted;
1931-
if (!identical(restricted, thisModel)) variableInfoMatchesThis = false;
1932-
if (!identical(restricted, otherModel)) variableInfoMatchesOther = false;
1933-
}
1934-
if (variableInfoMatchesOther) {
1935-
for (Variable? variable in other.variableInfo.keys) {
1936-
if (!variableInfo.containsKey(variable)) {
1937-
variableInfoMatchesOther = false;
1938-
break;
1939-
}
1940-
}
1941-
}
1942-
assert(variableInfoMatchesThis ==
1943-
_variableInfosEqual(newVariableInfo, variableInfo));
1944-
assert(variableInfoMatchesOther ==
1945-
_variableInfosEqual(newVariableInfo, other.variableInfo));
1946-
if (variableInfoMatchesThis) {
1947-
newVariableInfo = variableInfo;
1948-
} else if (variableInfoMatchesOther) {
1949-
newVariableInfo = other.variableInfo;
1950-
}
1951-
1952-
return _identicalOrNew(this, other, newReachable, newVariableInfo);
1953-
}
1954-
19551875
/// Updates the state to indicate that the control flow path is unreachable.
19561876
FlowModel<Variable, Type> setUnreachable() {
19571877
if (!reachable.locallyReachable) return this;
@@ -2797,59 +2717,6 @@ class VariableModel<Variable extends Object, Type extends Object> {
27972717
ssaNode: writeCaptured ? null : new SsaNode<Variable, Type>(null));
27982718
}
27992719

2800-
/// Returns an updated model reflect a control path that is known to have
2801-
/// previously passed through some [other] state. See [FlowModel.restrict]
2802-
/// for details.
2803-
VariableModel<Variable, Type> restrict(
2804-
TypeOperations<Variable, Type> typeOperations,
2805-
VariableModel<Variable, Type> otherModel,
2806-
bool unsafe) {
2807-
if (allowLocalBooleanVarsToPromoteByDefault) {
2808-
// TODO(paulberry): when we hardcode
2809-
// allowLocalBooleanVarsToPromoteByDefault to `true`, we should remove
2810-
// this method entirely.
2811-
throw new StateError('This method should not be called anymore');
2812-
}
2813-
List<Type>? thisPromotedTypes = promotedTypes;
2814-
List<Type>? otherPromotedTypes = otherModel.promotedTypes;
2815-
bool newAssigned = assigned || otherModel.assigned;
2816-
// The variable can only be unassigned in this state if it was also
2817-
// unassigned in the other state or if the other state didn't complete
2818-
// normally. For the latter case the resulting state is unreachable but to
2819-
// avoid creating a variable model that is both assigned and unassigned we
2820-
// take the intersection below.
2821-
//
2822-
// This situation can occur in try-finally like:
2823-
//
2824-
// method() {
2825-
// var local;
2826-
// try {
2827-
// local = 0;
2828-
// return; // assigned
2829-
// } finally {
2830-
// local; // unassigned
2831-
// }
2832-
// local; // unreachable state
2833-
// }
2834-
//
2835-
bool newUnassigned = unassigned && otherModel.unassigned;
2836-
bool newWriteCaptured = writeCaptured || otherModel.writeCaptured;
2837-
List<Type>? newPromotedTypes;
2838-
if (newWriteCaptured) {
2839-
// Write-captured variables can't be promoted
2840-
newPromotedTypes = null;
2841-
} else if (unsafe) {
2842-
// There was an assignment to the variable in the "this" path, so none of
2843-
// the promotions from the "other" path can be used.
2844-
newPromotedTypes = thisPromotedTypes;
2845-
} else {
2846-
newPromotedTypes = rebasePromotedTypes(
2847-
typeOperations, thisPromotedTypes, otherPromotedTypes);
2848-
}
2849-
return _identicalOrNew(this, otherModel, newPromotedTypes, tested,
2850-
newAssigned, newUnassigned, newWriteCaptured ? null : ssaNode);
2851-
}
2852-
28532720
/// Updates `this` with a new set of properties.
28542721
VariableModel<Variable, Type> setProperties(
28552722
Map<String, VariableModel<Variable, Type>> newProperties) =>
@@ -3524,18 +3391,7 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
35243391

35253392
final AssignedVariables<Node, Variable> _assignedVariables;
35263393

3527-
/// Set this boolean to `true` to temporarily enable the feature of allowing
3528-
/// local boolean variables to influence promotion, for this flow analysis
3529-
/// session (see https://github.com/dart-lang/language/issues/1274). Once the
3530-
/// top level const [allowLocalBooleanVarsToPromoteByDefault] is changed to
3531-
/// `true`, this field will always be `true`, so it can be safely removed.
3532-
final bool allowLocalBooleanVarsToPromote;
3533-
3534-
_FlowAnalysisImpl(this.typeOperations, this._assignedVariables,
3535-
{bool allowLocalBooleanVarsToPromote = false})
3536-
: allowLocalBooleanVarsToPromote =
3537-
allowLocalBooleanVarsToPromoteByDefault ||
3538-
allowLocalBooleanVarsToPromote;
3394+
_FlowAnalysisImpl(this.typeOperations, this._assignedVariables);
35393395

35403396
@override
35413397
bool get isReachable => _current.reachable.overallReachable;
@@ -4186,17 +4042,13 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
41864042

41874043
@override
41884044
void tryFinallyStatement_end(Node finallyBlock) {
4189-
AssignedVariablesNodeInfo<Variable> info =
4190-
_assignedVariables._getInfoForNode(finallyBlock);
4045+
// We used to need info for `finally` blocks but we don't anymore.
4046+
assert(!_assignedVariables._hasInfoForNode(finallyBlock),
4047+
'No assigned variables info should have been stored for $finallyBlock');
41914048
_TryFinallyContext<Variable, Type> context =
41924049
_stack.removeLast() as _TryFinallyContext<Variable, Type>;
4193-
if (allowLocalBooleanVarsToPromote) {
4194-
_current = context._afterBodyAndCatches
4195-
.attachFinally(typeOperations, context._beforeFinally, _current);
4196-
} else {
4197-
_current = _current.restrict(
4198-
typeOperations, context._afterBodyAndCatches, info._written);
4199-
}
4050+
_current = context._afterBodyAndCatches
4051+
.attachFinally(typeOperations, context._beforeFinally, _current);
42004052
}
42014053

42024054
@override
@@ -4218,13 +4070,11 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
42184070
_storeExpressionReference(expression, variableReference);
42194071
VariableModel<Variable, Type> variableModel =
42204072
variableReference.getInfo(_current.variableInfo);
4221-
if (allowLocalBooleanVarsToPromote) {
4222-
ExpressionInfo<Variable, Type>? expressionInfo = variableModel
4223-
.ssaNode?.expressionInfo
4224-
?.rebaseForward(typeOperations, _current);
4225-
if (expressionInfo != null) {
4226-
_storeExpressionInfo(expression, expressionInfo);
4227-
}
4073+
ExpressionInfo<Variable, Type>? expressionInfo = variableModel
4074+
.ssaNode?.expressionInfo
4075+
?.rebaseForward(typeOperations, _current);
4076+
if (expressionInfo != null) {
4077+
_storeExpressionInfo(expression, expressionInfo);
42284078
}
42294079
return variableModel.promotedTypes?.last;
42304080
}
@@ -4257,13 +4107,16 @@ class _FlowAnalysisImpl<Node extends Object, Statement extends Node,
42574107
}
42584108

42594109
@override
4260-
Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
4261-
if (identical(target, _expressionWithReference)) {
4262-
Reference<Variable, Type>? reference = _expressionReference;
4263-
if (reference != null) {
4264-
return reference.getNonPromotionReasons(
4265-
_current.variableInfo, typeOperations);
4266-
}
4110+
Map<Type, NonPromotionReason> whyNotPromoted(Expression? target) {
4111+
Reference<Variable, Type>? reference;
4112+
if (target == null) {
4113+
reference = new _ThisReference<Variable, Type>();
4114+
} else if (identical(target, _expressionWithReference)) {
4115+
reference = _expressionReference;
4116+
}
4117+
if (reference != null) {
4118+
return reference.getNonPromotionReasons(
4119+
_current.variableInfo, typeOperations);
42674120
}
42684121
return {};
42694122
}
@@ -4850,7 +4703,7 @@ class _LegacyTypePromotion<Node extends Object, Statement extends Node,
48504703
void whileStatement_end() {}
48514704

48524705
@override
4853-
Map<Type, NonPromotionReason> whyNotPromoted(Expression target) {
4706+
Map<Type, NonPromotionReason> whyNotPromoted(Expression? target) {
48544707
return {};
48554708
}
48564709

pkg/_fe_analyzer_shared/test/flow_analysis/assigned_variables/data/tryFinally.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5-
/*member: tryFinally:declared={a, b}, assigned={a, b}*/
5+
/*member: tryFinally:declared={a, b, d}, assigned={a, b}*/
66
tryFinally(int a, int b) {
77
/*assigned={a}*/ try /*declared={c}, assigned={a}*/ {
88
a = 0;
99
var c;
10-
} finally /*declared={d}, assigned={b}*/ {
10+
} finally {
1111
b = 0;
1212
var d;
1313
}
1414
}
1515

16-
/*member: tryCatchFinally:declared={a, b, c}, assigned={a, b, c}*/
16+
/*member: tryCatchFinally:declared={a, b, c, f}, assigned={a, b, c}*/
1717
tryCatchFinally(int a, int b, int c) {
1818
// Note: try/catch/finally is desugared into try/catch nested inside
1919
// try/finally. The comment preceding the "try" refers to the outer
@@ -25,7 +25,7 @@ tryCatchFinally(int a, int b, int c) {
2525
} on String {
2626
b = 0;
2727
var e;
28-
} finally /*declared={f}, assigned={c}*/ {
28+
} finally {
2929
c = 0;
3030
var f;
3131
}

0 commit comments

Comments
 (0)