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..cc583d61 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; }