| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 dart2js.resolution.class_hierarchy; | 5 library dart2js.resolution.class_hierarchy; |
| 6 | 6 |
| 7 import '../common.dart'; | 7 import '../common.dart'; |
| 8 import '../common/resolution.dart' show Feature; | 8 import '../common/resolution.dart' show Feature; |
| 9 import '../compiler.dart' show Compiler; | 9 import '../compiler.dart' show Compiler; |
| 10 import '../core_types.dart' show CoreClasses, CoreTypes; | 10 import '../core_types.dart' show CoreClasses, CoreTypes; |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 resolveTypeVariableBounds(node.typeParameters); | 289 resolveTypeVariableBounds(node.typeParameters); |
| 290 | 290 |
| 291 // Generate anonymous mixin application elements for the | 291 // Generate anonymous mixin application elements for the |
| 292 // intermediate mixin applications (excluding the last). | 292 // intermediate mixin applications (excluding the last). |
| 293 DartType supertype = resolveSupertype(element, node.superclass); | 293 DartType supertype = resolveSupertype(element, node.superclass); |
| 294 Link<Node> link = node.mixins.nodes; | 294 Link<Node> link = node.mixins.nodes; |
| 295 while (!link.tail.isEmpty) { | 295 while (!link.tail.isEmpty) { |
| 296 supertype = applyMixin(supertype, checkMixinType(link.head), link.head); | 296 supertype = applyMixin(supertype, checkMixinType(link.head), link.head); |
| 297 link = link.tail; | 297 link = link.tail; |
| 298 } | 298 } |
| 299 doApplyMixinTo(element, supertype, checkMixinType(link.head)); | 299 element.supertype = applyMixin(supertype, checkMixinType(link.head), node); |
| 300 element.interfaces = |
| 301 resolveInterfaces(element, node.interfaces, node.interfaces); |
| 302 calculateAllSupertypes(element); |
| 303 |
| 304 element.superclass.forEachLocalMember((Element member) { |
| 305 if (!member.isGenerativeConstructor) return; |
| 306 FunctionElement forwarder = createForwardingConstructor(member, element); |
| 307 if (Name.isPrivateName(member.name) && |
| 308 element.library != superclass.library) { |
| 309 // Do not create a forwarder to the super constructor, because the mixin |
| 310 // application is in a different library than the constructor in the |
| 311 // super class and it is not possible to call that constructor from the |
| 312 // library using the mixin application. |
| 313 return; |
| 314 } |
| 315 element.addConstructor(forwarder); |
| 316 }); |
| 317 |
| 300 return element.computeType(resolution); | 318 return element.computeType(resolution); |
| 301 } | 319 } |
| 302 | 320 |
| 321 /// Returns the this-type of the new class (mixin application) that is the |
| 322 /// result of applying [mixinType] to [supertype]. The mixin application is |
| 323 /// also created. |
| 324 /// |
| 325 /// The returned type has new synthetic type variables corresponding to the |
| 326 /// type variables of [mixinType] *and* the type variables of [element]. For |
| 327 /// example, given: |
| 328 /// |
| 329 /// class Mixin<M> {} |
| 330 /// class C<T> extends Object with M<int> {} |
| 331 /// |
| 332 /// The returned type will have the following type variables: |
| 333 /// |
| 334 /// <M, T> |
| 335 /// |
| 336 /// Notice that the first type variables correspond to the type variables of |
| 337 /// `Mixin`, which allows us to create a scope where we can look them up |
| 338 /// later. |
| 303 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { | 339 DartType applyMixin(DartType supertype, DartType mixinType, Node node) { |
| 340 if (!supertype.isInterfaceType || !mixinType.isInterfaceType) { |
| 341 element.hasIncompleteHierarchy = true; |
| 342 return objectType; |
| 343 } |
| 304 String superName = supertype.name; | 344 String superName = supertype.name; |
| 305 String mixinName = mixinType.name; | 345 String mixinName = mixinType.name; |
| 346 List<DartType> originalTypeParameters = new List<DartType>() |
| 347 ..addAll(mixinType.element.typeVariables) |
| 348 ..addAll(element.typeVariables); |
| 349 List<DartType> typeArguments = new List<DartType>() |
| 350 ..addAll(mixinType.typeArguments) |
| 351 ..addAll(element.typeVariables); |
| 306 MixinApplicationElementX mixinApplication = | 352 MixinApplicationElementX mixinApplication = |
| 307 new UnnamedMixinApplicationElementX("${superName}+${mixinName}", | 353 new UnnamedMixinApplicationElementX("${superName}+${mixinName}", |
| 308 element.compilationUnit, compiler.getNextFreeId(), node); | 354 element.compilationUnit, compiler.getNextFreeId(), node); |
| 309 // Create synthetic type variables for the mixin application. | 355 // Create synthetic type variables for the mixin application. |
| 310 List<DartType> typeVariables = <DartType>[]; | 356 List<DartType> typeVariables = <DartType>[]; |
| 311 int index = 0; | 357 int index = 0; |
| 312 for (TypeVariableType type in element.typeVariables) { | 358 for (TypeVariableType type in originalTypeParameters) { |
| 313 TypeVariableElementX typeVariableElement = new TypeVariableElementX( | 359 TypeVariableElementX typeVariableElement = new TypeVariableElementX( |
| 314 type.name, mixinApplication, index, type.element.node); | 360 type.name, mixinApplication, index, type.element.node); |
| 315 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); | 361 TypeVariableType typeVariable = new TypeVariableType(typeVariableElement); |
| 316 typeVariables.add(typeVariable); | 362 typeVariables.add(typeVariable); |
| 317 index++; | 363 index++; |
| 318 } | 364 } |
| 319 // Setup bounds on the synthetic type variables. | 365 // Setup bounds on the synthetic type variables. |
| 320 for (TypeVariableType type in element.typeVariables) { | 366 index = 0; |
| 321 TypeVariableType typeVariable = typeVariables[type.element.index]; | 367 for (TypeVariableType type in originalTypeParameters) { |
| 368 TypeVariableType typeVariable = typeVariables[index]; |
| 322 TypeVariableElementX typeVariableElement = typeVariable.element; | 369 TypeVariableElementX typeVariableElement = typeVariable.element; |
| 323 typeVariableElement.typeCache = typeVariable; | 370 typeVariableElement.typeCache = typeVariable; |
| 324 typeVariableElement.boundCache = | 371 typeVariableElement.boundCache = |
| 325 type.element.bound.subst(typeVariables, element.typeVariables); | 372 type.element.bound.subst(typeVariables, originalTypeParameters); |
| 373 index++; |
| 326 } | 374 } |
| 327 // Setup this and raw type for the mixin application. | 375 // Setup this and raw type for the mixin application. |
| 328 mixinApplication.computeThisAndRawType(resolution, typeVariables); | 376 mixinApplication.computeThisAndRawType(resolution, typeVariables); |
| 329 // Substitute in synthetic type variables in super and mixin types. | 377 // Substitute in synthetic type variables in super and mixin types. |
| 330 supertype = supertype.subst(typeVariables, element.typeVariables); | 378 supertype = supertype.subst(typeVariables, originalTypeParameters); |
| 331 mixinType = mixinType.subst(typeVariables, element.typeVariables); | 379 mixinType = mixinType.subst(typeVariables, originalTypeParameters); |
| 332 | 380 |
| 333 doApplyMixinTo(mixinApplication, supertype, mixinType); | 381 doApplyMixinTo(mixinApplication, supertype, mixinType); |
| 334 mixinApplication.resolutionState = STATE_DONE; | 382 mixinApplication.resolutionState = STATE_DONE; |
| 335 mixinApplication.supertypeLoadState = STATE_DONE; | 383 mixinApplication.supertypeLoadState = STATE_DONE; |
| 336 // Replace the synthetic type variables by the original type variables in | 384 // Replace the synthetic type variables by the original type variables in |
| 337 // the returned type (which should be the type actually extended). | 385 // the returned type (which should be the type actually extended). |
| 338 InterfaceType mixinThisType = mixinApplication.thisType; | 386 InterfaceType mixinThisType = mixinApplication.thisType; |
| 339 return mixinThisType.subst( | 387 return mixinThisType.subst(typeArguments, mixinThisType.typeArguments); |
| 340 element.typeVariables, mixinThisType.typeArguments); | |
| 341 } | 388 } |
| 342 | 389 |
| 343 bool isDefaultConstructor(FunctionElement constructor) { | 390 bool isDefaultConstructor(FunctionElement constructor) { |
| 344 if (constructor.name != '') return false; | 391 if (constructor.name != '') return false; |
| 345 constructor.computeType(resolution); | 392 constructor.computeType(resolution); |
| 346 return constructor.functionSignature.parameterCount == 0; | 393 return constructor.functionSignature.parameterCount == 0; |
| 347 } | 394 } |
| 348 | 395 |
| 349 FunctionElement createForwardingConstructor( | 396 FunctionElement createForwardingConstructor( |
| 350 ConstructorElement target, ClassElement enclosing) { | 397 ConstructorElement target, ClassElement enclosing) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 if (Name.isPrivateName(member.name) && | 456 if (Name.isPrivateName(member.name) && |
| 410 mixinApplication.library != superclass.library) { | 457 mixinApplication.library != superclass.library) { |
| 411 // Do not create a forwarder to the super constructor, because the mixin | 458 // Do not create a forwarder to the super constructor, because the mixin |
| 412 // application is in a different library than the constructor in the | 459 // application is in a different library than the constructor in the |
| 413 // super class and it is not possible to call that constructor from the | 460 // super class and it is not possible to call that constructor from the |
| 414 // library using the mixin application. | 461 // library using the mixin application. |
| 415 return; | 462 return; |
| 416 } | 463 } |
| 417 mixinApplication.addConstructor(forwarder); | 464 mixinApplication.addConstructor(forwarder); |
| 418 }); | 465 }); |
| 466 |
| 467 ClassElement mixin = mixinType.element; |
| 468 mixin.forEachLocalMember((Element member) { |
| 469 if (member.isGenerativeConstructor) return; |
| 470 if (!member.isInstanceMember) return; |
| 471 mixinApplication.addMember( |
| 472 member.copyWithEnclosing(mixinApplication), null); |
| 473 }); |
| 474 |
| 419 calculateAllSupertypes(mixinApplication); | 475 calculateAllSupertypes(mixinApplication); |
| 420 } | 476 } |
| 421 | 477 |
| 422 InterfaceType resolveMixinFor( | 478 InterfaceType resolveMixinFor( |
| 423 MixinApplicationElement mixinApplication, DartType mixinType) { | 479 MixinApplicationElement mixinApplication, DartType mixinType) { |
| 424 ClassElement mixin = mixinType.element; | 480 ClassElement mixin = mixinType.element; |
| 425 mixin.ensureResolved(resolution); | 481 mixin.ensureResolved(resolution); |
| 426 | 482 |
| 427 // Check for cycles in the mixin chain. | 483 // Check for cycles in the mixin chain. |
| 428 ClassElement previous = mixinApplication; // For better error messages. | 484 ClassElement previous = mixinApplication; // For better error messages. |
| (...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 Identifier selector = node.selector.asIdentifier(); | 716 Identifier selector = node.selector.asIdentifier(); |
| 661 var e = prefixElement.lookupLocalMember(selector.source); | 717 var e = prefixElement.lookupLocalMember(selector.source); |
| 662 if (e == null || !e.impliesType) { | 718 if (e == null || !e.impliesType) { |
| 663 reporter.reportErrorMessage(node.selector, | 719 reporter.reportErrorMessage(node.selector, |
| 664 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); | 720 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); |
| 665 return; | 721 return; |
| 666 } | 722 } |
| 667 loadSupertype(e, node); | 723 loadSupertype(e, node); |
| 668 } | 724 } |
| 669 } | 725 } |
| OLD | NEW |