|
| 1 | +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file |
| 2 | +// for details. All rights reserved. Use of this source code is governed by a |
| 3 | +// BSD-style license that can be found in the LICENSE file. |
| 4 | + |
| 5 | +import '../builder/inline_class_builder.dart'; |
| 6 | +import '../builder/member_builder.dart'; |
| 7 | +import '../builder/type_builder.dart'; |
| 8 | +import '../builder/type_variable_builder.dart'; |
| 9 | +import 'package:kernel/ast.dart'; |
| 10 | + |
| 11 | +import '../scope.dart'; |
| 12 | +import 'dill_class_builder.dart'; |
| 13 | +import 'dill_extension_type_member_builder.dart'; |
| 14 | +import 'dill_library_builder.dart'; |
| 15 | + |
| 16 | +class DillExtensionTypeBuilder extends InlineClassBuilderImpl { |
| 17 | + final InlineClass _extensionType; |
| 18 | + |
| 19 | + List<TypeVariableBuilder>? _typeParameters; |
| 20 | + |
| 21 | + List<TypeBuilder>? _interfaceBuilders; |
| 22 | + |
| 23 | + DillExtensionTypeBuilder(this._extensionType, DillLibraryBuilder parent) |
| 24 | + : super( |
| 25 | + /*metadata builders*/ |
| 26 | + null, |
| 27 | + /* modifiers*/ |
| 28 | + 0, |
| 29 | + _extensionType.name, |
| 30 | + parent, |
| 31 | + _extensionType.fileOffset, |
| 32 | + new Scope( |
| 33 | + kind: ScopeKind.declaration, |
| 34 | + local: <String, MemberBuilder>{}, |
| 35 | + setters: <String, MemberBuilder>{}, |
| 36 | + parent: parent.scope, |
| 37 | + debugName: "extension type ${_extensionType.name}", |
| 38 | + isModifiable: false), |
| 39 | + new ConstructorScope( |
| 40 | + _extensionType.name, <String, MemberBuilder>{})) { |
| 41 | + Map<Name, Procedure> _tearOffs = {}; |
| 42 | + for (InlineClassMemberDescriptor descriptor in inlineClass.members) { |
| 43 | + Name name = descriptor.name; |
| 44 | + if (descriptor.kind == InlineClassMemberKind.TearOff) { |
| 45 | + _tearOffs[name] = descriptor.member.asProcedure; |
| 46 | + } |
| 47 | + } |
| 48 | + |
| 49 | + for (InlineClassMemberDescriptor descriptor in inlineClass.members) { |
| 50 | + Name name = descriptor.name; |
| 51 | + switch (descriptor.kind) { |
| 52 | + case InlineClassMemberKind.Method: |
| 53 | + if (descriptor.isStatic) { |
| 54 | + Procedure procedure = descriptor.member.asProcedure; |
| 55 | + scope.addLocalMember( |
| 56 | + name.text, |
| 57 | + new DillExtensionTypeStaticMethodBuilder( |
| 58 | + procedure, descriptor, this), |
| 59 | + setter: false); |
| 60 | + } else { |
| 61 | + Procedure procedure = descriptor.member.asProcedure; |
| 62 | + assert(_tearOffs.containsKey(name), |
| 63 | + "No tear found for ${descriptor} in ${_tearOffs}"); |
| 64 | + scope.addLocalMember( |
| 65 | + name.text, |
| 66 | + new DillExtensionTypeInstanceMethodBuilder( |
| 67 | + procedure, descriptor, this, _tearOffs[name]!), |
| 68 | + setter: false); |
| 69 | + } |
| 70 | + break; |
| 71 | + case InlineClassMemberKind.TearOff: |
| 72 | + assert(_tearOffs[name] == descriptor.member.asProcedure); |
| 73 | + break; |
| 74 | + case InlineClassMemberKind.Getter: |
| 75 | + Procedure procedure = descriptor.member.asProcedure; |
| 76 | + scope.addLocalMember(name.text, |
| 77 | + new DillExtensionTypeGetterBuilder(procedure, descriptor, this), |
| 78 | + setter: false); |
| 79 | + break; |
| 80 | + case InlineClassMemberKind.Field: |
| 81 | + Field field = descriptor.member.asField; |
| 82 | + scope.addLocalMember(name.text, |
| 83 | + new DillExtensionTypeFieldBuilder(field, descriptor, this), |
| 84 | + setter: false); |
| 85 | + break; |
| 86 | + case InlineClassMemberKind.Setter: |
| 87 | + Procedure procedure = descriptor.member.asProcedure; |
| 88 | + scope.addLocalMember(name.text, |
| 89 | + new DillExtensionTypeSetterBuilder(procedure, descriptor, this), |
| 90 | + setter: true); |
| 91 | + break; |
| 92 | + case InlineClassMemberKind.Operator: |
| 93 | + Procedure procedure = descriptor.member.asProcedure; |
| 94 | + scope.addLocalMember(name.text, |
| 95 | + new DillExtensionTypeOperatorBuilder(procedure, descriptor, this), |
| 96 | + setter: false); |
| 97 | + break; |
| 98 | + case InlineClassMemberKind.Constructor: |
| 99 | + Procedure procedure = descriptor.member.asProcedure; |
| 100 | + constructorScope.addLocalMember( |
| 101 | + name.text, |
| 102 | + new DillExtensionTypeConstructorBuilder( |
| 103 | + procedure, _tearOffs[name], descriptor, this)); |
| 104 | + break; |
| 105 | + case InlineClassMemberKind.Factory: |
| 106 | + case InlineClassMemberKind.RedirectingFactory: |
| 107 | + Procedure procedure = descriptor.member.asProcedure; |
| 108 | + constructorScope.addLocalMember( |
| 109 | + name.text, |
| 110 | + new DillExtensionTypeFactoryBuilder( |
| 111 | + procedure, _tearOffs[name], descriptor, this)); |
| 112 | + break; |
| 113 | + } |
| 114 | + } |
| 115 | + } |
| 116 | + |
| 117 | + @override |
| 118 | + DillLibraryBuilder get libraryBuilder => parent as DillLibraryBuilder; |
| 119 | + |
| 120 | + @override |
| 121 | + DartType get declaredRepresentationType => |
| 122 | + _extensionType.declaredRepresentationType; |
| 123 | + |
| 124 | + @override |
| 125 | + InlineClass get inlineClass => _extensionType; |
| 126 | + |
| 127 | + @override |
| 128 | + List<TypeVariableBuilder>? get typeParameters { |
| 129 | + List<TypeVariableBuilder>? typeVariables = _typeParameters; |
| 130 | + if (typeVariables == null && _extensionType.typeParameters.isNotEmpty) { |
| 131 | + typeVariables = _typeParameters = computeTypeVariableBuilders( |
| 132 | + libraryBuilder, _extensionType.typeParameters); |
| 133 | + } |
| 134 | + return typeVariables; |
| 135 | + } |
| 136 | + |
| 137 | + @override |
| 138 | + List<TypeBuilder>? get interfaceBuilders { |
| 139 | + if (_extensionType.implements.isEmpty) return null; |
| 140 | + List<TypeBuilder>? interfaceBuilders = _interfaceBuilders; |
| 141 | + if (interfaceBuilders == null) { |
| 142 | + interfaceBuilders = _interfaceBuilders = new List<TypeBuilder>.generate( |
| 143 | + _extensionType.implements.length, |
| 144 | + (int i) => libraryBuilder.loader |
| 145 | + .computeTypeBuilder(_extensionType.implements[i]), |
| 146 | + growable: false); |
| 147 | + } |
| 148 | + return interfaceBuilders; |
| 149 | + } |
| 150 | +} |
0 commit comments