Bug: https://github.com/dart-lang/sdk/issues/49351
Adds checks for the following cases:
- Type arguments to createStaticInteropMock are correct
- No missing members in implementing class
- Inherited and non-overridden @staticInterop members are implemented
- Dart class can implement through inheritance and mixins
- Implemented members are correct subtypes of @staticInterop members
- Potential extension member conflicts that are attempted to be
resolved through subtyping rules
Change-Id: Iacbe5846040ba7fab41459aa19be77351cf1efca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255761
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Reviewed-by: Riley Porter <rileyporter@google.com>
This introduces a MemberName abstraction that supports the late
computation of member names, taking privacy and synthesized names
of unnamed extensions into account. With this feature, the unnamed
extension are now more directly handled as having no (known) name
which avoids the clash between the eagerly synthesized named of
unnamed extensions in different parts.
Closes#48765
TEST=existing
Change-Id: I62c00ace017141ecbc61eeecb275d0211f341c82
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258800
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
I've begun prototyping what it might look like to integrate the
current shared type analysis functionality with the analyzer and CFE,
and I've discovered some API improvements that are needed:
- The shared logic now handles the possibility that switch cases that
share a body have been merged prior to type analysis (because the
CFE merges them during parsing), in addition to the pre-existing
functionality which assumed that switch case merging had to be done
in the shared logic.
- The shared logic now returns several pieces of information as the
result of a call to `analyzeSwitchStatement`: whether the switch
statement had a `default` clause, whether it was exhaustive, whether
the last case body terminates, and the type of the scrutinee. These
are all needed by the CFE.
- The shared logic now allows `TypeAnalyzer.errors` to be `null`,
indicating that no errors should be reported. This reflects how
errors are suppressed during top level inference in the CFE.
- If a switch case lacks a `when` clause, this is reported by calling
`handleNoWhen` rather than passing a boolean to `handleCaseHead`.
- The shared logic now reports the appropriate error when a case
constant doesn't properly match the scrutinee's static type.
- Information about case labels is now delivered to flow analysis via
`switchStatement_endAlternatives` rather than
`switchStatement_beginCase`. This made it possible to rewrite the
shared `analyzeSwitchStatement` method in a way that requires less
bookkeeping, because it no longer has to peek ahead to look for
labels associated with a given case body.
- `TypeAnalyzer.analyzeExpression` is now responsible for
understanding that "no context" and a context of `dynamic` should
both be coalesced to `?`. The analyzer does this (although it's not
100% why), and it's definitely "business logic" that eventually
belongs in the shared type analyzer.
- `TypeAnalyzer.analyzeSwitchExpression` and
`TypeAnalyzer.analyzeSwitchStatement` no longer receive a list of
ExpressionCaseInfo / StatementCaseInfo objects describing the cases;
instead they query for them using a callback. This reduces the
lifetime of the ExpressionCaseInfo / StatementCaseInfo objects. In
the future, when we have record support, we could replace these
objects with records, which would then be passed on the stack,
avoiding any allocations.
- A new hook, `handleSwitchScrutinee`, is called right after visiting
the "scrutinee" expression of a switch expression or switch
statement. This hook is needed by the analyzer to compute
exhaustiveness. In a future CL, I hope to move exhaustiveness
analysis into the shared code as well, which should make this hook
unnecessary.
- `TypeAnalyzer.analyzeSwitchStatement` now reports an error if a
switch case completes normally and pattern support is not enabled.
- The test class `_MiniAstTypeAnalyzer` no longer overrides
`analyzeExpression` to provide a default context type; instead,
every call to `analyzeExpression` that didn't previously provide a
context now provides a context of `?`. Note that not all of these
are correct, but they are close enough for the unit tests we have
today. I plan to fix them in future CLs as I replace this logic
with shared logic.
- The hook `handleVariablePattern` is now always provided with a
static type. Previously, it was only provided with a static type if
this was the first time the variable was bound in the pattern.
Change-Id: I70e3c5468312a9329fcf4ad2e13749a32d2418e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/257487
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Rename `_CompactLinkedHashSet` to `_InternalLinkedHashSet` and
`_CompactImmutableLinkedHashSet` to `_InternalImmutableLinkedHashSet`
to make the names consistent with the corresponding `Map` class names
and to distinguish them from the non-VM-specific hash maps and sets,
which are generally named starting with `_Compact`.
Tested: ci
Change-Id: Ic1ebc44ba8beba34ceab382a4edddc6624fe3fb3
Cq-Include-Trybots: luci.dart.try:vm-kernel-precomp-linux-debug-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/258002
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
localMembersIterator uses filteredIterator under the hood, meaning that
it does a `is T` check internally. When then using it to only process a
specific type like this:
```
Iterator<Builder> iterator = builder.localMembersIterator;
while (iterator.moveNext()) {
Builder childBuilder = iterator.current;
if (childBuilder is SourceClassBuilder) {
// do something
}
}
```
we're doing two `is` checks, and also this - I think - reads easier:
```
Iterator<SourceClassBuilder> iterator = builder.localMembersIteratorOfType();
while (iterator.moveNext()) {
SourceClassBuilder childBuilder = iterator.current;
// do something
}
```
Change-Id: I6641343874ade3cf938aacc5dc0a7aa36bad9550
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/257361
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
This changes how scopes are computed for libraries and classes
(work on extensions is still pending). The change supports the new
shared scope need for augmentations, in which a declaration on the
origin or any of the augmentations is directly accessible in the
origin and all augmentations.
Change-Id: Ifb76f49bf80fcad2d92a0400b9be623406afb40d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/256262
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This updates the SourceLibraryBuilder.origin to return the effective
origin library and not just the immediate origin. In case of an
'import augment' in a part file, the immediate origin is set to the
part "library". Since the part is not a real library, the augmentation
library should not (try to) depend on that library but instead the
library containing the part.
Change-Id: I8ca1345c2e7c5bef71a7a1f9bed41a3bc4e538d0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255256
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Several unusual constructs that lead to unreachable code are now
recognized by flow analysis:
- Control flow after an expression of the form `e ?? other` or `e ??=
other`, where `e` has static type `Null` and `other` has static type
`Never`, is considered unreachable.
- Control flow predicated on an expression of the form `e is Never`
evaluating to `true` is considered unreachable.
- Control flow predicated on an expression of the form `e is! Never`
evaluating to `false` is considered unreachable.
- Control flow on the RHS of a null-aware access such as
`e?.property...`, `e?.property = ...` or `e?.method(...)`, where `e`
has static type `Null`, is considered unreachable (Note: this can
arise in the presence of extension methods).
Previously, these behaviors only took effect if `e` was a reference to
a local variable.
Note: the change to `regress/issue_31180` is because I’ve corrected
the behavior of implicit temporary variables to not undergo a type
change from `Null` to `dynamic`, so the dead code part of `null?[1]`
is now erroneous. (I had to make this change in order for the last
bullet above to work properly; without it, the type change to
`dynamic` prevents flow analysis from recognizing that the code to the
right of `?.` is unreachable.) There's no behavioral change to
correct code, but I've captured the behavioral change to incorrect
code in
`tests/language_2/null_aware/null_aware_index_on_null_error_test.dart`.
Bug: https://github.com/dart-lang/sdk/issues/49635
Change-Id: I8b24b3b040a34f897c0b61dcb9bd105be6d0af6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/251280
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This adds the flag `isEnumElement` to the `Field` node and uses it
to recognize enum elements for the exhaustiveness computation on
switch statements.
Closes#49697
TEST=pkg/front_end/testcases/general/issue49697/main.dart
Change-Id: I21852f3b063329e043639c825054f538c8ed6536
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255808
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This uses the `Procedure.signatureType` for checking super access
instead of the types derived from `Procedure.function`. This fixes
the checking of super access in face semi-stubs where the parameter
types have a more restrictive but covariant type.
Change-Id: I8b21238687bcec8e5e42a999c5a94d0e65cac28c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255660
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Scope.forEach iterates through the builder immediately mapped in the
scope. For duplicate declarations, this means that it'll give direct access to the last defined declaration and not to the first defined
declaration, which is inconsistent with how we generally handle
duplications. It also doesn't skip builders that are not "owned" by
the scope but merely accessible, which means that we easily have
duplicate handling of patches and augmentations which are part of
both the scope in which the were declared and the scope of the origin.
To normalize the handle of scope, this CL removes Scope.forEach
with iterators that explicit filter what subset of the builder
that we want to have access to. This prepares for the more complex
scope introduced by the augmentation libraries in which all
scopes have access to all declarations from the origin library as
well as other augmentation libraries.
Change-Id: I88bdfb1068fbb4eb9dd6fa3881b86a61104e50e3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255240
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This change breaks flow_analysis.dart into the following libraries:
- assigned_variables.dart (for the AssignedVariables class and related
code)
- promotion_key_store.dart (for the PromotionKeyStore class)
- type_operations.dart (for the TypeOperations mixin and related code)
- flow_analysis.dart (for the rest of flow analysis)
And it breaks mini_ast.dart into the following libraries:
- flow_analysis_mini_ast.dart (functionality specifically concerned
with testing flow analysis)
- mini_ast.dart (functionality not specifically related to flow
analysis)
This is in preparation for trying to share some more type inference
behaviors between the analyzer and CFE.
Note that although the diff is big, the only changes in this CL are
moving code from one place to another, renaming some class members
from private to public, and updating imports.
Change-Id: I71768f03b1e75ed754c7b7af39f6cf7f03c4fe44
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254462
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This change splits the `Harness` class into a base class, `Harness`,
which in principle can be used for testing type inference logic in
general, and a derived class `FlowAnalysisTestHarness`, which is
specialized for flow analysis tests.
This is in preparation for trying to share some more type inference
behaviors between the analyzer and CFE.
Change-Id: Ic56b8dd8748065ca59e246e0d804946cc69203c3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254280
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This pipes the expression type for a generated property setter, such
that synthesized variables in let expressions created for the generated
setter expression are typed correctly.
Before this change a let variable created for an extension property set
would use the value type even though the extension property setter is
method with a void return type.
Change-Id: I3fb0aaef7893e333352be81a2c8fced2a0a869fe
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253781
Reviewed-by: Aske Simon Christensen <askesc@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This adds
* for_in.dart with ForInResult and ForInVariable classes
* inference_results.dart with all *Result and NullGuard classes
* inference_visitor_base.dart with InferenceVisitorBase and its helpers
* mixin_inferrer.dart with MixinInferrer
* object_access_target.dart with the ObjectAccessTarget classes
Leaving
* inference_visitor.dart with InferenceVisitor(Impl) and helpers
* type_inferrer.dart with TypeInferrer(Impl) and helpers
Makes
* closure_context.dart a library instead of a part
Change-Id: Ib26fae2f2b2ee6c18edcd32dc12d35d1072d4a8e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/254020
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This reverts commit a5fda59219.
Reason for revert: breaks calling extension setters with `?.`, see b/241059207
Original change's description:
> [cfe] Use `void` for let-expressions for extension property set
>
> This pipes the expression type for a generated property setter, such
> that synthesized variables in let expressions created for the generated
> setter expression are typed correctly.
>
> Before this change a let variable created for an extension property set
> would use the value type even though the extension property setter is
> method with a void return type.
>
> Change-Id: I1e7d31eaf1410bb06d55e2845403865e0c7af452
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252742
> Commit-Queue: Johnni Winther <johnniwinther@google.com>
> Reviewed-by: Aske Simon Christensen <askesc@google.com>
TBR=johnniwinther@google.com,askesc@google.com
Change-Id: Iaafd12833939cbd38e09787fcdb5a4c78a964656
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/253440
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Ilya Yanok <yanok@google.com>
Reviewed-by: Ilya Yanok <yanok@google.com>
This pipes the expression type for a generated property setter, such
that synthesized variables in let expressions created for the generated
setter expression are typed correctly.
Before this change a let variable created for an extension property set
would use the value type even though the extension property setter is
method with a void return type.
Change-Id: I1e7d31eaf1410bb06d55e2845403865e0c7af452
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/252742
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>