Previously, initializers of implicitly typed variables did not
contribute to the SSA tracking performed by flow analysis (see
https://github.com/dart-lang/language/issues/1785). This change fixes
the bug, however the fix is conditioned on the "constructor tearoffs"
language feature to avoid compatibility issues (we don't want someone
to publish a package taking advantage of the fix, without realizing
that it makes their package unusable on older SDKs).
TEST=standard trybots
Bug: https://github.com/dart-lang/language/issues/1785
Change-Id: I1143440c7a9795b059e8f4b84e3f4125cd80732c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211306
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
When the parser encounters a `<` after an expression, it must choose
whether to interpret it as a relational operator or a <typeArguments>
selector. The disambiguation rule is: if the `<` and the tokens
following it *can* be parsed as <typeArguments>, and the token that
follows is a member of a privileged set of tokens, then it is treated
as a <typeArguments> selector; otherwise it is treated as a relational
operator.
This change reduces the privileged set of tokens to the following:
- the "continuation tokens" `(`, `.`, `==`, and `!=`
- the "stop tokens" `)`, `]`, `}`, `;`, `:`, and `,`
The names "continuation tokens" and "stop tokens" reflect the
rationale for choosing these tokens:
- Continuation tokens are tokens that we can reasonably imagine a
programmer wanting to place after a type argument selector to
*continue* the expression. For example, `if (List<int> == T) ...`
is allowed.
- Stop tokens are tokens that can't possibly follow a `>` that is a
relational operator, because they *stop* the expression that's in
progress. For example, `var x = List<int>;` is allowed.
If a user wants to follow a <typeArguments> selector with a token
other than the ones above, they'll have to parenthesize the
expression. So for example, if they want to do `List<int> + 1` (which
could be meaningful if an extension method defined `operator +` for
the type `Type`), they will have to use parentheses, and instead write
`(List<int>) + 1`.
Bug: https://github.com/dart-lang/language/issues/1806
Change-Id: I2816cdac24e55eac3cb3e9920e276404c1228d46
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210941
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Previously, the analyzer and CFE were responsible for two pieces of
logic that arguably should be in the shared flow analysis engine:
- Deciding whether or not it's necessary to tell flow analysis about
initializer expressions.
- Deciding whether or not to promote the variable at the time of
initialization (we do this when the variable is implicitly typed,
and the initializer is a promoted type variable type).
It's better to just always tell flow analysis about the initializer
expression and let it decide what to do about it.
This paves the way for fixing
https://github.com/dart-lang/language/issues/1785 (which results from
initializer expressions sometimes being ignored when they shouldn't
be), by consolidating the broken logic into the flow_analysis library,
where it will be easy to unit test the fix.
Bug: https://github.com/dart-lang/language/issues/1785
Change-Id: Iec832e92995eb4f8d0c1fbd4e9be6c897e0917b5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211180
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
`int` variables can attain NaN values because web int arithmetic
implemented by JavaScript numbers (doubles) is not closed under many
operations. It is possible get NaN using only addition:
int a = 1, b = -1;
while (a + a != a) { a += a; b += b; }
int nan = a + b;
On the VM, a, b and nan are all zero.
On the web, a, b and nan are Infinity, -Infinity and NaN, respectively.
Since NaN can leak into int arithmetic, is it helpful if bounds checks
catch NaN indexes. NaN compares false in any comparison, so a test
of the form
if (index < 0 || index >= a.length) throw ioore(a, index);
fails to detect a NaN value of `index`.
This is fixed by negating the comparisons, and applying De Morgan's law:
if (!(index >= 0 && index < a.length)) throw ioore(a, index);
These changes have been applied to JSArray.[], JSArray.[]= and String.[]
For dart2js the change is a little more involved. Primitive indexing is
lowered to code with a HBoundsCheck check instruction. The code generated
for the instruction now uses, e.g. `!(i>=0)` instead of `i<0`.
This leads to a small code size regression.
There is no regression at -O4 since bounds checks are omitted at -O4.
At -O3 (where the regression is largest) the regression is
0.01% for cm
0.06% for flutter gallery -- array-heavy diff and layout
0.21% for Meteor -- array-heavy code
0.30% for Box2DOctane -- array-heavy code
I believe the regression can be largely alleviated by determining if
NaN is impossible at the index check, and if so, reverting to the smaller
code pattern. The analysis could be global, incorporating NaN into the
global abstract value domain, or a much simpler a local dataflow
analysis. Many indexes are loop driven and cannot reach infinity because
they are incremented by a small bump and eventually (even without a loop
guard) the index would stop growing when the increment falls below the
rounding error in O(2^53) iterations.
Change-Id: I23ab1eb779f1d0c9c6655e13d69f65d453db9284
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210321
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Every known user of the coverage report just wants the line numbers. At
the moment they have to do a second RPC to get the Script object, so
they can translate the token positions into line numbers.
Slower test times with coverage are usually caused by the extra time it
takes to run the RPCs. So reporting the line number directly will halve
the time it takes to get coverage, for most users.
Bug: https://github.com/flutter/flutter/issues/86722
Change-Id: I7b8d436669713ebc7b7096790a02593b9cb94dda
TEST=CI
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211081
Commit-Queue: Liam Appelbe <liama@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
https://github.com/dart-lang/language/issues/1785 has a wide enough
impact that its fix will have to be bundled in with a language version
(i.e. future versions of Dart will have to reproduce the old buggy
behavior for code that's not opted in to the latest language version).
Therefore, we'll have to maintain tests of the behavior both before
and after the fix. This CL is the first step in that process, adding
tests that validate the current (buggy) behavior.
Bug: https://github.com/dart-lang/language/issues/1785
Change-Id: I78f17999ac1cbc096a312ef977db24654e06a263
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210400
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This flag prepares for the removal of the special case of implicit
creation syntax, `foo<bar>.baz()`, which with constructor-tearoffs
doesn't have to be a creation expression. Since both the analyzer
and the CFE needs to support parsering without special casing
before it can be removed, the flag is added to ensure both
implementations will agree on what the future parser behavior will be.
The CL hard-wires the CFE use of the parser to a single constant value.
Change-Id: I04724f039d2e698f3cf67e8b0b56dfa7e96ed3b4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211000
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Tool will try to extract useful information from invalid (e.g. partial
or wrong version) dill.
This is a first stab and could possibly be extended and improved in the
future.
Change-Id: Ib381794a3fe80036bb845800488fa0e1a7f04f83
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211241
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Formatted with `--fix`, followed by some small manual changes:
- Reflowed some comments to 80 columns.
- Replaced Map/Set constructor calls with {} literals.
- Removed type argument when on both sides of initialization.
Change-Id: I3f5d29dd7e144f96a02efa95db8b40bf63484442
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/210940
Commit-Queue: Stephen Adams <sra@google.com>
Reviewed-by: Mayank Patke <fishythefish@google.com>
Looking atanges to the tests I wasn't sure whether this was a good change
to make, but the metrics improve for both locations as a result:
CompilationUnit_declaration 64.159 | 58.277 -5.882
CompilationUnit_directive Infinity | 88.826 -Infinity
The tests mostly cover the case where insertion is between the two, and in
those cases we might want a blend of the two because it's impossible to know
whether the user is adding a directive after the last directive or adding
a declarartion before the first declaration. But that's a topic for a
different CL.
Change-Id: I2b82209ab77796d0bc8b9fc4a7c0ab91293c3746
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211083
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
Not used yet, mostly to get your opinion. If OK, will work on using it.
Change-Id: I772c6ab7547d5ca53a7e3949dc0874d7382a6439
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211042
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
I found this while testing a change to the computation of the completion
location in `OpType`. The experiment started producing a completion
location that wasn't previously produced, and that's what led to it being
a key for one set of data but not in the other set of data.
Change-Id: I3938ae68ec61afbef98d9674c7d6377fa4120d4a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/211100
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>