Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Unified Diff: pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart

Issue 2837093002: Add type schema elimination logic. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
new file mode 100644
index 0000000000000000000000000000000000000000..f9b856ffd59969aee32d910a8d1b5f3ede5b5ea0
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_elimination.dart
@@ -0,0 +1,127 @@
+// Copyright (c) 2017, 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.md file.
+
+import 'package:front_end/src/fasta/type_inference/type_schema.dart';
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+
+/// Returns the greatest closure of the given type [schema] with respect to `?`.
+///
+/// The greatest closure of a type schema `P` with respect to `?` is defined as
+/// `P` with every covariant occurrence of `?` replaced with `Null`, and every
+/// contravariant occurrence of `?` replaced with `Object`.
+///
+/// If the schema contains no instances of `?`, the original schema object is
+/// returned to avoid unnecessary allocation.
+///
+/// Note that the closure of a type schema is a proper type.
+///
+/// Note that the greatest closure of a type schema is always a supertype of any
+/// type which matches the schema.
+DartType greatestClosure(CoreTypes coreTypes, DartType schema) =>
+ _TypeSchemaEliminationVisitor.run(coreTypes, false, schema);
+
+/// Returns the least closure of the given type [schema] with respect to `?`.
+///
+/// The least closure of a type schema `P` with respect to `?` is defined as
+/// `P` with every covariant occurrence of `?` replaced with `Object`, and every
+/// contravariant occurrence of `?` replaced with `Null`.
+///
+/// If the schema contains no instances of `?`, the original schema object is
+/// returned to avoid unnecessary allocation.
+///
+/// Note that the closure of a type schema is a proper type.
+///
+/// Note that the least closure of a type schema is always a subtype of any type
+/// which matches the schema.
+DartType leastClosure(CoreTypes coreTypes, DartType schema) =>
+ _TypeSchemaEliminationVisitor.run(coreTypes, true, schema);
+
+/// Visitor that computes least and greatest closures of a type schema.
+///
+/// Each visitor method returns `null` if there are no `?`s contained in the
+/// type, otherwise it returns the result of substituting `?` with `Null` or
+/// `Object`, as appropriate.
+class _TypeSchemaEliminationVisitor extends TypeSchemaVisitor<DartType> {
+ final DartType nullType;
+
+ final DartType objectType;
+
+ bool isLeastClosure;
+
+ _TypeSchemaEliminationVisitor(CoreTypes coreTypes, this.isLeastClosure)
+ : nullType = coreTypes.nullClass.rawType,
+ objectType = coreTypes.objectClass.rawType;
+
+ @override
+ DartType visitFunctionType(FunctionType node) {
+ DartType newReturnType = node.returnType.accept(this);
+ isLeastClosure = !isLeastClosure;
+ List<DartType> newPositionalParameters = null;
+ for (int i = 0; i < node.positionalParameters.length; i++) {
+ DartType substitution = node.positionalParameters[i].accept(this);
+ if (substitution != null) {
+ newPositionalParameters =
+ node.positionalParameters.toList(growable: false);
+ newPositionalParameters[i] = substitution;
+ }
+ }
+ List<NamedType> newNamedParameters = null;
+ for (int i = 0; i < node.namedParameters.length; i++) {
+ DartType substitution = node.namedParameters[i].type.accept(this);
+ if (substitution != null) {
+ newNamedParameters = node.namedParameters.toList(growable: false);
+ newNamedParameters[i] =
+ new NamedType(node.namedParameters[i].name, substitution);
+ }
+ }
+ isLeastClosure = !isLeastClosure;
+ if (newReturnType == null &&
+ newPositionalParameters == null &&
+ newNamedParameters == null) {
+ // No types had to be substituted.
+ return null;
+ } else {
+ return new FunctionType(
+ newPositionalParameters ?? node.positionalParameters,
+ newReturnType ?? node.returnType,
+ namedParameters: newNamedParameters ?? node.namedParameters,
+ typeParameters: node.typeParameters,
+ requiredParameterCount: node.requiredParameterCount);
+ }
+ }
+
+ @override
+ DartType visitInterfaceType(InterfaceType node) {
+ List<DartType> newTypeArguments = null;
+ for (int i = 0; i < node.typeArguments.length; i++) {
+ DartType substitution = node.typeArguments[i].accept(this);
+ if (substitution != null) {
+ newTypeArguments ??= node.typeArguments.toList(growable: false);
+ newTypeArguments[i] = substitution;
+ }
+ }
+ if (newTypeArguments == null) {
+ // No type arguments needed to be substituted.
+ return null;
+ } else {
+ return new InterfaceType(node.classNode, newTypeArguments);
+ }
+ }
+
+ @override
+ DartType visitUnknownType(UnknownType node) =>
+ isLeastClosure ? nullType : objectType;
+
+ /// Runs an instance of the visitor on the given [schema] and returns the
+ /// resulting type. If the schema contains no instances of `?`, the original
+ /// schema object is returned to avoid unnecessary allocation.
+ static DartType run(
+ CoreTypes coreTypes, bool isLeastClosure, DartType schema) {
+ var visitor = new _TypeSchemaEliminationVisitor(coreTypes, isLeastClosure);
+ var result = schema.accept(visitor);
+ assert(visitor.isLeastClosure == isLeastClosure);
+ return result ?? schema;
+ }
+}
« no previous file with comments | « no previous file | pkg/front_end/test/fasta/type_inference/type_schema_elimination_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698