7703609cc1
Try/finally statements have an unusual property that needs to be handled in a special way by flow analysis: within the `finally` block, the `try` block might not have run to completion, but after the try/finally statement, the `try` block is known to have run to completion. Therefore, even though the code that follows the try/finally statement is immediately preceded by the end of the `finally` block, the flow states of those two control flow points might not be the same. Flow analysis accounts for this situation by analyzing the `finally` block as though it started executing right after the beginning of the `try` block, but with all variables that are written within the `try` block demoted. Then, after it finishes analyzing the `finally` block, it builds a fresh flow model by starting with the flow state after the end of the `try` block, and then applying any promotions that were performed within the `finally` block. This is accomplished by the `FlowModel.attachFinally` method. The following changes had to be made to make this work with field promotion: - If a given promotion key appears in the "after try" model but not the "after finally" model, it might represent a field that was promoted during the `try` block, so the promotion needs to be preserved. Previously, this situation could only occur if the promotion key represented a variable declared in the `try` block (and therefore the variable would not be accessible after the try/finally statement), so the promotion could be safely dropped. - If a given promotion key appears in the "after try" model and the "after finally" model, but not the "before finally" model, it might represent a field that was promoted within both the `try` and `finally` blocks, so the promotions need to be combined. Previously, this situation could not occur, so the promotion could be safely dropped. - If a given promotion key is associated with the same SSA node in the "before finally" and "after finally" models, but a different SSA node in the "after try" model, that means that the corresponding variable was assigned in the `try` block but not in the `finally` block. If any properties of the variable were promoted within the `finally` block, those promotions were applied to the SSA nodes used by the `finally` block, and don't appear in the SSA nodes used in the "after try" model. So those promotions need to be transferred. This is accomplished by the new `SsaNode._applyPropertyPromotions` method. - If a given promotion key appears in the "after finally" model but not the "after try" model, it might represent a field that was promoted during the `finally` block, so the promotion needs to be preserved. Previously, this situation could only occur if the promotion key represented a variable declared in the `finally` block (and therefore the variable would not be accessible after the try/finally statement), so the promotion could be safely dropped. Fixes https://github.com/dart-lang/sdk/issues/53225. Bug: https://github.com/dart-lang/sdk/issues/53225 Change-Id: Ie4b635dbf838447d6964c326e1ecebfff99bed8e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/320961 Reviewed-by: Johnni Winther <johnniwinther@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
FE/analyzer shared code
This package contains logic that is shared between the front_end and analyzer packages. It is intended solely to facilitate development of the Dart SDK, and is not intended for use by end users. In particular, this package has no public API, so no guarantee is made of compatibility between one version of the package and the next.
End users should consider using the analyzer package to analyze Dart source code.