Change the analyzer's use of the following shared generic types so
that it supplies the type parameter `TypeParameterElementImpl2`
instead of `TypeParameterElement` as the type it uses to represent
type parameters:
- `GeneratedTypeConstraint`
- `MergedTypeConstraint`
- `SharedFunctionTypeStructure`
- `SharedInferenceLogWriter`
- `SharedInferenceLogWriterImpl`
- `TypeAnalyzer`
- `TypeAnalyzerOperations`
- `TypeConstraintFromArgument`
- `TypeConstraintFromExtendsClause`
- `TypeConstraintFromFunctionContext`
- `TypeConstraintFromReturnType`
- `TypeConstraintGenerator`
- `TypeConstraintGeneratorMixin`
- `TypeConstraintOrigin`
- `UnknownTypeConstraintOrigin`
This required adding type casts in a few places. In other places, I
avoided type casts by tightening up some return types (for example,
`InstanceElementImpl2.typeParameters2` now returns
`List<TypeParameterElementImpl2>` instead of
`List<TypeParameterElement2>`. The analyzer public API was unchanged,
though (for example, `InstanceElement2.typeParameters2` still has a
return type of `List<TypeParameterElement2>`), so clients should be
unaffected.
As a result of this change, it is no longer necessary for a public API
class to implement the shared interface
`SharedTypeParameterStructure`. This interface was previously
implemented by `TypeParameterElement`; it is now implemented by
`TypeParameterElementImpl2`, which is not a part of the analyzer
public API.
This is part of a larger arc of work to change the analyzer's use of
the shared code so that the type parameters it supplies are not part
of the analyzer public API. See
https://github.com/dart-lang/sdk/issues/59763.
Change-Id: Ic6d42b415620430210e25ed212b11e03851d25ed
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402500
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Change the analyzer's use of the following shared classes and mixins
to supply `PromotableElement2` instead of `PromotableElement` as the
type parameter that represents promotable variables:
- `AssignedVariables`
- `AssignedVariablesForTesting`
- `CaseHeadOrDefaultInfo`
- `DemoteViaExplicitWrite`
- `FlowAnalysis`
- `GeneratedTypeConstraint`
- `MatchContext`
- `MergedTypeConstraint`
- `NonPromotionReasonVisitor`
- `SwitchExpressionMemberInfo`
- `SwitchStatementMemberInfo`
- `TypeAnalyzer`
- `TypeAnalyzerErrors`
- `TypeAnalyzerOperations`
- `TypeAnalyzerOperationsMixin`
- `TypeConstraintFromArgument`
- `TypeConstraintFromExtendsClause`
- `TypeConstraintFromFunctionContext`
- `TypeConstraintFromReturnType`
- `TypeConstraintGenerator`
- `TypeConstraintGeneratorMixin`
- `TypeConstraintOrigin`
- `UnknownTypeConstraintOrigin`
- `VariableBinder`
- `VariableBinderErrors`
This ensures that all references to variables within the shared code
are using the new analyzer element model.
As a result of this type change, a lot of analyzer code that
interfaces with shared logic needs to change to use the new element
model.
Also, a few additional members need to be added to
`BindPatternVariableElementImpl2`, `JoinPatternVariableElementImpl2`,
`LocalVariableElementImpl2`, and `PatternVariableElementImpl2` to
allow members of the underlying `_wrappedElement` to be accessed.
Change-Id: Ie925eeb82523c769c4d869a37551718f75d334ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/400660
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This adds support for replacement a [StaticGet] with the constant
initializer of the referenced constant during evaluation of macro
metadata. Currently constants defined in the same library or
compilation is supported. For full support the constant initializers
need to be included in the outlines/summaries.
Change-Id: I219f85dded63342d4e3f957f0b7321badbe376a4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392907
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This delays the resolution of the identifier in metadata, such the
parsed annotation expression is initially unresolved and
`Expression.resolve` must be called in order to resolve it.
This execises the support for references to identifiers declare via
macros, which will initially occur as unresolved identifiers.
Change-Id: I4863ce950ded0b9d2c1744421d9751cddea6e80c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391641
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This adds a shared metadata parser to be used for macros. The parser
create a new AST which supports unresolved ASTs and delayed AST resolution.
An id-test is added for the generated AST from both CFE and analyzer.
Change-Id: Ie51817493fa6e668727a7af3a55cd22e2be722b3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/391100
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This warning is similar to the existing `UNREACHABLE_SWITCH_CASE`
warning, except that it warns if the `default` clause of a switch
statement is unreachable due to all the `case` clasuses fully
exhausting the switched type.
To make the implementation easier, I changed the API for the
`reportExhaustiveness` method in `_fe_analyzer_shared` (which is the
primary entry point to the shared exhaustiveness checker). Previously,
this method returned a list of `ExhaustivenessError`, where each list
element was either an `UnreachableCaseError` (indicating that a
certain case was unreachable) or a `NonExhaustiveError` (indicating
that the entire switch statement was not exhaustive). If the caller
passed in `false` for `computeUnreachable`, `UnreachableCaseError`s
would not be returned, so the returned list would either be empty or
contain a single `NonExhaustiveError`.
The new API renames the types for clarity:
- `NonExhaustiveError` becomes `NonExhaustiveness`, to highlight the
fact that it's not necessarily an error for the switch's cases to be
non-exhaustive; it's only an error if the scrutinee's static type is
an "always exhaustive" type and there is no `default` clause.
- `UnreachableCaseError` becomes `CaseUnreachability`, to highlight
the fact that it's not an error for a case to be unreachable; it's a
warning.
Also, the new API adds instances of `CaseUnreachability` to an
optional user-provided list instead of returning a newly created list;
this allows callers to communicate that they don't need to see
`CaseUnreachability` information by passing `null`. This frees up the
return type to simply be an instance of `NonExhaustiveness` (if the
cases are not exhaustive) or `null` (if they are exhaustive). This
makes it easier for the analyzer to decide whether to issue the new
warning, because it doesn't have to dig around the list looking for an
instance of `NonExhaustiveness`.
The new warning has an associated quick fix (remove the unreachable
`default` clause). This quick fix uses the same `RemoveDeadCode` logic
in the analysis server that the existing `UNREACHABLE_SWITCH_CASE`
warning uses.
Fixes https://github.com/dart-lang/sdk/issues/54575.
Bug: https://github.com/dart-lang/sdk/issues/54575
Change-Id: I18b6b7c5249d77d28ead7488b4aae4ea65c4b664
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/378960
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This CL removes Type and TypeSchema type variables from the abstract
classes with shared code between the CFE and the analyzer. Extension
types SharedTypeView and SharedTypeSchemaView are declared to replace
the type variables.
The update propagates the discipline of distinguishing between types
and type schemas into the clients of the shared code. Now the code in
the CFE and the Analyzer that uses the shared code needs to statically
specify the interpretation of their type objects as either types or
type schemas.
Another benefit of the update is SharedTypeView and
SharedTypeSchemaView being less opaque than the Type and TypeSchema
type variables, which removes the necessity for some code duplication
in abstract methods for types and type schemas.
Finally, the update enables some further changes in the shared code
between the Analyzer and the CFE.
Change-Id: I88e8cfcd47d4f721974b4f2612521e85bb54c30f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379302
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Work towards https://github.com/dart-lang/language/issues/2
The feature is well-specified at the issue, but I will also follow
up with a specification to check into the language repo.
This change implements the feature more-or-less from front to back
(because the back is very close to the front in this case :P; no
"backend" work in the VM, etc). Digit separators are made available
via a new experiment, `digit-separators`.
Care is taken to report a single error when an underscore appears in
an unexpected position (see new `separators_error_test.dart`).
Three test files are added:
* `separators_test.dart` is run with the experiment enabled, and has
no compile-time errors.
* `separators_error_test.dart` is run with the experiment enabled, and
has many compile-time errors.
* `separators_error_no_experiment_test.dart` is run with the
experiment _disabled_.
Change-Id: I7f1b1305d28b708b5ddf83f26188cd6e9ce3dd58
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365181
Commit-Queue: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
Reviewed-by: Kevin Moore <kevmoo@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
As much as I don't like the scale of changes, there is no valid variable in these cases. So, we express this explicitly, without trying to pretend that there is on. Or crashing as we did without this CL.
Change-Id: I74cef1d3d9d3cba6985d83b98be361cca09170f9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/355300
Reviewed-by: Phil Quitslund <pquitslund@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This updates the checking order of the exhaustiveness algorithm to
process the sealed type on its own before checking the subtypes. This
has the benefit that for fields that fully covered by (a supertype of)
the sealed type itself, like a wildcard pattern, we avoid checking
each individual subtype.
For the exponential cases added in
https://dart-review.googlesource.com/c/sdk/+/291800
this avoids the exponential growth, bringing the number of checked
witness candidates from 837932 to 6 for the "subtype" test with n = 30 and from 12207032 to 12 for the "fields" test with n = 10.
The change also fixes a problem in the 'future_or_members.dart' caused by the non-null version of 'FutureOr<dynamic>' still being nullable. The old algorithm tried to use 'Object' as a witness canditate but filtered out 'FutureOr<dynamic>' because 'Object' wasn't a subtype if it. The new algorithm starts by using 'Object?' and therefore sees that 'FutureOr<dynamic>' exhausts it. This is an inherent problem in the modelling of StaticType and it should still be addressed.
Change-Id: Iaa5d5604afc4662fe1983d670638223eae5dbf6b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/291822
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This updates the toString on Witness to produce pattern code. The
created pattern is directly derived from the predicates of the
witness and there contain some needless precision, for instance
`[...[...]]` instead of `[...]`. It is the plan to address this in
a follow-up.
Change-Id: Ied7930f36b1e1818540b8c635b18ff92f28e113b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/290720
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This adds support for exhaustiveness checking of list types by
contextually dividing the list type into relevant cases for checking.
For instance, the exhaustiveness can be achieved by a single pattern
case [...]:
or by two disjoint patterns:
case []:
case [_, ...]:
When checking for exhaustiveness, witness candidates are created and tested against the available cases. This means that the chosen candidates must be matched by at least one case or the candidate is considered a witness of non-exhaustiveness.
Looking at the first example, we could choose `[...]`, the list of
arbitrary size, as a candidate. This works for the first example, since the case `[...]` matches the list of arbitrary size. But if we tried to use this on the second example it would fail, since neither `[]` nor `[_, ...]` fully matches the list of arbitrary size.
A solution could be to choose candidates `[]` and `[_, ...]`, the empty list and the list of 1 or more elements. This would work for the first example, since `[...]` matches both the empty list and the list of 1 or more elements. It also works for the second example, since `[]` matches the empty list and `[_, ...]` matches the list of 1 or more elements.
But now comes a third way of exhaustively matching a list:
case []:
case [_]:
case [_, _, ...]:
and our candidates no longer work, since while `[]` does match the empty
list, neither `[_]` nor `[_, _, ...]` matches the list of 1 or more
elements.
This shows us that there can be no fixed set of witness candidates that we can use to match a list type.
What we do instead, is to create the set of witness candidates based on the cases that should match it. We find the maximal number, n, of fixed, i.e. non-rest, elements in the cases, and then create the lists of sizes 0 to n-1 and the list of n or more elements as the witness candidates.
Change-Id: I27d594699a65510636a2b7811c60c261a02f9b57
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/287680
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Only the fields of a scrutinee type that are used in the cases are
now shown in the test expectations. When the field is not present,
for instance when the scrutinee type is nullable, or the fields are
only present on (some of) the subtype of the scrutinee type, the
fields are shown to be missing with a `-`.
Change-Id: I2d36b230e979dc929d083cfb8f9cdb9f1143d380
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/287280
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This remove the [Space] class from the old algorithm and instead
encodes the patterns into the new model. The [Pattern] and
[Patterns] classes of the new model have been renamed to
[SingleSpace] and [Space], respectively, and a [Path] class is
added to track the path property used in the model of the new
algorithm.
Change-Id: I0c86c738807030be2f9b59f3aefb5bfcf5bbaeee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286501
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This adds support for generic types in exhaustiveness checking.
There are two main obstacles:
1) Types that are not Dart subtypes might be related in the context
of exhaustiveness. For instance
sealed class A<X> {}
class B extends A<num> {}
method<T>(A<T> a) {
switch (a) {
case B(): ...
}
}
Here B is not a Dart subtype of A<T> but must still be a subtype
in the context of exhaustiveness since T could be num at runtime.
2) It is non-trivial to compute the subtypes of a generic sealed class
that is both sound and precise enough to be useful. For instance
sealed class A<X> {}
class B extends A<num> {}
class C<X> extends A<X> {}
class D<X extends num> extends A<X> {}
class E<X extends E<X>> extends A<X> {}
Computing the subtypes of A<F> for some type F, we would like to
exclude B (assuming F is not a supertype of num) because it
cannot be inhabit A<F>, and include C<F> so that we recognize
that C<F> exactly covers all C instances of A<F>. We would also
like to include D<F> but if we don't include the added `extends
num` bound, we might conclude that D<num> is _not_ sufficient to
cover D<F>. And what to do about E, can we even come up with a
type that represents the valid values?
The solution is threefold:
1) We add an 'overapproximate' function of types, which
replaces all type variables with their default types. This will compute
A<dynamic> for A<T>, A<int> for A<int>, A<List<dynamic>> for A<List<T>>,
and E<dynamic> for E<T extends E<T>>. This is similar to instantiate-
to-bounds, but is recursive.
We use this to test whether a type without type variables is a potential
subtype. For instance testing B <: overapproximate(A<F>) = A<F> shows
that B _cannot_ be a subtype of A<F>, and testing
B <: overapproximate(A<T>) = A<dynamic> shows that B _can_ be a subtype
of A<T>.
2) For finding subtypes of a sealed type, we recognize the case
when a type is a trivial subtype in which all type variables are passed
directly to the superclass, for instance like C<T> in the example. For
other cases we overapproximate the this type of the subclass.
3) To ensure that the [StaticType] can be subtype in the normal Dart
sense but also handle the overapproximation when computing sealed
subtypes, a new [WrappedStaticType] is added. This bridges the subtype
relation such that for instance B, when created as a sealed subtype
of A<T>, is both a subtype of A<num> (as it normally is) and of A<T>,
which it is by construction.
Change-Id: I9970c46009938ef15625e1193faf916b7544ce0b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/284681
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This adds the initial implementation of exhaustiveness checking in
the analyzer and CFE. The checking is currently only performed in
switch statements and only handle a subset of the patterns.
Change-Id: Ia0050c2c80fbefe3e22615599136f9d919ebe4ef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/279173
Reviewed-by: Jonas Termansen <sortie@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>