Skip to content

Commit b716a4e

Browse files
stereotype441commit-bot@chromium.org
authored andcommitted
Flow analysis: document how state methods are expected to be used.
I focused on the methods where the intended usage wasn't already obvious from the method name or its documentation comment. Change-Id: I8aeb01ccf8795e2f7a45b5cf1341d5ebbc77caaa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/110242 Auto-Submit: Paul Berry <[email protected]> Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
1 parent 41907fd commit b716a4e

File tree

1 file changed

+29
-1
lines changed

1 file changed

+29
-1
lines changed

pkg/front_end/lib/src/fasta/flow_analysis/flow_analysis.dart

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,8 @@ class State<Variable, Type> {
789789
}
790790

791791
/// Updates the state to indicate that the given [variable] has been
792-
/// determined to satisfy the given [type].
792+
/// determined to satisfy the given [type], e.g. as a consequence of an `is`
793+
/// expression as the condition of an `if` statement.
793794
///
794795
/// Note that the state is only changed if [type] is a subtype of the
795796
/// variable's previous (possibly promoted) type.
@@ -820,6 +821,23 @@ class State<Variable, Type> {
820821

821822
/// Updates the state to indicate that the given [variables] are no longer
822823
/// promoted; they are presumed to have their declared types.
824+
///
825+
/// This is used at the top of loops to conservatively cancel the promotion of
826+
/// variables that are modified within the loop, so that we correctly analyze
827+
/// code like the following:
828+
///
829+
/// if (x is int) {
830+
/// x.isEven; // OK, promoted to int
831+
/// while (true) {
832+
/// x.isEven; // ERROR: promotion lost
833+
/// x = 'foo';
834+
/// }
835+
/// }
836+
///
837+
/// Note that a more accurate analysis would be to iterate to a fixed point,
838+
/// and only remove promotions if it can be shown that they aren't restored
839+
/// later in the loop body. If we switch to a fixed point analysis, we should
840+
/// be able to remove this method.
823841
State<Variable, Type> removePromotedAll(Set<Variable> variables) {
824842
var newPromoted = _removePromotedAll(promoted, variables);
825843

@@ -835,13 +853,23 @@ class State<Variable, Type> {
835853
/// Updates the state to reflect a control path that is known to have
836854
/// previously passed through some [other] state.
837855
///
856+
/// Approximately, this method forms the union of the definite assignments and
857+
/// promotions in `this` state and the [other] state. More precisely:
858+
///
838859
/// The control flow path is considered reachable if both this state and the
839860
/// other state are reachable. Variables are considered definitely assigned
840861
/// if they were definitely assigned in either this state or the other state.
841862
/// Variable type promotions are taken from this state, unless the promotion
842863
/// in the other state is more specific, and the variable is "safe". A
843864
/// variable is considered safe if there is no chance that it was assigned
844865
/// more recently than the "other" state.
866+
///
867+
/// This is used after a `try/finally` statement to combine the promotions and
868+
/// definite assignments that occurred in the `try` and `finally` blocks
869+
/// (where `this` is the state from the `finally` block and `other` is the
870+
/// state from the `try` block). Variables that are assigned in the `finally`
871+
/// block are considered "unsafe" because the assignment might have cancelled
872+
/// the effect of any promotion that occurred inside the `try` block.
845873
State<Variable, Type> restrict(
846874
TypeOperations<Variable, Type> typeOperations,
847875
_VariableSet<Variable> emptySet,

0 commit comments

Comments
 (0)