| Index: pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| index e29d030b06dd7adb05e16d97e42ab3bcae621cde..b85c794fa14cb4abde5781ed1eecfbb28fc57ea8 100644
|
| --- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| +++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
|
| @@ -4,12 +4,16 @@
|
|
|
| library fasta.class_builder;
|
|
|
| +import '../errors.dart' show internalError;
|
| +
|
| import 'builder.dart'
|
| show
|
| Builder,
|
| ConstructorReferenceBuilder,
|
| LibraryBuilder,
|
| MetadataBuilder,
|
| + MixinApplicationBuilder,
|
| + NamedTypeBuilder,
|
| TypeBuilder,
|
| TypeDeclarationBuilder,
|
| TypeVariableBuilder;
|
| @@ -100,4 +104,67 @@ abstract class ClassBuilder<T extends TypeBuilder, R>
|
| }
|
|
|
| Builder findConstructorOrFactory(String name);
|
| +
|
| + /// Returns a map which maps the type variables of [superclass] to their
|
| + /// respective values as defined by the superclass clause of this class (and
|
| + /// its superclasses).
|
| + ///
|
| + /// It's assumed that [superclass] is a superclass of this class.
|
| + ///
|
| + /// For example, given:
|
| + ///
|
| + /// class Box<T> {}
|
| + /// class BeatBox extends Box<Beat> {}
|
| + /// class Beat {}
|
| + ///
|
| + /// We have:
|
| + ///
|
| + /// [[BeatBox]].getSubstitutionMap([[Box]]) -> {[[Box::T]]: Beat]]}.
|
| + ///
|
| + /// This method returns null if the map is empty, and it's an error if
|
| + /// [superclass] isn't a superclass.
|
| + Map<TypeVariableBuilder, TypeBuilder> getSubstitutionMap(
|
| + ClassBuilder superclass,
|
| + Uri fileUri,
|
| + int charOffset,
|
| + TypeBuilder dynamicType) {
|
| + TypeBuilder supertype = this.supertype;
|
| + Map<TypeVariableBuilder, TypeBuilder> substitutionMap;
|
| + List arguments;
|
| + List variables;
|
| + Builder builder;
|
| + while (builder != superclass) {
|
| + if (supertype is NamedTypeBuilder) {
|
| + NamedTypeBuilder t = supertype;
|
| + builder = t.builder;
|
| + arguments = t.arguments;
|
| + if (builder is ClassBuilder) {
|
| + variables = builder.typeVariables;
|
| + if (builder != superclass) {
|
| + supertype = builder.supertype;
|
| + }
|
| + }
|
| + } else if (supertype is MixinApplicationBuilder) {
|
| + MixinApplicationBuilder t = supertype;
|
| + supertype = t.supertype;
|
| + } else {
|
| + internalError("Superclass not found.", fileUri, charOffset);
|
| + }
|
| + if (variables != null) {
|
| + Map<TypeVariableBuilder, TypeBuilder> directSubstitutionMap =
|
| + <TypeVariableBuilder, TypeBuilder>{};
|
| + arguments ??= const [];
|
| + for (int i = 0; i < variables.length; i++) {
|
| + TypeBuilder argument =
|
| + arguments.length < i ? arguments[i] : dynamicType;
|
| + if (substitutionMap != null) {
|
| + argument = argument.subst(substitutionMap);
|
| + }
|
| + directSubstitutionMap[variables[i]] = argument;
|
| + }
|
| + substitutionMap = directSubstitutionMap;
|
| + }
|
| + }
|
| + return substitutionMap;
|
| + }
|
| }
|
|
|