Revert "[analyzer][cfe] Expand TypeAnalyzerOperations. Part 1"
This reverts commit a8cf0a08254bce394e16859a884de9ced5539b05.
Reason for revert: The CL broke a few places in google3.
Original change's description:
> [analyzer][cfe] Expand TypeAnalyzerOperations. Part 1
>
> This CL adds more of the type operations required in the subtype
> constraint gathering algorithm into the shared type operation
> class. The added operations are used in the constraint gathering
> algorithms in the Analyzer and the CFE.
>
> Part of https://github.com/dart-lang/sdk/issues/54902
>
> Change-Id: Ia895fc84bd7ab666330a4ab32b6e759f0977e750
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/346840
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Reviewed-by: Paul Berry <paulberry@google.com>
> Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Change-Id: Ibf75bb6dda4a4f5f36a2265036703977b28a4333
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/353160
Auto-Submit: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/nullability_suffix.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/nullability_suffix.dart
deleted file mode 100644
index 4f7fffa..0000000
--- a/pkg/_fe_analyzer_shared/lib/src/type_inference/nullability_suffix.dart
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Suffix indicating the nullability of a type.
-///
-/// This enum describes whether a `?` or `*` would be used at the end of the
-/// canonical representation of a type. It's subtly different the notions of
-/// "nullable", "non-nullable", "potentially nullable", and "potentially
-/// non-nullable" defined by the spec. For example, the type `Null` is
-/// nullable, even though it lacks a trailing `?`.
-///
-/// This enum is exposed through the analyzer API, so it should not be modified
-/// without considering the impact on analyzer clients.
-enum NullabilitySuffix {
- /// An indication that the canonical representation of the type under
- /// consideration ends with `?`. Types having this nullability suffix should
- /// be interpreted as being unioned with the Null type.
- question,
-
- /// An indication that the canonical representation of the type under
- /// consideration ends with `*`. Types having this nullability suffix are
- /// called "legacy types"; it has not yet been determined whether they should
- /// be unioned with the Null type.
- star,
-
- /// An indication that the canonical representation of the type under
- /// consideration does not end with either `?` or `*`.
- none
-}
diff --git a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer_operations.dart b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer_operations.dart
index adb22c5..646a9c9 100644
--- a/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer_operations.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/type_inference/type_analyzer_operations.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import '../flow_analysis/flow_analysis_operations.dart';
-import 'nullability_suffix.dart';
class RecordType<Type extends Object> {
final List<Type> positional;
@@ -15,23 +14,6 @@
});
}
-/// Describes all possibility for a type to be derived from a declaration.
-///
-/// This enum is intended to exhaustively handle all possibilities for a type to
-/// be derived from a type declaration. Currently, there are two such kinds of
-/// declarations: declarations inducing interfaces for dynamic dispatch (such as
-/// classes, mixins, and enums), and extension types.
-enum TypeDeclarationKind {
- /// Indication that the type is derived from a declaration inducing interface.
- ///
- /// An example of such declaration can be a class declaration, a mixin
- /// declaration, or an enum declaration.
- interfaceDeclaration,
-
- /// Indication that the type is derived from an extension type declaration.
- extensionTypeDeclaration,
-}
-
/// Callback API used by the shared type analyzer to query and manipulate the
/// client's representation of variables and types.
abstract interface class TypeAnalyzerOperations<Variable extends Object,
@@ -52,15 +34,9 @@
/// Returns the type `Never`.
Type get neverType;
- /// Returns the type `Null`.
- Type get nullType;
-
/// Returns the type `Object?`.
Type get objectQuestionType;
- /// Returns the type `Object`.
- Type get objectType;
-
/// Returns the unknown type schema (`_`) used in type inference.
TypeSchema get unknownType;
@@ -70,29 +46,6 @@
/// If [type] is a record type, returns it.
RecordType<Type>? asRecordType(Type type);
- /// Returns the nullability modifier of [type].
- NullabilitySuffix getNullabilitySuffix(Type type);
-
- /// If [type] was introduced by a class, mixin, enum, or extension type,
- /// returns a [TypeDeclarationKind] indicating what kind of thing it was
- /// introduced by. Otherwise, returns `null`.
- ///
- /// Examples of types derived from a class declarations are `A`, `A?`, `A*`,
- /// `B<T, S>`, where `A` and `B` are the names of class declarations or
- /// extension type declarations, `T` and `S` are types.
- TypeDeclarationKind? getTypeDeclarationKind(Type type);
-
- /// If at top level [typeSchema] describes a type that was introduced by a
- /// class, mixin, enum, or extension type, returns a [TypeDeclarationKind]
- /// indicating what kind of thing it was introduced by. Otherwise, returns
- /// `null`.
- ///
- /// Examples of type schemas at top level describing types derived from a
- /// declaration are `A`, `A?`, `A*`, `B<T, S>`, `B<_, B<_, _>>?`, where `A`
- /// and `B` are class declarations or extension type declarations, `T` and
- /// `S` are type schemas.
- TypeDeclarationKind? getTypeSchemaDeclarationKind(TypeSchema typeSchema);
-
/// Computes the greatest lower bound of [type1] and [type2].
Type glb(Type type1, Type type2);
@@ -111,45 +64,14 @@
bool isTypeSchemaSatisfied(
{required TypeSchema typeSchema, required Type type});
- /// Returns `true` if [type] is `F`, `F?`, or `F*` for some function type `F`.
- bool isFunctionType(Type type);
-
- /// If [type] takes the form `FutureOr<T>`, `FutureOr<T>?`, or `FutureOr<T>*`
- /// for some `T`, returns the type `T`. Otherwise returns `null`.
- Type? matchFutureOr(Type type);
-
- /// Returns `true` if [type] is `E<T1, ..., Tn>`, `E<T1, ..., Tn>?`, or
- /// `E<T1, ..., Tn>*` for some extension type declaration E, some
- /// non-negative n, and some types T1, ..., Tn.
- bool isExtensionType(Type type);
-
- /// Returns `true` if [type] is `A<T1, ..., Tn>`, `A<T1, ..., Tn>?`, or
- /// `A<T1, ..., Tn>*` for some class, mixin, or enum A, some non-negative n,
- /// and some types T1, ..., Tn. The method returns `false` if [type] is an
- /// extension type, a type alias, `Null`, `Never`, or `FutureOr<X>` for any
- /// type `X`.
- bool isInterfaceType(Type type);
-
- /// Returns `true` if [type] is `Null`.
- bool isNull(Type Type);
-
- /// Returns `true` if [type] is `Object` from `dart:core`. The method returns
- /// `false` for `Object?` and `Object*`.
- bool isObject(Type type);
-
- /// Returns `true` if [type] is `R`, `R?`, or `R*` for some record type `R`.
- bool isRecordType(Type type);
-
- /// Returns `true` if [typeSchema] is the unknown type schema (`_`).
- bool isUnknownType(TypeSchema typeSchema);
+ /// Returns `true` if [type] is the unknown type context (`_`).
+ bool isUnknownType(Type type);
/// Returns whether [node] is final.
bool isVariableFinal(Variable node);
- /// Returns `true` if [type] is the type `void`.
- bool isVoid(Type type);
-
- /// Returns the type schema `Iterable`, with type argument.
+ /// Returns the type schema `Iterable`, with type argument
+ /// [elementTypeSchema].
TypeSchema iterableTypeSchema(TypeSchema elementTypeSchema);
/// Returns the type `List`, with type argument [elementType].
@@ -225,7 +147,4 @@
/// Converts a type into a corresponding type schema.
TypeSchema typeToSchema(Type type);
-
- /// Returns [type] suffixed with the [suffix].
- Type withNullabilitySuffix(Type type, NullabilitySuffix suffix);
}
diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart
index ec34a04..9a5c2a3 100644
--- a/pkg/_fe_analyzer_shared/test/mini_ast.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart
@@ -19,7 +19,6 @@
ThisPropertyTarget;
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis_operations.dart';
import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
-import 'package:_fe_analyzer_shared/src/type_inference/nullability_suffix.dart';
import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart'
as shared;
import 'package:_fe_analyzer_shared/src/type_inference/type_analysis_result.dart';
@@ -2679,9 +2678,6 @@
late final Type objectQuestionType = Type('Object?');
@override
- late final Type objectType = Type('Object');
-
- @override
late final TypeSchema unknownType = TypeSchema('_');
@override
@@ -2691,9 +2687,6 @@
late final Type neverType = Type('Never');
@override
- late final Type nullType = Type('Null');
-
- @override
late final Type doubleType = Type('double');
@override
@@ -2821,33 +2814,6 @@
}
@override
- NullabilitySuffix getNullabilitySuffix(Type type) {
- if (type is QuestionType) {
- return NullabilitySuffix.question;
- } else if (type is StarType) {
- return NullabilitySuffix.star;
- } else {
- return NullabilitySuffix.none;
- }
- }
-
- @override
- TypeDeclarationKind? getTypeDeclarationKind(Type type) {
- if (isInterfaceType(type)) {
- return TypeDeclarationKind.interfaceDeclaration;
- } else if (isExtensionType(type)) {
- return TypeDeclarationKind.extensionTypeDeclaration;
- } else {
- return null;
- }
- }
-
- @override
- TypeDeclarationKind? getTypeSchemaDeclarationKind(TypeSchema typeSchema) {
- return getTypeDeclarationKind(typeSchema.toType());
- }
-
- @override
Type glb(Type type1, Type type2) {
if (type1.type == type2.type) return type1;
var typeNames = [type1.type, type2.type];
@@ -2876,63 +2842,19 @@
type is PrimaryType && type.name == 'dynamic' && type.args.isEmpty;
@override
- bool isFunctionType(Type type) {
- return withNullabilitySuffix(type, NullabilitySuffix.none) is FunctionType;
- }
-
- @override
- Type? matchFutureOr(Type type) {
- Type underlyingType = withNullabilitySuffix(type, NullabilitySuffix.none);
- if (underlyingType is PrimaryType && underlyingType.args.length == 1) {
- if (underlyingType.name == 'FutureOr') {
- return underlyingType.args[0];
- }
- }
- return null;
- }
-
- @override
bool isError(Type type) =>
type is PrimaryType && type.name == 'error' && type.args.isEmpty;
@override
- bool isExtensionType(Type type) {
- // TODO(cstefantsova): Add the support for extension types in the mini ast
- // testing framework.
- return false;
- }
-
- @override
- bool isInterfaceType(Type type) {
- Type underlyingType = withNullabilitySuffix(type, NullabilitySuffix.none);
- return underlyingType is PrimaryType && underlyingType.isInterfaceType;
- }
-
- @override
bool isNever(Type type) {
return type.type == 'Never';
}
@override
- bool isNull(Type type) {
- return type.type == 'Null';
- }
-
- @override
- bool isObject(Type type) {
- return type is PrimaryType && type.name == 'Object' && type.args.isEmpty;
- }
-
- @override
bool isPropertyPromotable(covariant _PropertyElement property) =>
property.isPromotable;
@override
- bool isRecordType(Type type) {
- return withNullabilitySuffix(type, NullabilitySuffix.none) is RecordType;
- }
-
- @override
bool isSameType(Type type1, Type type2) {
return type1.type == type2.type;
}
@@ -2951,7 +2873,7 @@
isSubtypeOf(type, typeSchema.toType());
@override
- bool isUnknownType(TypeSchema typeSchema) => typeSchema is UnknownType;
+ bool isUnknownType(Type type) => type is UnknownType;
@override
bool isVariableFinal(Var node) {
@@ -2959,10 +2881,6 @@
}
@override
- bool isVoid(Type type) =>
- type is PrimaryType && type.name == 'void' && type.args.isEmpty;
-
- @override
TypeSchema iterableTypeSchema(TypeSchema elementTypeSchema) {
return TypeSchema.fromType(
PrimaryType('Iterable', args: [elementTypeSchema.toType()]));
@@ -3150,36 +3068,6 @@
PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
covariant _PropertyElement property) =>
property.whyNotPromotable;
-
- @override
- Type withNullabilitySuffix(Type type, NullabilitySuffix modifier) {
- switch (modifier) {
- case NullabilitySuffix.none:
- if (type is QuestionType) {
- return type.innerType;
- } else if (type is StarType) {
- return type.innerType;
- } else {
- return type;
- }
- case NullabilitySuffix.question:
- if (type is QuestionType) {
- return type;
- } else if (type is StarType) {
- return QuestionType(type.innerType);
- } else {
- return QuestionType(type);
- }
- case NullabilitySuffix.star:
- if (type is QuestionType) {
- return StarType(type.innerType);
- } else if (type is StarType) {
- return type;
- } else {
- return StarType(type);
- }
- }
- }
}
/// Representation of an expression or statement in the pseudo-Dart language
diff --git a/pkg/_fe_analyzer_shared/test/mini_types.dart b/pkg/_fe_analyzer_shared/test/mini_types.dart
index 1bafd10..8800c75 100644
--- a/pkg/_fe_analyzer_shared/test/mini_types.dart
+++ b/pkg/_fe_analyzer_shared/test/mini_types.dart
@@ -60,14 +60,6 @@
/// reference to a type parameter, or one of the special types whose name is a
/// single word (e.g. `dynamic`).
class PrimaryType extends Type {
- /// Names of primary types not originating from a class, a mixin, or an enum.
- static const List<String> namedNonInterfaceTypes = [
- 'FutureOr',
- 'Never',
- 'Null',
- 'dynamic',
- ];
-
/// The name of the type.
final String name;
@@ -76,8 +68,6 @@
PrimaryType(this.name, {this.args = const []}) : super._();
- bool get isInterfaceType => !namedNonInterfaceTypes.contains(name);
-
@override
Type? recursivelyDemote({required bool covariant}) {
List<Type>? newArgs = args.recursivelyDemote(covariant: covariant);
diff --git a/pkg/analyzer/lib/dart/element/nullability_suffix.dart b/pkg/analyzer/lib/dart/element/nullability_suffix.dart
index ac63891..59a7759 100644
--- a/pkg/analyzer/lib/dart/element/nullability_suffix.dart
+++ b/pkg/analyzer/lib/dart/element/nullability_suffix.dart
@@ -1,6 +1,27 @@
-// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-export 'package:_fe_analyzer_shared/src/type_inference/nullability_suffix.dart'
- show NullabilitySuffix;
+/// Suffix indicating the nullability of a type.
+///
+/// This enum describes whether a `?` or `*` would be used at the end of the
+/// canonical representation of a type. It's subtly different the notions of
+/// "nullable", "non-nullable", "potentially nullable", and "potentially
+/// non-nullable" defined by the spec. For example, the type `Null` is
+/// nullable, even though it lacks a trailing `?`.
+enum NullabilitySuffix {
+ /// An indication that the canonical representation of the type under
+ /// consideration ends with `?`. Types having this nullability suffix should
+ /// be interpreted as being unioned with the Null type.
+ question,
+
+ /// An indication that the canonical representation of the type under
+ /// consideration ends with `*`. Types having this nullability suffix are
+ /// called "legacy types"; it has not yet been determined whether they should
+ /// be unioned with the Null type.
+ star,
+
+ /// An indication that the canonical representation of the type under
+ /// consideration does not end with either `?` or `*`.
+ none
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index d3804b9..4f4756c 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -2,9 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'
- show TypeDeclarationKind;
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
@@ -103,21 +102,21 @@
// If `P` is a type variable `X` in `L`, then the match holds:
// Under constraint `_ <: X <: Q`.
- var P_nullability = _typeSystemOperations.getNullabilitySuffix(P);
- if (_typeSystemOperations.isTypeParameterType(P) &&
+ var P_nullability = P.nullabilitySuffix;
+ if (P is TypeParameterType &&
P_nullability == NullabilitySuffix.none &&
_typeParameters.contains(P.element)) {
- _addUpper(P.element as TypeParameterElement, Q);
+ _addUpper(P.element, Q);
return true;
}
// If `Q` is a type variable `X` in `L`, then the match holds:
// Under constraint `P <: X <: _`.
- var Q_nullability = _typeSystemOperations.getNullabilitySuffix(Q);
- if (_typeSystemOperations.isTypeParameterType(Q) &&
+ var Q_nullability = Q.nullabilitySuffix;
+ if (Q is TypeParameterType &&
Q_nullability == NullabilitySuffix.none &&
_typeParameters.contains(Q.element)) {
- _addLower(Q.element as TypeParameterElement, P);
+ _addLower(Q.element, P);
return true;
}
@@ -140,8 +139,8 @@
if (Q_nullability == NullabilitySuffix.star) {
// If `P` is `dynamic` or `void` and `P` is a subtype match
// for `Q0` under constraint set `C`.
- if (_typeSystemOperations.isDynamic(P) ||
- _typeSystemOperations.isVoid(P)) {
+ if (identical(P, DynamicTypeImpl.instance) ||
+ identical(P, VoidTypeImpl.instance)) {
var rewind = _constraints.length;
var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
if (trySubtypeMatch(P, Q0, leftSchema)) {
@@ -155,14 +154,18 @@
}
// If `Q` is `FutureOr<Q0>` the match holds under constraint set `C`:
- if (_typeSystemOperations.matchFutureOr(Q) case var Q0?
- when Q_nullability == NullabilitySuffix.none) {
+ if (Q_nullability == NullabilitySuffix.none &&
+ Q is InterfaceType &&
+ Q.isDartAsyncFutureOr) {
+ var Q0 = Q.typeArguments[0];
var rewind = _constraints.length;
// If `P` is `FutureOr<P0>` and `P0` is a subtype match for `Q0` under
// constraint set `C`.
- if (_typeSystemOperations.matchFutureOr(P) case var P0?
- when P_nullability == NullabilitySuffix.none) {
+ if (P_nullability == NullabilitySuffix.none &&
+ P is InterfaceType &&
+ P.isDartAsyncFutureOr) {
+ var P0 = P.typeArguments[0];
if (trySubtypeMatch(P0, Q0, leftSchema)) {
return true;
}
@@ -193,15 +196,13 @@
// If `Q` is `Q0?` the match holds under constraint set `C`:
if (Q_nullability == NullabilitySuffix.question) {
- var Q0 = _typeSystemOperations.withNullabilitySuffix(
- Q, NullabilitySuffix.none);
+ var Q0 = (Q as TypeImpl).withNullability(NullabilitySuffix.none);
var rewind = _constraints.length;
// If `P` is `P0?` and `P0` is a subtype match for `Q0` under
// constraint set `C`.
if (P_nullability == NullabilitySuffix.question) {
- var P0 = _typeSystemOperations.withNullabilitySuffix(
- P, NullabilitySuffix.none);
+ var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
if (trySubtypeMatch(P0, Q0, leftSchema)) {
return true;
}
@@ -210,8 +211,8 @@
// Or if `P` is `dynamic` or `void` and `Object` is a subtype match
// for `Q0` under constraint set `C`.
- if (_typeSystemOperations.isDynamic(P) ||
- _typeSystemOperations.isVoid(P)) {
+ if (identical(P, DynamicTypeImpl.instance) ||
+ identical(P, VoidTypeImpl.instance)) {
if (trySubtypeMatch(_typeSystem.objectNone, Q0, leftSchema)) {
return true;
}
@@ -240,8 +241,10 @@
}
// If `P` is `FutureOr<P0>` the match holds under constraint set `C1 + C2`:
- if (_typeSystemOperations.matchFutureOr(P) case var P0?
- when P_nullability == NullabilitySuffix.none) {
+ if (P_nullability == NullabilitySuffix.none &&
+ P is InterfaceType &&
+ P.isDartAsyncFutureOr) {
+ var P0 = P.typeArguments[0];
var rewind = _constraints.length;
// If `Future<P0>` is a subtype match for `Q` under constraint set `C1`.
@@ -257,8 +260,7 @@
// If `P` is `P0?` the match holds under constraint set `C1 + C2`:
if (P_nullability == NullabilitySuffix.question) {
- var P0 = _typeSystemOperations.withNullabilitySuffix(
- P, NullabilitySuffix.none);
+ var P0 = (P as TypeImpl).withNullability(NullabilitySuffix.none);
var rewind = _constraints.length;
// If `P0` is a subtype match for `Q` under constraint set `C1`.
@@ -273,27 +275,26 @@
// If `Q` is `dynamic`, `Object?`, or `void` then the match holds under
// no constraints.
- if (_typeSystemOperations.isDynamic(Q) ||
- _typeSystemOperations.isVoid(Q) ||
- Q == _typeSystemOperations.objectQuestionType) {
+ if (identical(Q, DynamicTypeImpl.instance) ||
+ identical(Q, VoidTypeImpl.instance) ||
+ Q_nullability == NullabilitySuffix.question && Q.isDartCoreObject) {
return true;
}
// If `P` is `Never` then the match holds under no constraints.
- if (_typeSystemOperations.isNever(P)) {
+ if (identical(P, NeverTypeImpl.instance)) {
return true;
}
// If `Q` is `Object`, then the match holds under no constraints:
// Only if `P` is non-nullable.
- if (Q == _typeSystemOperations.objectType) {
+ if (Q_nullability == NullabilitySuffix.none && Q.isDartCoreObject) {
return _typeSystem.isNonNullable(P);
}
// If `P` is `Null`, then the match holds under no constraints:
// Only if `Q` is nullable.
- if (P_nullability == NullabilitySuffix.none &&
- _typeSystemOperations.isNull(P)) {
+ if (P_nullability == NullabilitySuffix.none && P.isDartCoreNull) {
return _typeSystem.isNullable(Q);
}
@@ -310,70 +311,33 @@
_constraints.length = rewind;
}
- TypeDeclarationKind? P_typeDeclarationKind =
- _typeSystemOperations.getTypeDeclarationKind(P);
- TypeDeclarationKind? Q_typeDeclarationKind =
- _typeSystemOperations.getTypeDeclarationKind(Q);
- if (P_typeDeclarationKind == TypeDeclarationKind.interfaceDeclaration &&
- Q_typeDeclarationKind == TypeDeclarationKind.interfaceDeclaration) {
- // If `P` is `C<M0, ..., Mk> and `Q` is `C<N0, ..., Nk>`, then the match
- // holds under constraints `C0 + ... + Ck`:
- // If `Mi` is a subtype match for `Ni` with respect to L under
- // constraints `Ci`.
- if (P.element == Q.element) {
- if (!_interfaceType_arguments(
- P as InterfaceType, Q as InterfaceType, leftSchema)) {
- return false;
- }
- return true;
- }
- return _interfaceType(P as InterfaceType, Q as InterfaceType, leftSchema);
- } else if (P_typeDeclarationKind ==
- TypeDeclarationKind.extensionTypeDeclaration &&
- Q_typeDeclarationKind == TypeDeclarationKind.extensionTypeDeclaration) {
- // If `P` is `C<M0, ..., Mk> and `Q` is `C<N0, ..., Nk>`, then the match
- // holds under constraints `C0 + ... + Ck`:
- // If `Mi` is a subtype match for `Ni` with respect to L under
- // constraints `Ci`.
- if (P.element == Q.element) {
- if (!_interfaceType_arguments(
- P as InterfaceType, Q as InterfaceType, leftSchema)) {
- return false;
- }
- return true;
- }
- return _interfaceType(P as InterfaceType, Q as InterfaceType, leftSchema);
- }
-
- if (P_typeDeclarationKind != null && Q_typeDeclarationKind != null) {
- return _interfaceType(P as InterfaceType, Q as InterfaceType, leftSchema);
+ if (P is InterfaceType && Q is InterfaceType) {
+ return _interfaceType(P, Q, leftSchema);
}
// If `Q` is `Function` then the match holds under no constraints:
// If `P` is a function type.
if (Q_nullability == NullabilitySuffix.none && Q.isDartCoreFunction) {
- if (_typeSystemOperations.isFunctionType(P)) {
+ if (P is FunctionType) {
return true;
}
}
- if (_typeSystemOperations.isFunctionType(P) &&
- _typeSystemOperations.isFunctionType(Q)) {
- return _functionType(P as FunctionType, Q as FunctionType, leftSchema);
+ if (P is FunctionType && Q is FunctionType) {
+ return _functionType(P, Q, leftSchema);
}
// A type `P` is a subtype match for `Record` with respect to `L` under no
// constraints:
// If `P` is a record type or `Record`.
if (Q_nullability == NullabilitySuffix.none && Q.isDartCoreRecord) {
- if (_typeSystemOperations.isRecordType(P)) {
+ if (P is RecordType) {
return true;
}
}
- if (_typeSystemOperations.isRecordType(P) &&
- _typeSystemOperations.isRecordType(Q)) {
- return _recordType(P as RecordTypeImpl, Q as RecordTypeImpl, leftSchema);
+ if (P is RecordTypeImpl && Q is RecordTypeImpl) {
+ return _recordType(P, Q, leftSchema);
}
return false;
@@ -584,6 +548,17 @@
return false;
}
+ // If `P` is `C<M0, ..., Mk> and `Q` is `C<N0, ..., Nk>`, then the match
+ // holds under constraints `C0 + ... + Ck`:
+ // If `Mi` is a subtype match for `Ni` with respect to L under
+ // constraints `Ci`.
+ if (P.element == Q.element) {
+ if (!_interfaceType_arguments(P, Q, leftSchema)) {
+ return false;
+ }
+ return true;
+ }
+
// If `P` is `C0<M0, ..., Mk>` and `Q` is `C1<N0, ..., Nj>` then the match
// holds with respect to `L` under constraints `C`:
// If `C1<B0, ..., Bj>` is a superinterface of `C0<M0, ..., Mk>` and
diff --git a/pkg/analyzer/lib/src/dart/element/type_system.dart b/pkg/analyzer/lib/src/dart/element/type_system.dart
index 2177237..446665f 100644
--- a/pkg/analyzer/lib/src/dart/element/type_system.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_system.dart
@@ -7,6 +7,7 @@
import 'package:analyzer/dart/ast/ast.dart' show AstNode;
import 'package:analyzer/dart/ast/token.dart' show TokenType;
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/dart/element/type_system.dart';
diff --git a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
index fdf2054..a4ed4af 100644
--- a/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/flow_analysis_visitor.dart
@@ -23,9 +23,6 @@
import 'package:analyzer/src/dart/element/type_system.dart' show TypeSystemImpl;
import 'package:analyzer/src/generated/variable_type_provider.dart';
-export 'package:_fe_analyzer_shared/src/type_inference/nullability_suffix.dart'
- show NullabilitySuffix;
-
/// Data gathered by flow analysis, retained for testing purposes.
class FlowAnalysisDataForTesting {
/// The list of nodes, [Expression]s or [Statement]s, that cannot be reached,
@@ -404,15 +401,9 @@
DartType get neverType => typeSystem.typeProvider.neverType;
@override
- DartType get nullType => typeSystem.typeProvider.nullType;
-
- @override
DartType get objectQuestionType => typeSystem.objectQuestion;
@override
- DartType get objectType => typeSystem.objectNone;
-
- @override
DartType get unknownType => UnknownInferredType.instance;
@override
@@ -454,27 +445,6 @@
}
@override
- NullabilitySuffix getNullabilitySuffix(DartType type) {
- return type.nullabilitySuffix;
- }
-
- @override
- TypeDeclarationKind? getTypeDeclarationKind(DartType type) {
- if (isInterfaceType(type)) {
- return TypeDeclarationKind.interfaceDeclaration;
- } else if (isExtensionType(type)) {
- return TypeDeclarationKind.extensionTypeDeclaration;
- } else {
- return null;
- }
- }
-
- @override
- TypeDeclarationKind? getTypeSchemaDeclarationKind(DartType typeSchema) {
- return getTypeDeclarationKind(typeSchema);
- }
-
- @override
DartType glb(DartType type1, DartType type2) {
return typeSystem.greatestLowerBound(type1, type2);
}
@@ -497,40 +467,11 @@
bool isError(DartType type) => type is InvalidType;
@override
- bool isExtensionType(DartType type) {
- return type is InterfaceType && type.element is ExtensionTypeElement;
- }
-
- @override
- bool isFunctionType(DartType type) {
- return type is FunctionType;
- }
-
- @override
- bool isInterfaceType(DartType type) {
- return type is InterfaceType &&
- !type.isDartCoreNull &&
- !type.isDartAsyncFutureOr &&
- type.element is! ExtensionTypeElement;
- }
-
- @override
bool isNever(DartType type) {
return typeSystem.isBottom(type);
}
@override
- bool isNull(DartType type) {
- return type.isDartCoreNull;
- }
-
- @override
- bool isObject(DartType type) {
- return type.isDartCoreObject &&
- type.nullabilitySuffix == NullabilitySuffix.none;
- }
-
- @override
bool isPropertyPromotable(Object property) {
if (property is! PropertyAccessorElement) return false;
var field = property.variable;
@@ -539,9 +480,6 @@
}
@override
- bool isRecordType(DartType type) => type is RecordType;
-
- @override
bool isSameType(covariant TypeImpl type1, covariant TypeImpl type2) {
return type1 == type2;
}
@@ -560,8 +498,8 @@
isSubtypeOf(type, typeSchema);
@override
- bool isUnknownType(DartType typeSchema) {
- return identical(typeSchema, UnknownInferredType.instance);
+ bool isUnknownType(DartType type) {
+ return identical(type, UnknownInferredType.instance);
}
@override
@@ -570,11 +508,6 @@
}
@override
- bool isVoid(DartType type) {
- return identical(type, VoidTypeImpl.instance);
- }
-
- @override
DartType iterableTypeSchema(DartType elementTypeSchema) {
return typeSystem.typeProvider.iterableType(elementTypeSchema);
}
@@ -621,15 +554,6 @@
}
@override
- DartType? matchFutureOr(DartType type) {
- if (type is InterfaceType && type.isDartAsyncFutureOr) {
- return type.typeArguments[0];
- } else {
- return null;
- }
- }
-
- @override
DartType? matchIterableType(DartType type) {
var iterableElement = typeSystem.typeProvider.iterableElement;
var listType = type.asInstanceOf(iterableElement);
@@ -751,11 +675,6 @@
// declaration, or because field promotion is disabled.
return null;
}
-
- @override
- DartType withNullabilitySuffix(DartType type, NullabilitySuffix suffix) {
- return (type as TypeImpl).withNullability(suffix);
- }
}
/// The visitor that gathers local variables that are potentially assigned
diff --git a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
index 305b8f3..90fe457 100644
--- a/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/named_type_resolver.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
diff --git a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
index 82f3b50..e1de80e 100644
--- a/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/resolution_visitor.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
diff --git a/pkg/analyzer/lib/src/error/dead_code_verifier.dart b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
index 8098e90..b9ae8164 100644
--- a/pkg/analyzer/lib/src/error/dead_code_verifier.dart
+++ b/pkg/analyzer/lib/src/error/dead_code_verifier.dart
@@ -6,6 +6,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 0cda82f..3e6c9e1 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 2d6f924..caea4d8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -20,6 +20,7 @@
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/scope.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart';
diff --git a/pkg/analyzer/lib/src/summary2/types_builder.dart b/pkg/analyzer/lib/src/summary2/types_builder.dart
index 1497a40..1599bac 100644
--- a/pkg/analyzer/lib/src/summary2/types_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/types_builder.dart
@@ -4,6 +4,7 @@
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index 50451e8..8259e27 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -2,12 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-import 'package:_fe_analyzer_shared/src/type_inference/nullability_suffix.dart'
- show NullabilitySuffix;
-
-import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'
- show TypeDeclarationKind;
-
import 'package:kernel/ast.dart';
import 'package:kernel/type_algebra.dart';
@@ -260,6 +254,14 @@
return true;
}
+ bool _isNull(DartType type) {
+ // TODO(paulberry): would it be better to call this "_isBottom", and to have
+ // it return `true` for both Null and bottom types? Revisit this once
+ // enough functionality is implemented that we can compare the behavior with
+ // the old analyzer-based implementation.
+ return type is NullType;
+ }
+
/// Whether the [subtype] interface is a subtype of the [supertype] interface
/// with respect to variance.
///
@@ -473,9 +475,12 @@
// If P is a legacy type P0* then the match holds under constraint set C:
//
// Only if P0 is a subtype match for Q under constraint set C.
- if (_typeOperations.getNullabilitySuffix(p) == NullabilitySuffix.star) {
+ if (isLegacyTypeConstructorApplication(p,
+ isNonNullableByDefault: _isNonNullableByDefault)) {
return _isNullabilityAwareSubtypeMatch(
- _typeOperations.withNullabilitySuffix(p, NullabilitySuffix.none), q,
+ computeTypeWithoutNullabilityMarker(p,
+ isNonNullableByDefault: _isNonNullableByDefault),
+ q,
constrainSupertype: constrainSupertype);
}
@@ -485,23 +490,24 @@
// set C.
// Or if P is not dynamic or void and P is a subtype match for Q0? under
// constraint set C.
- if (_typeOperations.getNullabilitySuffix(q) == NullabilitySuffix.star) {
+ if (isLegacyTypeConstructorApplication(q,
+ isNonNullableByDefault: _isNonNullableByDefault)) {
final int baseConstraintCount = _protoConstraints.length;
- if ((_typeOperations.isDynamic(p) || _typeOperations.isVoid(p)) &&
- _isNullabilityAwareSubtypeMatch(p,
- _typeOperations.withNullabilitySuffix(q, NullabilitySuffix.none),
+ if ((p is DynamicType || p is VoidType) &&
+ _isNullabilityAwareSubtypeMatch(
+ p,
+ computeTypeWithoutNullabilityMarker(q,
+ isNonNullableByDefault: _isNonNullableByDefault),
constrainSupertype: constrainSupertype)) {
return true;
}
_protoConstraints.length = baseConstraintCount;
- if (!_typeOperations.isDynamic(p) &&
- !_typeOperations.isVoid(p) &&
+ if (p is! DynamicType &&
+ p is! VoidType &&
_isNullabilityAwareSubtypeMatch(
- p,
- _typeOperations.withNullabilitySuffix(
- q, NullabilitySuffix.question),
+ p, q.withDeclaredNullability(Nullability.nullable),
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -515,21 +521,18 @@
// constraint set C. Or if P is a subtype match for Q0 under constraint set
// C. Or if P is a subtype match for Future<Q0> under empty constraint set
// C.
- if (_typeOperations.matchFutureOr(q) != null) {
+ if (q is FutureOrType) {
final int baseConstraintCount = _protoConstraints.length;
if (p is FutureOrType &&
- _isNullabilityAwareSubtypeMatch(
- p.typeArgument, (q as FutureOrType).typeArgument,
+ _isNullabilityAwareSubtypeMatch(p.typeArgument, q.typeArgument,
constrainSupertype: constrainSupertype)) {
return true;
}
_protoConstraints.length = baseConstraintCount;
bool isMatchWithFuture = _isNullabilityAwareSubtypeMatch(
- p,
- _environment.futureType(
- (q as FutureOrType).typeArgument, Nullability.nonNullable),
+ p, _environment.futureType(q.typeArgument, Nullability.nonNullable),
constrainSupertype: constrainSupertype);
bool matchWithFutureAddsConstraints =
_protoConstraints.length != baseConstraintCount;
@@ -558,23 +561,23 @@
// Or if P is a subtype match for Q0 under non-empty constraint set C.
// Or if P is a subtype match for Null under constraint set C.
// Or if P is a subtype match for Q0 under empty constraint set C.
- if (_typeOperations.getNullabilitySuffix(q) == NullabilitySuffix.question) {
+ if (isNullableTypeConstructorApplication(q)) {
final int baseConstraintCount = _protoConstraints.length;
- final DartType rawP =
- _typeOperations.withNullabilitySuffix(p, NullabilitySuffix.none);
- final DartType rawQ =
- _typeOperations.withNullabilitySuffix(q, NullabilitySuffix.none);
+ final DartType rawP = computeTypeWithoutNullabilityMarker(p,
+ isNonNullableByDefault: _isNonNullableByDefault);
+ final DartType rawQ = computeTypeWithoutNullabilityMarker(q,
+ isNonNullableByDefault: _isNonNullableByDefault);
- if (_typeOperations.getNullabilitySuffix(p) ==
- NullabilitySuffix.question &&
+ if (isNullableTypeConstructorApplication(p) &&
_isNullabilityAwareSubtypeMatch(rawP, rawQ,
constrainSupertype: constrainSupertype)) {
return true;
}
_protoConstraints.length = baseConstraintCount;
- if ((_typeOperations.isDynamic(p) || _typeOperations.isVoid(p)) &&
- _isNullabilityAwareSubtypeMatch(_typeOperations.objectType, rawQ,
+ if ((p is DynamicType || p is VoidType) &&
+ _isNullabilityAwareSubtypeMatch(
+ _environment.coreTypes.objectNonNullableRawType, rawQ,
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -589,7 +592,7 @@
}
_protoConstraints.length = baseConstraintCount;
- if (_isNullabilityAwareSubtypeMatch(p, _typeOperations.nullType,
+ if (_isNullabilityAwareSubtypeMatch(p, const NullType(),
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -605,11 +608,10 @@
//
// If Future<P0> is a subtype match for Q under constraint set C1.
// And if P0 is a subtype match for Q under constraint set C2.
- if (_typeOperations.matchFutureOr(p) != null) {
+ if (p is FutureOrType) {
final int baseConstraintCount = _protoConstraints.length;
if (_isNullabilityAwareSubtypeMatch(
- _environment.futureType(
- (p as FutureOrType).typeArgument, Nullability.nonNullable),
+ _environment.futureType(p.typeArgument, Nullability.nonNullable),
q,
constrainSupertype: constrainSupertype) &&
_isNullabilityAwareSubtypeMatch(p.typeArgument, q,
@@ -626,10 +628,11 @@
if (isNullableTypeConstructorApplication(p)) {
final int baseConstraintCount = _protoConstraints.length;
if (_isNullabilityAwareSubtypeMatch(
- _typeOperations.withNullabilitySuffix(p, NullabilitySuffix.none),
+ computeTypeWithoutNullabilityMarker(p,
+ isNonNullableByDefault: _isNonNullableByDefault),
q,
constrainSupertype: constrainSupertype) &&
- _isNullabilityAwareSubtypeMatch(_typeOperations.nullType, q,
+ _isNullabilityAwareSubtypeMatch(const NullType(), q,
constrainSupertype: constrainSupertype)) {
return true;
}
@@ -638,29 +641,28 @@
// If Q is dynamic, Object?, or void then the match holds under no
// constraints.
- if (_typeOperations.isDynamic(q) ||
- _typeOperations.isVoid(q) ||
- q == _typeOperations.objectQuestionType) {
+ if (q is DynamicType ||
+ q is VoidType ||
+ q == _environment.coreTypes.objectNullableRawType) {
return true;
}
// If P is Never then the match holds under no constraints.
- if (_typeOperations.isNever(p) &&
- _typeOperations.getNullabilitySuffix(p) == NullabilitySuffix.none) {
+ if (p is NeverType && p.declaredNullability == Nullability.nonNullable) {
return true;
}
// If Q is Object, then the match holds under no constraints:
//
// Only if P is non-nullable.
- if (q == _typeOperations.objectType) {
- return _typeOperations.getNullabilitySuffix(p) == NullabilitySuffix.none;
+ if (q == _environment.coreTypes.objectNonNullableRawType) {
+ return p.nullability == Nullability.nonNullable;
}
// If P is Null, then the match holds under no constraints:
//
// Only if Q is nullable.
- if (_typeOperations.isNull(p)) {
+ if (p is NullType) {
return q.nullability == Nullability.nullable;
}
@@ -689,42 +691,34 @@
// under constraints C0 + ... + Ck:
//
// If Mi is a subtype match for Ni with respect to L under constraints Ci.
- TypeDeclarationKind? pTypeDeclarationKind =
- _typeOperations.getTypeDeclarationKind(p);
- TypeDeclarationKind? qTypeDeclarationKind =
- _typeOperations.getTypeDeclarationKind(q);
- if (pTypeDeclarationKind == TypeDeclarationKind.interfaceDeclaration &&
- qTypeDeclarationKind == TypeDeclarationKind.interfaceDeclaration) {
- if ((p as InterfaceType).classNode == (q as InterfaceType).classNode) {
- assert(p.typeArguments.length == q.typeArguments.length);
+ if (p is InterfaceType &&
+ q is InterfaceType &&
+ p.classNode == q.classNode) {
+ assert(p.typeArguments.length == q.typeArguments.length);
- final int baseConstraintCount = _protoConstraints.length;
- bool isMatch = true;
- for (int i = 0; isMatch && i < p.typeArguments.length; ++i) {
- isMatch = _isNullabilityAwareInterfaceSubtypeMatch(p, q,
- constrainSupertype: constrainSupertype);
- }
- if (isMatch) return true;
- _protoConstraints.length = baseConstraintCount;
+ final int baseConstraintCount = _protoConstraints.length;
+ bool isMatch = true;
+ for (int i = 0; isMatch && i < p.typeArguments.length; ++i) {
+ isMatch = _isNullabilityAwareInterfaceSubtypeMatch(p, q,
+ constrainSupertype: constrainSupertype);
}
- } else if (pTypeDeclarationKind ==
- TypeDeclarationKind.extensionTypeDeclaration &&
- qTypeDeclarationKind == TypeDeclarationKind.extensionTypeDeclaration) {
- if ((p as ExtensionType).extensionTypeDeclaration ==
- (q as ExtensionType).extensionTypeDeclaration) {
- assert(p.typeArguments.length == q.typeArguments.length);
+ if (isMatch) return true;
+ _protoConstraints.length = baseConstraintCount;
+ } else if (p is ExtensionType &&
+ q is ExtensionType &&
+ p.extensionTypeDeclaration == q.extensionTypeDeclaration) {
+ assert(p.typeArguments.length == q.typeArguments.length);
- final int baseConstraintCount = _protoConstraints.length;
- bool isMatch = true;
- for (int i = 0; isMatch && i < p.typeArguments.length; ++i) {
- isMatch = isMatch &&
- _isNullabilityAwareSubtypeMatch(
- p.typeArguments[i], q.typeArguments[i],
- constrainSupertype: constrainSupertype);
- }
- if (isMatch) return true;
- _protoConstraints.length = baseConstraintCount;
+ final int baseConstraintCount = _protoConstraints.length;
+ bool isMatch = true;
+ for (int i = 0; isMatch && i < p.typeArguments.length; ++i) {
+ isMatch = isMatch &&
+ _isNullabilityAwareSubtypeMatch(
+ p.typeArguments[i], q.typeArguments[i],
+ constrainSupertype: constrainSupertype);
}
+ if (isMatch) return true;
+ _protoConstraints.length = baseConstraintCount;
}
// If P is C0<M0, ..., Mk> and Q is C1<N0, ..., Nj> then the match holds
@@ -733,9 +727,9 @@
// If C1<B0, ..., Bj> is a superinterface of C0<M0, ..., Mk> and C1<B0, ...,
// Bj> is a subtype match for C1<N0, ..., Nj> with respect to L under
// constraints C.
- if (pTypeDeclarationKind != null && qTypeDeclarationKind != null) {
- final List<DartType>? sArguments = getTypeArgumentsAsInstanceOf(
- p as TypeDeclarationType, (q as TypeDeclarationType).typeDeclaration);
+ if (p is TypeDeclarationType && q is TypeDeclarationType) {
+ final List<DartType>? sArguments =
+ getTypeArgumentsAsInstanceOf(p, q.typeDeclaration);
if (sArguments != null) {
assert(sArguments.length == q.typeArguments.length);
@@ -755,7 +749,7 @@
//
// If P is a function type.
if (q == _environment.coreTypes.functionNonNullableRawType &&
- _typeOperations.isFunctionType(p)) {
+ p is FunctionType) {
return true;
}
@@ -766,10 +760,10 @@
// If R0 is a subtype match for a type R1 with respect to L under
// constraints C. If n <= k and r <= m. And for i in 0...r, Ni is a
// subtype match for Mi with respect to L under constraints Ci.
- if (_typeOperations.isFunctionType(p) &&
- _typeOperations.isFunctionType(q) &&
- (p as FunctionType).typeParameters.isEmpty &&
- (q as FunctionType).typeParameters.isEmpty &&
+ if (p is FunctionType &&
+ q is FunctionType &&
+ p.typeParameters.isEmpty &&
+ q.typeParameters.isEmpty &&
p.namedParameters.isEmpty &&
q.namedParameters.isEmpty &&
p.requiredParameterCount <= q.requiredParameterCount &&
@@ -792,10 +786,10 @@
// Function types with named parameters are treated analogously to the
// positional parameter case above.
- if (_typeOperations.isFunctionType(p) &&
- _typeOperations.isFunctionType(q) &&
- (p as FunctionType).typeParameters.isEmpty &&
- (q as FunctionType).typeParameters.isEmpty &&
+ if (p is FunctionType &&
+ q is FunctionType &&
+ p.typeParameters.isEmpty &&
+ q.typeParameters.isEmpty &&
p.positionalParameters.length == p.requiredParameterCount &&
q.positionalParameters.length == q.requiredParameterCount &&
p.requiredParameterCount == q.requiredParameterCount &&
@@ -845,10 +839,10 @@
// with respect to L under constraints C0. And C1 is C02 + ... + Cn2 + C0.
// And C2 is C1 with each constraint replaced with its closure with respect
// to [Z0, ..., Zn].
- if (_typeOperations.isFunctionType(p) &&
- _typeOperations.isFunctionType(q) &&
- (p as FunctionType).typeParameters.isNotEmpty &&
- (q as FunctionType).typeParameters.isNotEmpty &&
+ if (p is FunctionType &&
+ q is FunctionType &&
+ p.typeParameters.isNotEmpty &&
+ q.typeParameters.isNotEmpty &&
p.typeParameters.length == q.typeParameters.length) {
final int baseConstraintCount = _protoConstraints.length;
@@ -880,8 +874,8 @@
new NullabilityAwareTypeVariableEliminator(
structuralEliminationTargets: p.typeParameters.toSet(),
nominalEliminationTargets: {},
- bottomType: _typeOperations.neverType,
- topType: _typeOperations.objectQuestionType,
+ bottomType: const NeverType.nonNullable(),
+ topType: _environment.coreTypes.objectNullableRawType,
topFunctionType:
_environment.coreTypes.functionNonNullableRawType,
unhandledTypeHandler: (DartType type, ignored) =>
@@ -918,10 +912,9 @@
// respect to `L` under constraints `C0 + ... + Cm`
// If for `i` in `0...m`, `Mi` is a subtype match for `Ni` with respect to
// `L` under constraints `Ci`.
- if (_typeOperations.isRecordType(p) &&
- _typeOperations.isRecordType(q) &&
- (p as RecordType).positional.length ==
- (q as RecordType).positional.length &&
+ if (p is RecordType &&
+ q is RecordType &&
+ p.positional.length == q.positional.length &&
p.named.length == q.named.length) {
bool sameNames = true;
for (int i = 0; sameNames && i < p.named.length; i++) {
@@ -961,10 +954,10 @@
DartType subtype, DartType supertype) {
// The unknown type `?` is a subtype match for any type `Q` with no
// constraints.
- if (_typeOperations.isUnknownType(subtype)) return true;
+ if (subtype is UnknownType) return true;
// Any type `P` is a subtype match for the unknown type `?` with no
// constraints.
- if (_typeOperations.isUnknownType(supertype)) return true;
+ if (supertype is UnknownType) return true;
// A type variable `T` in `L` is a subtype match for any type schema `Q`:
// - Under constraint `T <: Q`.
@@ -1006,8 +999,8 @@
if (identical(subtype, supertype)) return true;
// Handle FutureOr<T> union type.
- if (_typeOperations.matchFutureOr(subtype) != null) {
- DartType subtypeArg = (subtype as FutureOrType).typeArgument;
+ if (subtype is FutureOrType) {
+ DartType subtypeArg = subtype.typeArgument;
if (supertype is FutureOrType) {
// `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to
// `L` under constraints `C`:
@@ -1034,7 +1027,7 @@
.isSubtypeWhenUsingNullabilities();
}
- if (_typeOperations.matchFutureOr(supertype) != null) {
+ if (supertype is FutureOrType) {
// `P` is a subtype match for `FutureOr<Q>` with respect to `L` under
// constraints `C`:
// - If `P` is a subtype match for `Future<Q>` with respect to `L` under
@@ -1056,8 +1049,7 @@
// should be united. Also, computeNullability is used to fetch the
// nullability of the argument because it can be a FutureOr itself.
Nullability unitedNullability = uniteNullabilities(
- (supertype as FutureOrType).typeArgument.nullability,
- supertype.nullability);
+ supertype.typeArgument.nullability, supertype.nullability);
DartType supertypeArg =
supertype.typeArgument.withDeclaredNullability(unitedNullability);
DartType supertypeFuture =
@@ -1081,7 +1073,7 @@
if (_isTop(supertype)) return true;
// `Null` is a subtype match for any type `Q` under no constraints.
// Note that nullable types will change this.
- if (_typeOperations.isNull(subtype)) return true;
+ if (_isNull(subtype)) return true;
// A type variable `T` not in `L` with bound `P` is a subtype match for the
// same type variable `T` with bound `Q` with respect to `L` under
@@ -1121,17 +1113,15 @@
return _isNullabilityObliviousSubtypeMatch(
subtype.parameter.bound, supertype);
}
- if (_typeOperations.isInterfaceType(subtype) &&
- _typeOperations.isInterfaceType(supertype)) {
- return _isNullabilityObliviousInterfaceSubtypeMatch(
- subtype as InterfaceType, supertype as InterfaceType);
+ if (subtype is InterfaceType && supertype is InterfaceType) {
+ return _isNullabilityObliviousInterfaceSubtypeMatch(subtype, supertype);
}
- if (_typeOperations.isFunctionType(subtype)) {
- if (_typeOperations.isInterfaceType(supertype)) {
+ if (subtype is FunctionType) {
+ if (supertype is InterfaceType) {
return supertype == _environment.coreTypes.functionLegacyRawType ||
supertype == _environment.coreTypes.objectLegacyRawType;
} else if (supertype is FunctionType) {
- return _isFunctionSubtypeMatch(subtype as FunctionType, supertype);
+ return _isFunctionSubtypeMatch(subtype, supertype);
}
}
// A type `P` is a subtype match for a type `Q` with respect to `L` under
@@ -1139,9 +1129,8 @@
// - If `P` is an interface type which implements a call method of type `F`,
// and `F` is a subtype match for a type `Q` with respect to `L` under
// constraints `C`.
- if (_typeOperations.isInterfaceType(subtype)) {
- Member? callMember =
- getInterfaceMember((subtype as InterfaceType).classNode, callName);
+ if (subtype is InterfaceType) {
+ Member? callMember = getInterfaceMember(subtype.classNode, callName);
if (callMember is Procedure && !callMember.isGetter) {
DartType callType = callMember.getterType;
callType =
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 9cfeba1..cc583d6 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -4,7 +4,6 @@
import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis_operations.dart';
import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
-import 'package:_fe_analyzer_shared/src/type_inference/nullability_suffix.dart';
import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'
as shared;
import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'
@@ -14,7 +13,6 @@
show ClassHierarchy, ClassHierarchyBase;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'package:kernel/src/norm.dart';
-import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import '../../base/instrumentation.dart' show Instrumentation;
@@ -512,16 +510,10 @@
DartType get neverType => const NeverType.nonNullable();
@override
- DartType get nullType => const NullType();
-
- @override
DartType get objectQuestionType =>
typeEnvironment.coreTypes.objectNullableRawType;
@override
- DartType get objectType => typeEnvironment.coreTypes.objectNonNullableRawType;
-
- @override
DartType get unknownType => const UnknownType();
@override
@@ -553,20 +545,6 @@
}
@override
- NullabilitySuffix getNullabilitySuffix(DartType type) {
- if (isTypeWithoutNullabilityMarker(type,
- isNonNullableByDefault: nullability == Nullability.nonNullable)) {
- return NullabilitySuffix.none;
- } else if (isNullableTypeConstructorApplication(type)) {
- return NullabilitySuffix.question;
- } else {
- assert(isLegacyTypeConstructorApplication(type,
- isNonNullableByDefault: nullability == Nullability.nonNullable));
- return NullabilitySuffix.star;
- }
- }
-
- @override
DartType factor(DartType from, DartType what) {
return factorType(typeEnvironment, from, what);
}
@@ -577,33 +555,11 @@
}
@override
- bool isExtensionType(DartType type) {
- return type is ExtensionType;
- }
-
- @override
- bool isInterfaceType(DartType type) {
- return type is InterfaceType;
- }
-
- @override
bool isNever(DartType type) {
return typeEnvironment.coreTypes.isBottom(type);
}
@override
- bool isNull(DartType type) {
- return type is NullType;
- }
-
- @override
- bool isObject(DartType type) {
- return type is InterfaceType &&
- type.classNode == typeEnvironment.objectClass &&
- type.nullability == Nullability.nonNullable;
- }
-
- @override
bool isPropertyPromotable(covariant Member property) {
FieldNonPromotabilityInfo? fieldNonPromotabilityInfo =
this.fieldNonPromotabilityInfo;
@@ -628,9 +584,6 @@
}
@override
- bool isRecordType(DartType type) => type is RecordType;
-
- @override
PropertyNonPromotabilityReason? whyPropertyIsNotPromotable(
covariant Member property) {
FieldNonPromotabilityInfo? fieldNonPromotabilityInfo =
@@ -772,24 +725,12 @@
bool isError(DartType type) => type is InvalidType;
@override
- bool isFunctionType(DartType type) => type is FunctionType;
-
- @override
- DartType? matchFutureOr(DartType type) {
- if (type is! FutureOrType) {
- return null;
- } else {
- return type.typeArgument;
- }
- }
-
- @override
bool isTypeSchemaSatisfied(
{required DartType typeSchema, required DartType type}) =>
isSubtypeOf(type, typeSchema);
@override
- bool isUnknownType(DartType typeSchema) => typeSchema is UnknownType;
+ bool isUnknownType(DartType type) => type is UnknownType;
@override
bool isVariableFinal(VariableDeclaration node) {
@@ -797,9 +738,6 @@
}
@override
- bool isVoid(DartType type) => type is VoidType;
-
- @override
DartType iterableTypeSchema(DartType elementTypeSchema) {
return new InterfaceType(typeEnvironment.coreTypes.iterableClass,
Nullability.nonNullable, <DartType>[elementTypeSchema]);
@@ -967,38 +905,6 @@
@override
DartType typeToSchema(DartType type) => type;
-
- @override
- DartType withNullabilitySuffix(DartType type, NullabilitySuffix modifier) {
- switch (modifier) {
- case NullabilitySuffix.none:
- return computeTypeWithoutNullabilityMarker(type,
- isNonNullableByDefault: nullability == Nullability.nonNullable);
- case NullabilitySuffix.question:
- return type.withDeclaredNullability(Nullability.nullable);
- case NullabilitySuffix.star:
- return type.withDeclaredNullability(Nullability.legacy);
- }
- }
-
- @override
- TypeDeclarationKind? getTypeDeclarationKind(DartType type) {
- if (type is TypeDeclarationType) {
- switch (type) {
- case InterfaceType():
- return TypeDeclarationKind.interfaceDeclaration;
- case ExtensionType():
- return TypeDeclarationKind.extensionTypeDeclaration;
- }
- } else {
- return null;
- }
- }
-
- @override
- TypeDeclarationKind? getTypeSchemaDeclarationKind(DartType typeSchema) {
- return getTypeDeclarationKind(typeSchema);
- }
}
/// Type inference results used for testing.
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index d40c04a..36fbd07 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -1480,7 +1480,6 @@
immediate
immediately
immutable
-impact
implement
implementation
implementations
@@ -1536,13 +1535,11 @@
indicated
indicates
indicating
-indication
indices
indirect
indirectly
induce
induced
-inducing
infer
inference
inferrable
@@ -2064,7 +2061,6 @@
notice
noticed
notifies
-notions
now
nowhere
null
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 499f14f..39fbe33 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -2282,6 +2282,7 @@
@override
bool visitExtensionType(ExtensionType node) {
+ assert(node.declaredNullability != Nullability.undetermined);
return node.declaredNullability == Nullability.nullable ||
node.declaredNullability == Nullability.legacy;
}