OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.class_builder; | 5 library fasta.class_builder; |
6 | 6 |
7 import '../errors.dart' show internalError; | 7 import '../errors.dart' show internalError; |
8 | 8 |
9 import 'builder.dart' | 9 import 'builder.dart' |
10 show | 10 show |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 LibraryBuilder parent, | 49 LibraryBuilder parent, |
50 int charOffset) | 50 int charOffset) |
51 : scopeBuilder = new ScopeBuilder(scope), | 51 : scopeBuilder = new ScopeBuilder(scope), |
52 constructorScopeBuilder = new ScopeBuilder(constructors), | 52 constructorScopeBuilder = new ScopeBuilder(constructors), |
53 super(metadata, modifiers, name, parent, charOffset); | 53 super(metadata, modifiers, name, parent, charOffset); |
54 | 54 |
55 /// Returns true if this class is the result of applying a mixin to its | 55 /// Returns true if this class is the result of applying a mixin to its |
56 /// superclass. | 56 /// superclass. |
57 bool get isMixinApplication => mixedInType != null; | 57 bool get isMixinApplication => mixedInType != null; |
58 | 58 |
| 59 bool get isNamedMixinApplication { |
| 60 return isMixinApplication && super.isNamedMixinApplication; |
| 61 } |
| 62 |
59 T get mixedInType; | 63 T get mixedInType; |
60 | 64 |
| 65 void set mixedInType(T mixin); |
| 66 |
61 List<ConstructorReferenceBuilder> get constructorReferences => null; | 67 List<ConstructorReferenceBuilder> get constructorReferences => null; |
62 | 68 |
63 LibraryBuilder get library { | 69 LibraryBuilder get library { |
64 LibraryBuilder library = parent; | 70 LibraryBuilder library = parent; |
65 return library.partOfLibrary ?? library; | 71 return library.partOfLibrary ?? library; |
66 } | 72 } |
67 | 73 |
68 @override | 74 @override |
69 int resolveConstructors(LibraryBuilder library) { | 75 int resolveConstructors(LibraryBuilder library) { |
70 if (constructorReferences == null) return 0; | 76 if (constructorReferences == null) return 0; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 Map<TypeVariableBuilder, TypeBuilder> getSubstitutionMap( | 114 Map<TypeVariableBuilder, TypeBuilder> getSubstitutionMap( |
109 ClassBuilder superclass, | 115 ClassBuilder superclass, |
110 Uri fileUri, | 116 Uri fileUri, |
111 int charOffset, | 117 int charOffset, |
112 TypeBuilder dynamicType) { | 118 TypeBuilder dynamicType) { |
113 TypeBuilder supertype = this.supertype; | 119 TypeBuilder supertype = this.supertype; |
114 Map<TypeVariableBuilder, TypeBuilder> substitutionMap; | 120 Map<TypeVariableBuilder, TypeBuilder> substitutionMap; |
115 List arguments; | 121 List arguments; |
116 List variables; | 122 List variables; |
117 Builder builder; | 123 Builder builder; |
| 124 |
| 125 /// If [application] is mixing in [superclass] directly or via other named |
| 126 /// mixin applications, return it. |
| 127 NamedTypeBuilder findSuperclass(MixinApplicationBuilder application) { |
| 128 for (TypeBuilder t in application.mixins) { |
| 129 if (t is NamedTypeBuilder) { |
| 130 if (t.builder == superclass) return t; |
| 131 } else if (t is MixinApplicationBuilder) { |
| 132 NamedTypeBuilder s = findSuperclass(t); |
| 133 if (s != null) return s; |
| 134 } |
| 135 } |
| 136 return null; |
| 137 } |
| 138 |
| 139 void handleNamedTypeBuilder(NamedTypeBuilder t) { |
| 140 builder = t.builder; |
| 141 arguments = t.arguments ?? const []; |
| 142 if (builder is ClassBuilder) { |
| 143 ClassBuilder cls = builder; |
| 144 variables = cls.typeVariables; |
| 145 supertype = cls.supertype; |
| 146 } |
| 147 } |
| 148 |
118 while (builder != superclass) { | 149 while (builder != superclass) { |
| 150 variables = null; |
119 if (supertype is NamedTypeBuilder) { | 151 if (supertype is NamedTypeBuilder) { |
120 NamedTypeBuilder t = supertype; | 152 handleNamedTypeBuilder(supertype); |
121 builder = t.builder; | |
122 arguments = t.arguments; | |
123 if (builder is ClassBuilder) { | |
124 variables = builder.typeVariables; | |
125 if (builder != superclass) { | |
126 supertype = builder.supertype; | |
127 } | |
128 } | |
129 } else if (supertype is MixinApplicationBuilder) { | 153 } else if (supertype is MixinApplicationBuilder) { |
130 MixinApplicationBuilder t = supertype; | 154 MixinApplicationBuilder t = supertype; |
| 155 NamedTypeBuilder s = findSuperclass(t); |
| 156 if (s != null) { |
| 157 handleNamedTypeBuilder(s); |
| 158 } |
131 supertype = t.supertype; | 159 supertype = t.supertype; |
132 } else { | 160 } else { |
133 internalError("Superclass not found.", fileUri, charOffset); | 161 internalError("Superclass not found '${superclass.fullNameForErrors}'.", |
| 162 fileUri, charOffset); |
134 } | 163 } |
135 if (variables != null) { | 164 if (variables != null) { |
136 Map<TypeVariableBuilder, TypeBuilder> directSubstitutionMap = | 165 Map<TypeVariableBuilder, TypeBuilder> directSubstitutionMap = |
137 <TypeVariableBuilder, TypeBuilder>{}; | 166 <TypeVariableBuilder, TypeBuilder>{}; |
138 arguments ??= const []; | |
139 for (int i = 0; i < variables.length; i++) { | 167 for (int i = 0; i < variables.length; i++) { |
140 TypeBuilder argument = | 168 TypeBuilder argument = |
141 arguments.length < i ? arguments[i] : dynamicType; | 169 i < arguments.length ? arguments[i] : dynamicType; |
142 if (substitutionMap != null) { | 170 if (substitutionMap != null) { |
143 argument = argument.subst(substitutionMap); | 171 argument = argument.subst(substitutionMap); |
144 } | 172 } |
145 directSubstitutionMap[variables[i]] = argument; | 173 directSubstitutionMap[variables[i]] = argument; |
146 } | 174 } |
147 substitutionMap = directSubstitutionMap; | 175 substitutionMap = directSubstitutionMap; |
148 } | 176 } |
149 } | 177 } |
150 return substitutionMap; | 178 return substitutionMap; |
151 } | 179 } |
(...skipping 14 matching lines...) Expand all Loading... |
166 } | 194 } |
167 | 195 |
168 void addWarning(int charOffset, String message) { | 196 void addWarning(int charOffset, String message) { |
169 library.addWarning(charOffset, message, fileUri: fileUri); | 197 library.addWarning(charOffset, message, fileUri: fileUri); |
170 } | 198 } |
171 | 199 |
172 void addNit(int charOffset, String message) { | 200 void addNit(int charOffset, String message) { |
173 library.addNit(charOffset, message, fileUri: fileUri); | 201 library.addNit(charOffset, message, fileUri: fileUri); |
174 } | 202 } |
175 } | 203 } |
OLD | NEW |