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