| 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 Resolution; | 8 import '../common/resolution.dart' show Resolution; |
| 9 import '../core_types.dart' show CommonElements; | 9 import '../core_types.dart' show CommonElements; |
| 10 import '../elements/resolution_types.dart'; | 10 import '../elements/resolution_types.dart'; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 59 if (nameSet.contains(typeName)) { | 59 if (nameSet.contains(typeName)) { |
| 60 reporter.reportErrorMessage( | 60 reporter.reportErrorMessage( |
| 61 typeNode, | 61 typeNode, |
| 62 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, | 62 MessageKind.DUPLICATE_TYPE_VARIABLE_NAME, |
| 63 {'typeVariableName': typeName}); | 63 {'typeVariableName': typeName}); |
| 64 } | 64 } |
| 65 nameSet.add(typeName); | 65 nameSet.add(typeName); |
| 66 | 66 |
| 67 TypeVariableElementX variableElement = typeVariable.element; | 67 TypeVariableElementX variableElement = typeVariable.element; |
| 68 if (typeNode.bound != null) { | 68 if (typeNode.bound != null) { |
| 69 ResolutionDartType boundType = typeResolver | 69 ResolutionDartType boundType = |
| 70 .resolveNominalTypeAnnotation(this, typeNode.bound, const []); | 70 typeResolver.resolveTypeAnnotation(this, typeNode.bound); |
| 71 variableElement.boundCache = boundType; | 71 variableElement.boundCache = boundType; |
| 72 | 72 |
| 73 void checkTypeVariableBound() { | 73 void checkTypeVariableBound() { |
| 74 Link<TypeVariableElement> seenTypeVariables = | 74 Link<TypeVariableElement> seenTypeVariables = |
| 75 const Link<TypeVariableElement>(); | 75 const Link<TypeVariableElement>(); |
| 76 seenTypeVariables = seenTypeVariables.prepend(variableElement); | 76 seenTypeVariables = seenTypeVariables.prepend(variableElement); |
| 77 ResolutionDartType bound = boundType; | 77 ResolutionDartType bound = boundType; |
| 78 while (bound.isTypeVariable) { | 78 while (bound.isTypeVariable) { |
| 79 TypeVariableElement element = bound.element; | 79 TypeVariableElement element = bound.element; |
| 80 if (seenTypeVariables.contains(element)) { | 80 if (seenTypeVariables.contains(element)) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 } | 244 } |
| 245 | 245 |
| 246 EnumCreator creator = | 246 EnumCreator creator = |
| 247 new EnumCreator(reporter, resolution.commonElements, element); | 247 new EnumCreator(reporter, resolution.commonElements, element); |
| 248 creator.createMembers(); | 248 creator.createMembers(); |
| 249 return enumType; | 249 return enumType; |
| 250 } | 250 } |
| 251 | 251 |
| 252 /// Resolves the mixed type for [mixinNode] and checks that the mixin type | 252 /// Resolves the mixed type for [mixinNode] and checks that the mixin type |
| 253 /// is a valid, non-blacklisted interface type. The mixin type is returned. | 253 /// is a valid, non-blacklisted interface type. The mixin type is returned. |
| 254 ResolutionDartType checkMixinType(NominalTypeAnnotation mixinNode) { | 254 ResolutionDartType checkMixinType(TypeAnnotation mixinNode) { |
| 255 ResolutionDartType mixinType = resolveNominalType(mixinNode); | 255 ResolutionDartType mixinType = resolveType(mixinNode); |
| 256 if (isBlackListed(mixinType)) { | 256 if (isBlackListed(mixinType)) { |
| 257 reporter.reportErrorMessage( | 257 reporter.reportErrorMessage( |
| 258 mixinNode, MessageKind.CANNOT_MIXIN, {'type': mixinType}); | 258 mixinNode, MessageKind.CANNOT_MIXIN, {'type': mixinType}); |
| 259 } else if (mixinType.isTypeVariable) { | 259 } else if (mixinType.isTypeVariable) { |
| 260 reporter.reportErrorMessage(mixinNode, MessageKind.CLASS_NAME_EXPECTED); | 260 reporter.reportErrorMessage(mixinNode, MessageKind.CLASS_NAME_EXPECTED); |
| 261 } else if (mixinType.isMalformed) { | 261 } else if (mixinType.isMalformed) { |
| 262 reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, | 262 reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_MALFORMED, |
| 263 {'className': element.name, 'malformedType': mixinType}); | 263 {'className': element.name, 'malformedType': mixinType}); |
| 264 } else if (mixinType.isEnumType) { | 264 } else if (mixinType.isEnumType) { |
| 265 reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_ENUM, | 265 reporter.reportErrorMessage(mixinNode, MessageKind.CANNOT_MIXIN_ENUM, |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 // the mixin for this application to avoid getting into | 434 // the mixin for this application to avoid getting into |
| 435 // infinite recursion when traversing members. | 435 // infinite recursion when traversing members. |
| 436 return null; | 436 return null; |
| 437 } | 437 } |
| 438 previous = current; | 438 previous = current; |
| 439 current = currentMixinApplication.mixin; | 439 current = currentMixinApplication.mixin; |
| 440 } | 440 } |
| 441 return mixinType; | 441 return mixinType; |
| 442 } | 442 } |
| 443 | 443 |
| 444 ResolutionDartType resolveNominalType(NominalTypeAnnotation node) { | 444 ResolutionDartType resolveType(TypeAnnotation node) { |
| 445 return typeResolver.resolveNominalTypeAnnotation(this, node, const []); | 445 return typeResolver.resolveTypeAnnotation(this, node); |
| 446 } | 446 } |
| 447 | 447 |
| 448 ResolutionDartType resolveSupertype( | 448 ResolutionDartType resolveSupertype( |
| 449 ClassElement cls, NominalTypeAnnotation superclass) { | 449 ClassElement cls, TypeAnnotation superclass) { |
| 450 ResolutionDartType supertype = resolveNominalType(superclass); | 450 ResolutionDartType supertype = resolveType(superclass); |
| 451 if (supertype != null) { | 451 if (supertype != null) { |
| 452 if (supertype.isMalformed) { | 452 if (supertype.isMalformed) { |
| 453 reporter.reportErrorMessage( | 453 reporter.reportErrorMessage( |
| 454 superclass, | 454 superclass, |
| 455 MessageKind.CANNOT_EXTEND_MALFORMED, | 455 MessageKind.CANNOT_EXTEND_MALFORMED, |
| 456 {'className': element.name, 'malformedType': supertype}); | 456 {'className': element.name, 'malformedType': supertype}); |
| 457 return objectType; | 457 return objectType; |
| 458 } else if (supertype.isEnumType) { | 458 } else if (supertype.isEnumType) { |
| 459 reporter.reportErrorMessage(superclass, MessageKind.CANNOT_EXTEND_ENUM, | 459 reporter.reportErrorMessage(superclass, MessageKind.CANNOT_EXTEND_ENUM, |
| 460 {'className': element.name, 'enumType': supertype}); | 460 {'className': element.name, 'enumType': supertype}); |
| 461 return objectType; | 461 return objectType; |
| 462 } else if (!supertype.isInterfaceType) { | 462 } else if (!supertype.isInterfaceType) { |
| 463 reporter.reportErrorMessage( | 463 reporter.reportErrorMessage( |
| 464 superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); | 464 superclass.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 465 return objectType; | 465 return objectType; |
| 466 } else if (isBlackListed(supertype)) { | 466 } else if (isBlackListed(supertype)) { |
| 467 reporter.reportErrorMessage( | 467 reporter.reportErrorMessage( |
| 468 superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); | 468 superclass, MessageKind.CANNOT_EXTEND, {'type': supertype}); |
| 469 return objectType; | 469 return objectType; |
| 470 } | 470 } |
| 471 } | 471 } |
| 472 return supertype; | 472 return supertype; |
| 473 } | 473 } |
| 474 | 474 |
| 475 Link<ResolutionDartType> resolveInterfaces( | 475 Link<ResolutionDartType> resolveInterfaces( |
| 476 NodeList interfaces, Node superclass) { | 476 NodeList interfaces, Node superclass) { |
| 477 Link<ResolutionDartType> result = const Link<ResolutionDartType>(); | 477 Link<ResolutionDartType> result = const Link<ResolutionDartType>(); |
| 478 if (interfaces == null) return result; | 478 if (interfaces == null) return result; |
| 479 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { | 479 for (Link<Node> link = interfaces.nodes; !link.isEmpty; link = link.tail) { |
| 480 ResolutionDartType interfaceType = resolveNominalType(link.head); | 480 ResolutionDartType interfaceType = resolveType(link.head); |
| 481 if (interfaceType != null) { | 481 if (interfaceType != null) { |
| 482 if (interfaceType.isMalformed) { | 482 if (interfaceType.isMalformed) { |
| 483 reporter.reportErrorMessage( | 483 reporter.reportErrorMessage( |
| 484 link.head, | 484 link.head, |
| 485 MessageKind.CANNOT_IMPLEMENT_MALFORMED, | 485 MessageKind.CANNOT_IMPLEMENT_MALFORMED, |
| 486 {'className': element.name, 'malformedType': interfaceType}); | 486 {'className': element.name, 'malformedType': interfaceType}); |
| 487 } else if (interfaceType.isEnumType) { | 487 } else if (interfaceType.isEnumType) { |
| 488 reporter.reportErrorMessage( | 488 reporter.reportErrorMessage( |
| 489 link.head, | 489 link.head, |
| 490 MessageKind.CANNOT_IMPLEMENT_ENUM, | 490 MessageKind.CANNOT_IMPLEMENT_ENUM, |
| 491 {'className': element.name, 'enumType': interfaceType}); | 491 {'className': element.name, 'enumType': interfaceType}); |
| 492 } else if (!interfaceType.isInterfaceType) { | 492 } else if (!interfaceType.isInterfaceType) { |
| 493 // TODO(johnniwinther): Handle dynamic. | 493 // TODO(johnniwinther): Handle dynamic. |
| 494 NominalTypeAnnotation typeAnnotation = link.head; | 494 TypeAnnotation typeAnnotation = link.head; |
| 495 reporter.reportErrorMessage( | 495 reporter.reportErrorMessage( |
| 496 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); | 496 typeAnnotation.typeName, MessageKind.CLASS_NAME_EXPECTED); |
| 497 } else { | 497 } else { |
| 498 if (interfaceType == element.supertype) { | 498 if (interfaceType == element.supertype) { |
| 499 reporter.reportErrorMessage( | 499 reporter.reportErrorMessage( |
| 500 superclass, | 500 superclass, |
| 501 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, | 501 MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS, |
| 502 {'type': interfaceType}); | 502 {'type': interfaceType}); |
| 503 reporter.reportErrorMessage( | 503 reporter.reportErrorMessage( |
| 504 link.head, | 504 link.head, |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 node.superclass.accept(this); | 609 node.superclass.accept(this); |
| 610 visitNodeList(node.mixins); | 610 visitNodeList(node.mixins); |
| 611 } | 611 } |
| 612 | 612 |
| 613 void visitNamedMixinApplication(NamedMixinApplication node) { | 613 void visitNamedMixinApplication(NamedMixinApplication node) { |
| 614 node.superclass.accept(this); | 614 node.superclass.accept(this); |
| 615 visitNodeList(node.mixins); | 615 visitNodeList(node.mixins); |
| 616 visitNodeList(node.interfaces); | 616 visitNodeList(node.interfaces); |
| 617 } | 617 } |
| 618 | 618 |
| 619 void visitNominalTypeAnnotation(NominalTypeAnnotation node) { | 619 void visitTypeAnnotation(TypeAnnotation node) { |
| 620 node.typeName.accept(this); | 620 node.typeName.accept(this); |
| 621 } | 621 } |
| 622 | 622 |
| 623 void visitIdentifier(Identifier node) { | 623 void visitIdentifier(Identifier node) { |
| 624 Element element = lookupInScope(reporter, node, context, node.source); | 624 Element element = lookupInScope(reporter, node, context, node.source); |
| 625 if (element != null && element.isClass) { | 625 if (element != null && element.isClass) { |
| 626 loadSupertype(element, node); | 626 loadSupertype(element, node); |
| 627 } | 627 } |
| 628 } | 628 } |
| 629 | 629 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 644 Identifier selector = node.selector.asIdentifier(); | 644 Identifier selector = node.selector.asIdentifier(); |
| 645 var e = prefixElement.lookupLocalMember(selector.source); | 645 var e = prefixElement.lookupLocalMember(selector.source); |
| 646 if (e == null || !e.impliesType) { | 646 if (e == null || !e.impliesType) { |
| 647 reporter.reportErrorMessage(node.selector, | 647 reporter.reportErrorMessage(node.selector, |
| 648 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); | 648 MessageKind.CANNOT_RESOLVE_TYPE, {'typeName': node.selector}); |
| 649 return; | 649 return; |
| 650 } | 650 } |
| 651 loadSupertype(e, node); | 651 loadSupertype(e, node); |
| 652 } | 652 } |
| 653 } | 653 } |
| OLD | NEW |