parlough 6 months ago
parent 54548429f4
commit 1cb16f8d44

@ -152,6 +152,7 @@ packages/$sdk/dev_compiler/web/dart_stack_trace_mapper.js
packages/_fe_analyzer_shared/src/parser/parser.md
packages/analyzer/fix_data.yaml
packages/analyzer/src/summary/format.fbs
packages/analyzer/src/wolf/README.md
packages/build_runner/src/server/README.md
packages/build_runner/src/server/build_updates_client/live_reload_client.js
packages/build_runner/src/server/graph_viz.html

File diff suppressed because one or more lines are too long

@ -0,0 +1,81 @@
# Wolf Analysis
The code in this directory is __experimental__ and not yet ready for public
consumption. This file briefly describes its design and intended use.
## Intention
Wolf analysis is intended as a broader, more extensible version of flow analysis
for use in the analyzer package and the linter. If it proves useful, we may
expand it to be usable by clients of the analyzer such as code generators.
The reason for making a new type of analysis, rather than extending flow
analysis, is because the design of flow analysis is heavily constrained in ways
that make it expensive to modify, maintain, and extend:
- It has to operate in parallel with type inference. This means that it can only
make a single pass through the source code, and any time it "looks ahead", the
code it is looking at doesn't yet have types. This forces it to make some
conservative assumptions when analyzing loops and closures--for example, on
entry to a loop, flow analysis knows which variables are written inside the
loop body, but it doesn't know the types of the values that are written to
those variables; so it has to discard type promotions for all of them. If
later analysis shows that the values that were written are compatible with the
promoted type, it's too late to go back and update the analysis.
- It can't be improved without bumping the language version (or it will break
existing programs).
- All of its analyses must be 100% sound, because they are relied on by later
compilation stages. This severly limits its ability to account for human
intent, which we would sometimes like to do in lints.
- It has to be shared between the analyzer and the common front end, which means
that all of the data structures it acts on must be abstract.
Additionally, flow analysis doesn't understand special behavioral guarantees of
methods and types declared outside the SDK, and it never looks outside of a
single method body.
## Design
The design consists of multiple analysis stages:
- AST-to-IR. The analyzer's AST is converted to a stack-based IR (intermediate
representation). The proposed IR and the approach for converting to it are
described in http://flutter.dev/go/dart-static-analysis-ir.
- Scope analysis. A pass is made through the IR, identifying all the state
variables of interest. This includes local variables as well as any other
pieces of state that are needed for whatever lints are enabled. This stage
records the set of state variables that could potentially be changed inside
each loop, block, closure, etc., for use in later analysis stages.
- SSA (single static assignment) analysis. A pass is made through the IR to
assign SSA node ids to each state variable and stack value. Queries are
generated at points that are of interest to whatever lints are enabled (e.g. a
lint that verifies that certain kinds of values are never null will generate
queries that ask "is the value represented by this SSA node null?").
- Query solver. Each query generated by SSA analysis is resolved by working
backwards through the IR, rewriting it in terms of previous SSA nodes, until a
point in the code is reached where the query either can or can't be
definitively answered. The mechanism for rewriting queries is inspired by
Prolog. Depending on the result of the query, a lint output might be
generated.
Other analysis stages might be added in the future. For example, if we find that
some lints can't be easily expressed in terms of queries, but can still benefit
from the SSA representation, we may add other analysis stages after SSA
analysis, to support those lints.
## Support structure
In addition to the pieces above, there is a simple interpreter that executes the
IR. The interpreter is not intended for production use; it is just sophisticated
enough to serve as the basis for unit testing the other stages. For example, we
use it in the unit tests of the AST-to-IR conversion stage, to make sure that
the output of this stage properly reflects Dart semantics. (If, instead, our
unit tests simply compared the output of AST-to-IR conversion to an expected
sequence of instructions, the unit tests would be much more brittle, and there
would be a much greater risk of human error in reviewing them.)

File diff suppressed because one or more lines are too long

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "68625bab86590a7ebe9e384ad0eedabd",
"index.html": "8c3bab0974079e7688b00bb3fc59f02a",
"/": "8c3bab0974079e7688b00bb3fc59f02a",
"index.html": "47bc35b1bd84d5f59e30dfd937306833",
"/": "47bc35b1bd84d5f59e30dfd937306833",
"assets/AssetManifest.bin": "054a099135a9f27b5ec05cbb690ec7aa",
"assets/fonts/SpecialElite-Regular.ttf": "0361d96faa98b0a716bec7e56e794c3d",
"assets/fonts/MaterialIcons-Regular.otf": "29fb5f62e1543123d6c11e2baff4cf84",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "1939055055";
const serviceWorkerVersion = "1348086192";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "abaeea879f3279d2833ea9b6d03fcc4f",
"index.html": "c173e9ec165ca23b6975d8012b7f786e",
"/": "c173e9ec165ca23b6975d8012b7f786e",
"index.html": "6681df26c26aae63fc18e7ad716bcdf5",
"/": "6681df26c26aae63fc18e7ad716bcdf5",
"assets/AssetManifest.bin": "693635b5258fe5f1cda720cf224f158c",
"assets/fonts/MaterialIcons-Regular.otf": "32fce58e2acb9c420eab0fe7b828b761",
"assets/AssetManifest.bin.json": "69a99f98c8b1fb8111c5fb961769fcd8",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "3576800701";
const serviceWorkerVersion = "1286285635";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "d3e8be9819697c196251e6e977053336",
"index.html": "9d219ce8405c676895c4838f43d70fba",
"/": "9d219ce8405c676895c4838f43d70fba",
"index.html": "729b7e846591ac3dbcc6f53e91194154",
"/": "729b7e846591ac3dbcc6f53e91194154",
"assets/AssetManifest.bin": "761912449bbe20af7dfbf06dcfc9616e",
"assets/fonts/MaterialIcons-Regular.otf": "2a5a36a9b82c9c429e9212d43eb01b78",
"assets/assets/music/Mr_Smith-Sonorus.mp3": "9353b7bb732002062e2c9107a95f3d2a",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "3910074359";
const serviceWorkerVersion = "1641474453";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "05f725318f41bf1601ead9ffa9355535",
"index.html": "bc2fc11bc506acb66877b822a6faceeb",
"/": "bc2fc11bc506acb66877b822a6faceeb",
"index.html": "ead050a1e77dc69f0f98074e6261c458",
"/": "ead050a1e77dc69f0f98074e6261c458",
"assets/AssetManifest.bin": "693635b5258fe5f1cda720cf224f158c",
"assets/fonts/MaterialIcons-Regular.otf": "ef1faf7fac4f017221b68758f47614d7",
"assets/AssetManifest.bin.json": "69a99f98c8b1fb8111c5fb961769fcd8",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "639307";
const serviceWorkerVersion = "1265655803";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "b3e6ffc626a7ddc3a2a95f62ee423a43",
"index.html": "9c90748c16c49f23683062dc74ae0836",
"/": "9c90748c16c49f23683062dc74ae0836",
"index.html": "c45941cbfde4b63a71e2777823fd3936",
"/": "c45941cbfde4b63a71e2777823fd3936",
"assets/AssetManifest.bin": "693635b5258fe5f1cda720cf224f158c",
"assets/fonts/MaterialIcons-Regular.otf": "890244a8648ef016cfdfc2d34b068a4d",
"assets/AssetManifest.bin.json": "69a99f98c8b1fb8111c5fb961769fcd8",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "2695912293";
const serviceWorkerVersion = "1848714903";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "470be0990b1a9c5a9011c08ba3d78e79",
"index.html": "9e602b78d1405fb9ac7823143d337c8b",
"/": "9e602b78d1405fb9ac7823143d337c8b",
"index.html": "49d4202ed2827d0d26b1be2030a41470",
"/": "49d4202ed2827d0d26b1be2030a41470",
"assets/AssetManifest.bin": "101b77a1c7d9a43813794867c09db513",
"assets/fonts/MaterialIcons-Regular.otf": "376dbca97bb1af68f8077738d363a10d",
"assets/assets/visited.png": "7ffb4d1849aa8c7899d2be15a4b71014",

@ -37,7 +37,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "1338828539";
const serviceWorkerVersion = "3417765670";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "8cd9b0527efb8828cd336f4a2bdd731e",
"index.html": "9b60b82a122a92faac7791db19cbcecb",
"/": "9b60b82a122a92faac7791db19cbcecb",
"index.html": "26432d415a625c8ee2f04d463c464b7c",
"/": "26432d415a625c8ee2f04d463c464b7c",
"assets/AssetManifest.bin": "f37b4f0c219a3862fa556e12e7a3ff68",
"assets/fonts/Corben/Corben-Bold.ttf": "8f9921f9c52d3c25fd354d6e01f7b024",
"assets/fonts/MaterialIcons-Regular.otf": "d79873b80524301499554a4713cef183",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "3356680825";
const serviceWorkerVersion = "504361848";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

@ -5,8 +5,8 @@ const CACHE_NAME = 'flutter-app-cache';
const RESOURCES = {"flutter.js": "7d69e653079438abfbb24b82a655b0a4",
"manifest.json": "fcc4cffd0f45ba41f31bdd5e05ca1ded",
"index.html": "728e2b6c2df9720755cdf4566834ba9b",
"/": "728e2b6c2df9720755cdf4566834ba9b",
"index.html": "eb83bf93cf2151d1819ab989e29ef213",
"/": "eb83bf93cf2151d1819ab989e29ef213",
"assets/AssetManifest.bin": "693635b5258fe5f1cda720cf224f158c",
"assets/fonts/MaterialIcons-Regular.otf": "3157eafc066cfa151439d4a7368bb3b3",
"assets/AssetManifest.bin.json": "69a99f98c8b1fb8111c5fb961769fcd8",

@ -34,7 +34,7 @@
<script>
// The value below is injected by flutter build, do not touch.
const serviceWorkerVersion = "2172241986";
const serviceWorkerVersion = "725908852";
</script>
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>

Loading…
Cancel
Save