Chromium Code Reviews| 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.kernel_library_builder; | 5 library fasta.kernel_library_builder; |
| 6 | 6 |
| 7 import 'package:kernel/ast.dart'; | 7 import 'package:kernel/ast.dart'; |
| 8 | 8 |
| 9 import 'package:kernel/clone.dart' show CloneVisitor; | 9 import 'package:kernel/clone.dart' show CloneVisitor; |
| 10 | 10 |
| 11 import '../errors.dart' show internalError; | 11 import '../errors.dart' show internalError; |
| 12 | 12 |
| 13 import '../loader.dart' show Loader; | 13 import '../loader.dart' show Loader; |
| 14 | 14 |
| 15 import '../modifier.dart' show abstractMask, staticMask; | 15 import '../modifier.dart' |
| 16 show abstractMask, namedMixinApplicationMask, staticMask; | |
| 16 | 17 |
| 17 import '../source/source_library_builder.dart' | 18 import '../source/source_library_builder.dart' |
| 18 show DeclarationBuilder, SourceLibraryBuilder; | 19 show DeclarationBuilder, SourceLibraryBuilder; |
| 19 | 20 |
| 20 import '../source/source_class_builder.dart' show SourceClassBuilder; | 21 import '../source/source_class_builder.dart' show SourceClassBuilder; |
| 21 | 22 |
| 22 import '../util/relativize.dart' show relativizeUri; | 23 import '../util/relativize.dart' show relativizeUri; |
| 23 | 24 |
| 24 import 'kernel_builder.dart' | 25 import 'kernel_builder.dart' |
| 25 show | 26 show |
| 26 AccessErrorBuilder, | 27 AccessErrorBuilder, |
| 27 Builder, | 28 Builder, |
| 28 BuiltinTypeBuilder, | 29 BuiltinTypeBuilder, |
| 29 ClassBuilder, | 30 ClassBuilder, |
| 30 ConstructorReferenceBuilder, | 31 ConstructorReferenceBuilder, |
| 31 FormalParameterBuilder, | 32 FormalParameterBuilder, |
| 32 FunctionTypeAliasBuilder, | 33 FunctionTypeAliasBuilder, |
| 33 InvalidTypeBuilder, | 34 InvalidTypeBuilder, |
| 34 KernelConstructorBuilder, | 35 KernelConstructorBuilder, |
| 35 KernelEnumBuilder, | 36 KernelEnumBuilder, |
| 36 KernelFieldBuilder, | 37 KernelFieldBuilder, |
| 37 KernelFormalParameterBuilder, | 38 KernelFormalParameterBuilder, |
| 38 KernelFunctionTypeAliasBuilder, | 39 KernelFunctionTypeAliasBuilder, |
| 39 KernelFunctionTypeBuilder, | 40 KernelFunctionTypeBuilder, |
| 40 KernelInvalidTypeBuilder, | 41 KernelInvalidTypeBuilder, |
| 41 KernelMixinApplicationBuilder, | 42 KernelMixinApplicationBuilder, |
| 42 KernelNamedMixinApplicationBuilder, | |
| 43 KernelNamedTypeBuilder, | 43 KernelNamedTypeBuilder, |
| 44 KernelProcedureBuilder, | 44 KernelProcedureBuilder, |
| 45 KernelTypeBuilder, | 45 KernelTypeBuilder, |
| 46 KernelTypeVariableBuilder, | 46 KernelTypeVariableBuilder, |
| 47 LibraryBuilder, | 47 LibraryBuilder, |
| 48 MemberBuilder, | 48 MemberBuilder, |
| 49 MetadataBuilder, | 49 MetadataBuilder, |
| 50 NamedMixinApplicationBuilder, | 50 NamedTypeBuilder, |
| 51 PrefixBuilder, | 51 PrefixBuilder, |
| 52 ProcedureBuilder, | 52 ProcedureBuilder, |
| 53 Scope, | 53 Scope, |
| 54 TypeBuilder, | 54 TypeBuilder, |
| 55 TypeVariableBuilder, | 55 TypeVariableBuilder, |
| 56 compareProcedures; | 56 compareProcedures; |
| 57 | 57 |
| 58 class KernelLibraryBuilder | 58 class KernelLibraryBuilder |
| 59 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { | 59 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { |
| 60 final Library library; | 60 final Library library; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 96 | 96 |
| 97 void addClass( | 97 void addClass( |
| 98 List<MetadataBuilder> metadata, | 98 List<MetadataBuilder> metadata, |
| 99 int modifiers, | 99 int modifiers, |
| 100 String className, | 100 String className, |
| 101 List<TypeVariableBuilder> typeVariables, | 101 List<TypeVariableBuilder> typeVariables, |
| 102 KernelTypeBuilder supertype, | 102 KernelTypeBuilder supertype, |
| 103 List<KernelTypeBuilder> interfaces, | 103 List<KernelTypeBuilder> interfaces, |
| 104 int charOffset) { | 104 int charOffset) { |
| 105 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. | 105 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. |
| 106 var declaration = endNestedDeclaration(); | 106 var declaration = endNestedDeclaration()..resolveTypes(typeVariables, this); |
| 107 assert(declaration.parent == libraryDeclaration); | 107 assert(declaration.parent == libraryDeclaration); |
| 108 Map<String, MemberBuilder> members = declaration.members; | 108 Map<String, MemberBuilder> members = declaration.members; |
| 109 Map<String, MemberBuilder> constructors = declaration.constructors; | 109 Map<String, MemberBuilder> constructors = declaration.constructors; |
| 110 Map<String, MemberBuilder> setters = declaration.setters; | 110 Map<String, MemberBuilder> setters = declaration.setters; |
| 111 | 111 |
| 112 Scope classScope = new Scope( | 112 Scope classScope = new Scope( |
| 113 members, setters, scope.withTypeVariables(typeVariables), | 113 members, setters, scope.withTypeVariables(typeVariables), |
| 114 isModifiable: false); | 114 isModifiable: false); |
| 115 | 115 |
| 116 // When looking up a constructor, we don't consider type variables or the | 116 // When looking up a constructor, we don't consider type variables or the |
| 117 // library scope. | 117 // library scope. |
| 118 Scope constructorScope = | 118 Scope constructorScope = |
| 119 new Scope(constructors, null, null, isModifiable: false); | 119 new Scope(constructors, null, null, isModifiable: false); |
| 120 ClassBuilder cls = new SourceClassBuilder( | 120 ClassBuilder cls = new SourceClassBuilder( |
| 121 metadata, | 121 metadata, |
| 122 modifiers, | 122 modifiers, |
| 123 className, | 123 className, |
| 124 typeVariables, | 124 typeVariables, |
| 125 applyMixins(supertype), | 125 applyMixins(supertype, |
| 126 subclassName: className, typeVariables: typeVariables), | |
| 126 interfaces, | 127 interfaces, |
| 127 classScope, | 128 classScope, |
| 128 constructorScope, | 129 constructorScope, |
| 129 this, | 130 this, |
| 130 new List<ConstructorReferenceBuilder>.from(constructorReferences), | 131 new List<ConstructorReferenceBuilder>.from(constructorReferences), |
| 131 charOffset); | 132 charOffset); |
| 132 constructorReferences.clear(); | 133 constructorReferences.clear(); |
| 133 Map<String, TypeVariableBuilder> typeVariablesByName = | 134 Map<String, TypeVariableBuilder> typeVariablesByName = |
| 134 checkTypeVariables(typeVariables, cls); | 135 checkTypeVariables(typeVariables, cls); |
| 135 void setParent(String name, MemberBuilder member) { | 136 void setParent(String name, MemberBuilder member) { |
| 137 while (member != null) { | |
| 138 member.parent = cls; | |
| 139 member = member.next; | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 void setParentAndCheckConflicts(String name, MemberBuilder member) { | |
| 136 if (typeVariablesByName != null) { | 144 if (typeVariablesByName != null) { |
| 137 TypeVariableBuilder tv = typeVariablesByName[name]; | 145 TypeVariableBuilder tv = typeVariablesByName[name]; |
| 138 if (tv != null) { | 146 if (tv != null) { |
| 139 cls.addCompileTimeError( | 147 cls.addCompileTimeError( |
| 140 member.charOffset, "Conflict with type variable '$name'."); | 148 member.charOffset, "Conflict with type variable '$name'."); |
| 141 cls.addCompileTimeError(tv.charOffset, "This is the type variable."); | 149 cls.addCompileTimeError(tv.charOffset, "This is the type variable."); |
| 142 } | 150 } |
| 143 } | 151 } |
| 144 while (member != null) { | 152 setParent(name, member); |
| 145 member.parent = cls; | |
| 146 member = member.next; | |
| 147 } | |
| 148 } | 153 } |
| 149 | 154 |
| 150 members.forEach(setParent); | 155 members.forEach(setParentAndCheckConflicts); |
| 151 constructors.forEach(setParent); | 156 constructors.forEach(setParentAndCheckConflicts); |
| 157 // Formally, a setter has the name `id=`, so it can never conflict with a | |
| 158 // type variable. | |
| 152 setters.forEach(setParent); | 159 setters.forEach(setParent); |
| 153 declaration.resolveTypes(typeVariables, this); | |
| 154 addBuilder(className, cls, charOffset); | 160 addBuilder(className, cls, charOffset); |
| 155 } | 161 } |
| 156 | 162 |
| 157 Map<String, TypeVariableBuilder> checkTypeVariables( | 163 Map<String, TypeVariableBuilder> checkTypeVariables( |
| 158 List<TypeVariableBuilder> typeVariables, Builder owner) { | 164 List<TypeVariableBuilder> typeVariables, Builder owner) { |
| 159 if (typeVariables?.isEmpty ?? true) return null; | 165 if (typeVariables?.isEmpty ?? true) return null; |
| 160 Map<String, TypeVariableBuilder> typeVariablesByName = | 166 Map<String, TypeVariableBuilder> typeVariablesByName = |
| 161 <String, TypeVariableBuilder>{}; | 167 <String, TypeVariableBuilder>{}; |
| 162 for (TypeVariableBuilder tv in typeVariables) { | 168 for (TypeVariableBuilder tv in typeVariables) { |
| 163 TypeVariableBuilder existing = typeVariablesByName[tv.name]; | 169 TypeVariableBuilder existing = typeVariablesByName[tv.name]; |
| 164 if (existing != null) { | 170 if (existing != null) { |
| 165 addCompileTimeError(tv.charOffset, | 171 addCompileTimeError(tv.charOffset, |
| 166 "A type variable can't have the same name as another."); | 172 "A type variable can't have the same name as another."); |
| 167 addCompileTimeError( | 173 addCompileTimeError( |
| 168 existing.charOffset, "The other type variable named '${tv.name}'."); | 174 existing.charOffset, "The other type variable named '${tv.name}'."); |
| 169 } else { | 175 } else { |
| 170 typeVariablesByName[tv.name] = tv; | 176 typeVariablesByName[tv.name] = tv; |
| 171 if (tv.name == owner.name) { | 177 if (owner is ClassBuilder) { |
|
Johnni Winther
2017/05/08 10:05:34
Why is the only for classes? Aren't `typedef F<F>(
ahe
2017/05/08 11:13:15
Not according to our tests, and it also seems like
| |
| 172 addCompileTimeError( | 178 if (tv.name == owner.name) { |
| 173 tv.charOffset, | 179 addCompileTimeError( |
| 174 "A type variable can't have the same name as its enclosing " | 180 tv.charOffset, |
| 175 "declaration."); | 181 "A type variable can't have the same name as its enclosing " |
| 182 "declaration."); | |
| 183 } | |
| 176 } | 184 } |
| 177 } | 185 } |
| 178 } | 186 } |
| 179 return typeVariablesByName; | 187 return typeVariablesByName; |
| 180 } | 188 } |
| 181 | 189 |
| 182 KernelNamedTypeBuilder removeTypeVariables(KernelNamedTypeBuilder type) { | |
| 183 return type.arguments == null | |
| 184 ? type | |
| 185 : addNamedType(type.name, null, type.charOffset); | |
| 186 } | |
| 187 | |
| 188 KernelTypeBuilder applyMixin( | 190 KernelTypeBuilder applyMixin( |
| 189 KernelTypeBuilder supertype, KernelTypeBuilder mixin, String name) { | 191 KernelTypeBuilder supertype, KernelTypeBuilder mixin, String signature, |
| 190 supertype = removeTypeVariables(supertype); | 192 {List<MetadataBuilder> metadata, |
| 191 mixin = removeTypeVariables(mixin); | 193 String name, |
| 194 List<TypeVariableBuilder> typeVariables, | |
| 195 int modifiers: abstractMask, | |
| 196 List<KernelTypeBuilder> interfaces, | |
| 197 int charOffset: -1}) { | |
| 192 var constructors = <String, MemberBuilder>{}; | 198 var constructors = <String, MemberBuilder>{}; |
| 193 if (name != null) { | 199 bool isNamed = name != null; |
| 194 constructors[""] = new KernelConstructorBuilder( | 200 SourceClassBuilder builder; |
| 195 null, 0, null, "", null, null, this, mixin.charOffset, -1, -1, null); | 201 if (isNamed) { |
| 196 } | 202 modifiers |= namedMixinApplicationMask; |
| 197 if (name == null) { | 203 } else { |
| 198 name = "${supertype.name}&${mixin.name}"; | 204 name = supertype.name; |
| 199 } | 205 int index = name.indexOf("^"); |
| 200 var builder = mixinApplicationClasses.putIfAbsent(name, () { | 206 if (index != -1) { |
| 201 var builder = new SourceClassBuilder( | 207 name = name.substring(0, index); |
| 202 null, // metadata | 208 } |
| 203 0, // modifiers | 209 name = "$name&${mixin.name}$signature"; |
| 210 builder = mixinApplicationClasses[name]; | |
| 211 } | |
| 212 if (builder == null) { | |
| 213 builder = new SourceClassBuilder( | |
| 214 metadata, | |
| 215 modifiers, | |
| 204 name, | 216 name, |
| 205 null, // typeVariables | 217 typeVariables, |
| 206 supertype, | 218 supertype, |
| 207 null, // interfaces | 219 interfaces, |
| 208 new Scope(<String, MemberBuilder>{}, <String, MemberBuilder>{}, | 220 new Scope(<String, MemberBuilder>{}, <String, MemberBuilder>{}, |
| 209 scope.withTypeVariables(null /* typeVariables */), | 221 scope.withTypeVariables(typeVariables), |
| 210 isModifiable: false), | 222 isModifiable: false), |
| 211 new Scope(constructors, null, null, isModifiable: false), | 223 new Scope(constructors, null, null, isModifiable: false), |
| 212 this, | 224 this, |
| 213 <ConstructorReferenceBuilder>[], | 225 <ConstructorReferenceBuilder>[], |
| 214 -1, // charOffset | 226 charOffset, |
| 215 null, | 227 null, |
| 216 mixin); | 228 mixin); |
| 217 addBuilder(name, builder, -1 /* charOffset */); | 229 addBuilder(name, builder, charOffset); |
| 218 return builder; | 230 if (!isNamed) { |
| 219 }); | 231 mixinApplicationClasses[name] = builder; |
| 220 return new KernelNamedTypeBuilder(name, null, -1 /* charOffset */, fileUri) | 232 } |
| 221 ..bind(builder); | 233 } |
| 234 return addNamedType(name, <KernelTypeBuilder>[], charOffset) | |
| 235 ..bind(isNamed ? builder : null); | |
| 222 } | 236 } |
| 223 | 237 |
| 224 KernelTypeBuilder applyMixins(KernelTypeBuilder type, [String name]) { | 238 KernelTypeBuilder applyMixins(KernelTypeBuilder type, |
| 239 {List<MetadataBuilder> metadata, | |
| 240 String name, | |
| 241 String subclassName, | |
| 242 List<TypeVariableBuilder> typeVariables, | |
| 243 int modifiers: abstractMask, | |
| 244 List<KernelTypeBuilder> interfaces, | |
| 245 int charOffset: -1}) { | |
| 225 if (type is KernelMixinApplicationBuilder) { | 246 if (type is KernelMixinApplicationBuilder) { |
| 247 subclassName ??= name; | |
| 248 List<List<String>> signatureParts = <List<String>>[]; | |
| 249 Map<String, String> unresolved = <String, String>{}; | |
| 250 Map<String, String> unresolvedReversed = <String, String>{}; | |
| 251 int unresolvedCount = 0; | |
| 252 Map<String, TypeBuilder> freeTypes = <String, TypeBuilder>{}; | |
| 253 | |
| 254 if (name == null || type.mixins.length != 1) { | |
| 255 TypeBuilder last = type.mixins.last; | |
| 256 | |
| 257 /// Compute a signature of the type arguments used by the supertype and | |
| 258 /// mixins. These types are free variables. At this point we can't | |
| 259 /// trust that the number of type arguments match the type parameters, | |
| 260 /// so we also need to be able to detect missing type arguments. To do | |
| 261 /// so, we separate each list of type arguments by `^` and type | |
| 262 /// arguments by `&`. For example, the mixin `C<S> with M<T, U>` would | |
| 263 /// look like this: | |
| 264 /// | |
| 265 /// ^#U0^#U1&#U2 | |
| 266 /// | |
| 267 /// Where `#U0`, `#U1`, and `#U2` are the free variables arising from | |
| 268 /// `S`, `T`, and `U` respectively. | |
| 269 /// | |
| 270 /// As we can resolve any type parameters used at this point, those are | |
| 271 /// named `#T0` and so forth. This reduces the number of free variables | |
| 272 /// which is crucial for memory usage and the Dart VM's bootstrap | |
| 273 /// sequence. | |
| 274 /// | |
| 275 /// For example, consider this use of mixin applications: | |
| 276 /// | |
| 277 /// class _InternalLinkedHashMap<K, V> extends _HashVMBase | |
| 278 /// with | |
| 279 /// MapMixin<K, V>, | |
| 280 /// _LinkedHashMapMixin<K, V>, | |
| 281 /// _HashBase, | |
| 282 /// _OperatorEqualsAndHashCode {} | |
| 283 /// | |
| 284 /// In this case, only two variables are free, and we produce this | |
| 285 /// signature: `^^#T0&#T1^#T0&#T1^^`. Assume another class uses the | |
| 286 /// sames mixins but with missing type arguments for `MapMixin`, its | |
| 287 /// signature would be: `^^^#T0&#T1^^`. | |
| 288 /// | |
| 289 /// Note that we do not need to compute a signature for a named mixin | |
| 290 /// application with only one mixin as we don't have to invent a name | |
| 291 /// for any classes in this situation. | |
| 292 void analyzeArguments(TypeBuilder type) { | |
| 293 if (name != null && type == last) { | |
| 294 // The last mixin of a named mixin application doesn't contribute | |
| 295 // to free variables. | |
| 296 return; | |
| 297 } | |
| 298 if (type is NamedTypeBuilder) { | |
| 299 List<String> part = <String>[]; | |
| 300 for (int i = 0; i < (type.arguments?.length ?? 0); i++) { | |
| 301 var argument = type.arguments[i]; | |
| 302 String name; | |
| 303 if (argument is NamedTypeBuilder) { | |
| 304 if (argument.builder != null) { | |
| 305 int index = typeVariables?.indexOf(argument.builder) ?? -1; | |
| 306 if (index != -1) { | |
| 307 name = "#T${index}"; | |
| 308 } | |
| 309 } else if (argument.arguments == null) { | |
| 310 name = unresolved[argument.name] ??= "#U${unresolvedCount++}"; | |
| 311 } | |
| 312 } | |
| 313 name ??= "#U${unresolvedCount++}"; | |
| 314 unresolvedReversed[name] = argument.name; | |
| 315 freeTypes[name] = argument; | |
| 316 part.add(name); | |
| 317 type.arguments[i] = | |
| 318 new KernelNamedTypeBuilder(name, null, -1, fileUri); | |
| 319 } | |
| 320 signatureParts.add(part); | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 analyzeArguments(type.supertype); | |
| 325 type.mixins.forEach(analyzeArguments); | |
| 326 } | |
| 226 KernelTypeBuilder supertype = type.supertype; | 327 KernelTypeBuilder supertype = type.supertype; |
| 328 List<List<String>> currentSignatureParts = <List<String>>[]; | |
| 329 int currentSignatureCount = 0; | |
| 330 String computeSignature() { | |
| 331 if (freeTypes.isEmpty) return ""; | |
| 332 currentSignatureParts.add(signatureParts[currentSignatureCount++]); | |
| 333 if (currentSignatureParts.any((l) => l.isNotEmpty)) { | |
| 334 return "^${currentSignatureParts.map((l) => l.join('&')).join('^')}"; | |
| 335 } else { | |
| 336 return ""; | |
| 337 } | |
| 338 } | |
| 339 | |
| 340 Map<String, TypeVariableBuilder> computeTypeVariables() { | |
| 341 Map<String, TypeVariableBuilder> variables = | |
| 342 <String, TypeVariableBuilder>{}; | |
| 343 for (List<String> strings in currentSignatureParts) { | |
| 344 for (String name in strings) { | |
| 345 variables[name] ??= addTypeVariable(name, null, -1); | |
| 346 } | |
| 347 } | |
| 348 return variables; | |
| 349 } | |
| 350 | |
| 351 checkArguments(t) { | |
| 352 for (var argument in t.arguments ?? const []) { | |
| 353 if (argument.builder == null && argument.name.startsWith("#")) { | |
| 354 throw "No builder on ${argument.name}"; | |
| 355 } | |
| 356 } | |
| 357 } | |
| 358 | |
| 359 computeSignature(); // This combines the supertype with the first mixin. | |
| 227 for (int i = 0; i < type.mixins.length - 1; i++) { | 360 for (int i = 0; i < type.mixins.length - 1; i++) { |
| 228 supertype = applyMixin(supertype, type.mixins[i], null); | 361 Set<String> supertypeArguments = new Set<String>(); |
| 229 } | 362 for (var part in currentSignatureParts) { |
| 230 return applyMixin(supertype, type.mixins.last, name); | 363 supertypeArguments.addAll(part); |
| 364 } | |
| 365 String signature = computeSignature(); | |
| 366 var variables = computeTypeVariables(); | |
| 367 if (supertypeArguments.isNotEmpty) { | |
| 368 supertype = addNamedType( | |
| 369 supertype.name, | |
| 370 supertypeArguments.map((n) { | |
| 371 var t = addNamedType(n, null, -1)..bind(variables[n]); | |
|
Johnni Winther
2017/05/08 10:05:34
var t = ...
return t;
->
return ...
ahe
2017/05/08 11:13:15
Done.
| |
| 372 return t; | |
| 373 }).toList(), | |
| 374 -1); | |
| 375 } | |
| 376 KernelNamedTypeBuilder mixin = type.mixins[i]; | |
| 377 for (var type in mixin.arguments ?? const []) { | |
| 378 type.bind(variables[type.name]); | |
| 379 } | |
| 380 checkArguments(supertype); | |
| 381 checkArguments(mixin); | |
| 382 supertype = applyMixin(supertype, mixin, signature, | |
| 383 typeVariables: | |
| 384 new List<TypeVariableBuilder>.from(variables.values)); | |
| 385 } | |
| 386 KernelNamedTypeBuilder mixin = type.mixins.last; | |
| 387 | |
| 388 Set<String> supertypeArguments = new Set<String>(); | |
| 389 for (var part in currentSignatureParts) { | |
| 390 supertypeArguments.addAll(part); | |
| 391 } | |
| 392 String signature = name == null ? computeSignature() : ""; | |
| 393 var variables; | |
| 394 if (name == null) { | |
| 395 variables = computeTypeVariables(); | |
| 396 typeVariables = new List<TypeVariableBuilder>.from(variables.values); | |
| 397 if (supertypeArguments.isNotEmpty) { | |
| 398 supertype = addNamedType( | |
| 399 supertype.name, | |
| 400 supertypeArguments.map((n) { | |
| 401 var t = addNamedType(n, null, -1)..bind(variables[n]); | |
| 402 return t; | |
|
Johnni Winther
2017/05/08 10:05:34
Ditto
ahe
2017/05/08 11:13:15
Done.
| |
| 403 }).toList(), | |
| 404 -1); | |
| 405 } | |
| 406 } else { | |
| 407 if (supertypeArguments.isNotEmpty) { | |
| 408 supertype = addNamedType(supertype.name, | |
| 409 supertypeArguments.map((n) => freeTypes[n]).toList(), -1); | |
| 410 } | |
| 411 } | |
| 412 | |
| 413 if (name == null) { | |
| 414 for (var type in mixin.arguments ?? const []) { | |
| 415 type.bind(variables[type.name]); | |
| 416 } | |
| 417 } | |
| 418 checkArguments(supertype); | |
| 419 checkArguments(mixin); | |
| 420 | |
| 421 KernelNamedTypeBuilder t = applyMixin(supertype, mixin, signature, | |
| 422 metadata: metadata, | |
| 423 name: name, | |
| 424 typeVariables: typeVariables, | |
| 425 modifiers: modifiers, | |
| 426 interfaces: interfaces, | |
| 427 charOffset: charOffset); | |
| 428 if (name == null) { | |
| 429 var builder = t.builder; | |
| 430 t = addNamedType( | |
| 431 t.name, freeTypes.keys.map((k) => freeTypes[k]).toList(), -1); | |
| 432 if (builder != null) { | |
| 433 t.bind(builder); | |
| 434 } | |
| 435 } | |
| 436 return t; | |
| 231 } else { | 437 } else { |
| 232 return type; | 438 return type; |
| 233 } | 439 } |
| 234 } | 440 } |
| 235 | 441 |
| 236 void addNamedMixinApplication( | 442 void addNamedMixinApplication( |
| 237 List<MetadataBuilder> metadata, | 443 List<MetadataBuilder> metadata, |
| 238 String name, | 444 String name, |
| 239 List<TypeVariableBuilder> typeVariables, | 445 List<TypeVariableBuilder> typeVariables, |
| 240 int modifiers, | 446 int modifiers, |
| 241 KernelTypeBuilder mixinApplication, | 447 KernelTypeBuilder mixinApplication, |
| 242 List<KernelTypeBuilder> interfaces, | 448 List<KernelTypeBuilder> interfaces, |
| 243 int charOffset) { | 449 int charOffset) { |
| 244 // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`. | 450 // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`. |
| 245 var decl = endNestedDeclaration(); | 451 endNestedDeclaration().resolveTypes(typeVariables, this); |
| 246 KernelTypeBuilder supertype = applyMixins(mixinApplication, name); | 452 KernelNamedTypeBuilder supertype = applyMixins(mixinApplication, |
| 453 metadata: metadata, | |
| 454 name: name, | |
| 455 typeVariables: typeVariables, | |
| 456 modifiers: modifiers, | |
| 457 interfaces: interfaces, | |
| 458 charOffset: charOffset); | |
| 247 checkTypeVariables(typeVariables, supertype.builder); | 459 checkTypeVariables(typeVariables, supertype.builder); |
| 248 decl.resolveTypes(typeVariables, this); | |
| 249 } | 460 } |
| 250 | 461 |
| 251 void addField(List<MetadataBuilder> metadata, int modifiers, | 462 void addField(List<MetadataBuilder> metadata, int modifiers, |
| 252 KernelTypeBuilder type, String name, int charOffset, | 463 KernelTypeBuilder type, String name, int charOffset, |
| 253 {bool hasInitializer}) { | 464 {bool hasInitializer}) { |
| 254 addBuilder( | 465 addBuilder( |
| 255 name, | 466 name, |
| 256 new KernelFieldBuilder( | 467 new KernelFieldBuilder( |
| 257 metadata, type, name, modifiers, this, charOffset, | 468 metadata, type, name, modifiers, this, charOffset, |
| 258 hasInitializer: hasInitializer), | 469 hasInitializer: hasInitializer), |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 627 int count = boundlessTypeVariables.length; | 838 int count = boundlessTypeVariables.length; |
| 628 for (KernelTypeVariableBuilder builder in boundlessTypeVariables) { | 839 for (KernelTypeVariableBuilder builder in boundlessTypeVariables) { |
| 629 builder.finish(this, object); | 840 builder.finish(this, object); |
| 630 } | 841 } |
| 631 boundlessTypeVariables.clear(); | 842 boundlessTypeVariables.clear(); |
| 632 return count; | 843 return count; |
| 633 } | 844 } |
| 634 | 845 |
| 635 @override | 846 @override |
| 636 void includePart(covariant KernelLibraryBuilder part) { | 847 void includePart(covariant KernelLibraryBuilder part) { |
| 848 part.mixinApplicationClasses | |
| 849 .forEach((String name, SourceClassBuilder builder) { | |
| 850 SourceClassBuilder existing = | |
| 851 mixinApplicationClasses.putIfAbsent(name, () => builder); | |
| 852 if (existing != builder) { | |
| 853 part.scope.local.remove(name); | |
| 854 } | |
| 855 }); | |
| 637 super.includePart(part); | 856 super.includePart(part); |
| 638 nativeMethods.addAll(part.nativeMethods); | 857 nativeMethods.addAll(part.nativeMethods); |
| 639 boundlessTypeVariables.addAll(part.boundlessTypeVariables); | 858 boundlessTypeVariables.addAll(part.boundlessTypeVariables); |
| 640 assert(mixinApplicationClasses.isEmpty); | |
| 641 } | 859 } |
| 642 } | 860 } |
| OLD | NEW |