LocalVariableElement(s) and ParameterElement(s) are unique, and are not
equal across functions. So, we can use a single instance of
LocalVariableInfo. We don't need it for CompilationUnit though.
Actually, we don't need LocalVariableInfo in each FunctionBody, but
our API exposes isPotentiallyMutatedInClosure/Scope from FunctionBody.
Change-Id: I446101020efec7727c7aabd6dd3369563a926d33
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123160
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
We now have multiple messages for the same name (id) and all of the
messages should be included in the docs so that users aren't confused
when the message they see doesn't match what's documented.
Change-Id: I0f668ececae1e9852eff9db25f29a48b7414c4d3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123141
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
If the RHS of an assignment is a subtype of the current promoted type
(or one of the previously promoted types), any relevant promotions are
kept.
So for example:
if (x is int) {
x = x + 1; // Still an int!
print(x.isEVen); // ok
}
This required two significant changes:
- Clients must now tell the flow analysis engine the type of the RHS
of the assignment. This required some refactoring in the analyzer,
because this information wasn't always easily available at the point
where we were calling flow analysis.
- The flow analysis engine now has to keep track of a "chain" of the
currently active promotions, so that it can potentially un-do some
promotions but not others. This meant that the algorithms for
"join" and "restrict" had to be reworked.
In a future CL I'll add the ability for assignments to promote to
types that have been previously checked against ("types of interest"),
e.g.:
if (x is! int) {
x = 0; // x is now an int!
}
// x is now known to be an int because it's promoted in both branches
Change-Id: I63d6c9a2021b045d391b2d9c674e9a2e5f770e62
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123003
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Currently we only use this logic when the for-each loop declares its
own loop variable, and that loop variable doesn't have an explicit
type. However, for NNBD, we'll need to use the same logic for when
the for-each loop doesn't declare its own loop variable, so that flow
analysis can see whether the implicit assignment to the loop variable
should un-do type promotions or not. Since flow analysis integrates
via the ResolverVisitor, we need the inferred type to be accessible to
the ResolverVisitor. So we create a new method
`StaticTypeAnalyzer.computeForEachElementType` to compute the type,
and call it from `ResolverVisitor`.
Change-Id: I544d72371a6c710297e467b9b37bd909490a7336
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122880
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
https://github.com/dart-lang/language/blob/master/resources/type-system/subtyping.md#rules
This includes subtyping tests ported from CFE.
Performance is on par with the performance before this changes.
On package:flutter, when each isSubtypeOf() is executed 100 times,
timings are 35292 ms vs. 33838 ms spent on isSubtypeOf() itself
(not the whole analysis times). So, the difference is about 5%,
but because it is 100x, it should result in less than 0.05% of total
analysis time difference.
There are other optimizations that we can make in this area, though.
For example checking for `Object?` could be done using identical() to
avoid expensive megamorphic (I think) `isDartCoreObject`. Similarly
for checks for `Null` and `FutureOr`.
Google3 presubmit looks green.
https://test.corp.google.com/ui#id=OCL:276348418:BASE:276562990:1571960231050:ff94b8d8
Change-Id: I0b7e5baba82908e1123783c4a9494b1dfc74ea99
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122682
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This should make it easier to verify that the CFE implementation is
correct.
Note that this effort encountered a few bugs in the analyzer
implementation, which are marked with TODOs. I will fix them in
follow-up CLs.
Change-Id: Ic164a1cf214b5730f848b17db2838c29d25b00d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122850
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
These data structures are only used for testing (and are not even
created in normal production use). Add "ForTesting" to their names so
that we are less likely to use them by accident.
Change-Id: Ic719d66089a692362957e257c9bbb2f632bfd174
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122980
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Remove markdown from diagnostic messages,
Format messages to fit in 80 lines,
Sort unsorted file,
Move diagnostic tests to the correct test classes,
Remove diagnostic that is no longer being generated.
Change-Id: I1dbd6a141a4ef31eb89d9ea5edfd17512cbb261a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122821
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Previously, the client was responsible for querying AssignedVariables
to find the variables assigned and captured during constructs like
loops, and passing that information into FlowAnalysis methods. With
this CL, the client simply passes AssignedVariables into the
FlowAnalysis constructor, and the lookup happens automatically.
Change-Id: Ifbbf8ba8ea0d0f8a31d41244892c8c816eea56dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122731
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When analyzing an expression like `x += y`, where `x` may be type
promoted, we need to consider x's unpromoted type when determining
whether the result of the addition may be assigned to `x`. Before
flow analysis, we didn't need to worry about this subtlety because the
appearance of `x` on the LHS of an assignment used to disqualify it
from type promotion within any scopes containing the assignment.
Change-Id: I17887c457c9d0ce17ce704884e04d93ca8a3e925
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/122587
Reviewed-by: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>