OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 elements.modelx; | 5 library elements.modelx; |
6 | 6 |
7 import '../compiler.dart' show | 7 import '../compiler.dart' show |
8 Compiler; | 8 Compiler; |
9 import '../constants/constant_constructors.dart'; | 9 import '../constants/constant_constructors.dart'; |
10 import '../constants/constructors.dart'; | 10 import '../constants/constructors.dart'; |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 // Marks this element as a native element. | 244 // Marks this element as a native element. |
245 void setNative(String name) { | 245 void setNative(String name) { |
246 _isNative = true; | 246 _isNative = true; |
247 _fixedBackendName = name; | 247 _fixedBackendName = name; |
248 } | 248 } |
249 | 249 |
250 FunctionElement asFunctionElement() => null; | 250 FunctionElement asFunctionElement() => null; |
251 | 251 |
252 bool get isAbstract => modifiers.isAbstract; | 252 bool get isAbstract => modifiers.isAbstract; |
253 | 253 |
254 void diagnose(Element context, DiagnosticListener listener) {} | |
255 | |
256 bool get hasTreeElements => analyzableElement.hasTreeElements; | 254 bool get hasTreeElements => analyzableElement.hasTreeElements; |
257 | 255 |
258 TreeElements get treeElements => analyzableElement.treeElements; | 256 TreeElements get treeElements => analyzableElement.treeElements; |
259 | 257 |
260 AnalyzableElement get analyzableElement { | 258 AnalyzableElement get analyzableElement { |
261 Element element = outermostEnclosingMemberOrTopLevel; | 259 Element element = outermostEnclosingMemberOrTopLevel; |
262 if (element.isAbstractField || element.isPrefix) return element.library; | 260 if (element.isAbstractField || element.isPrefix) return element.library; |
263 return element; | 261 return element; |
264 } | 262 } |
265 | 263 |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
468 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, | 466 WarnOnUseElementX(WrappedMessage this.warning, WrappedMessage this.info, |
469 Element enclosingElement, Element wrappedElement) | 467 Element enclosingElement, Element wrappedElement) |
470 : this.wrappedElement = wrappedElement, | 468 : this.wrappedElement = wrappedElement, |
471 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); | 469 super(wrappedElement.name, ElementKind.WARN_ON_USE, enclosingElement); |
472 | 470 |
473 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { | 471 Element unwrap(DiagnosticListener listener, Spannable usageSpannable) { |
474 var unwrapped = wrappedElement; | 472 var unwrapped = wrappedElement; |
475 if (warning != null) { | 473 if (warning != null) { |
476 Spannable spannable = warning.spannable; | 474 Spannable spannable = warning.spannable; |
477 if (spannable == null) spannable = usageSpannable; | 475 if (spannable == null) spannable = usageSpannable; |
478 listener.reportWarning( | 476 DiagnosticMessage warningMessage = listener.createMessage( |
479 spannable, warning.messageKind, warning.messageArguments); | 477 spannable, warning.messageKind, warning.messageArguments); |
480 } | 478 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
481 if (info != null) { | 479 if (info != null) { |
482 Spannable spannable = info.spannable; | 480 Spannable spannable = info.spannable; |
483 if (spannable == null) spannable = usageSpannable; | 481 if (spannable == null) spannable = usageSpannable; |
484 listener.reportInfo( | 482 infos.add(listener.createMessage( |
485 spannable, info.messageKind, info.messageArguments); | 483 spannable, info.messageKind, info.messageArguments)); |
| 484 } |
| 485 listener.reportWarning(warningMessage, infos); |
486 } | 486 } |
487 if (unwrapped.isWarnOnUse) { | 487 if (unwrapped.isWarnOnUse) { |
488 unwrapped = unwrapped.unwrap(listener, usageSpannable); | 488 unwrapped = unwrapped.unwrap(listener, usageSpannable); |
489 } | 489 } |
490 return unwrapped; | 490 return unwrapped; |
491 } | 491 } |
492 | 492 |
493 accept(ElementVisitor visitor, arg) { | 493 accept(ElementVisitor visitor, arg) { |
494 return visitor.visitWarnOnUseElement(this, arg); | 494 return visitor.visitWarnOnUseElement(this, arg); |
495 } | 495 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
527 var set = new Setlet(); | 527 var set = new Setlet(); |
528 while (element.isAmbiguous) { | 528 while (element.isAmbiguous) { |
529 AmbiguousElement ambiguous = element; | 529 AmbiguousElement ambiguous = element; |
530 set.add(ambiguous.newElement); | 530 set.add(ambiguous.newElement); |
531 element = ambiguous.existingElement; | 531 element = ambiguous.existingElement; |
532 } | 532 } |
533 set.add(element); | 533 set.add(element); |
534 return set; | 534 return set; |
535 } | 535 } |
536 | 536 |
| 537 List<DiagnosticMessage> computeInfos(Element context, |
| 538 DiagnosticListener listener) { |
| 539 return const <DiagnosticMessage>[]; |
| 540 } |
| 541 |
537 accept(ElementVisitor visitor, arg) { | 542 accept(ElementVisitor visitor, arg) { |
538 return visitor.visitAmbiguousElement(this, arg); | 543 return visitor.visitAmbiguousElement(this, arg); |
539 } | 544 } |
540 | 545 |
541 bool get isTopLevel => false; | 546 bool get isTopLevel => false; |
542 | 547 |
543 DynamicType get type => const DynamicType(); | 548 DynamicType get type => const DynamicType(); |
544 } | 549 } |
545 | 550 |
546 /// Element synthesized to diagnose an ambiguous import. | 551 /// Element synthesized to diagnose an ambiguous import. |
547 class AmbiguousImportX extends AmbiguousElementX { | 552 class AmbiguousImportX extends AmbiguousElementX { |
548 AmbiguousImportX( | 553 AmbiguousImportX( |
549 MessageKind messageKind, | 554 MessageKind messageKind, |
550 Map messageArguments, | 555 Map messageArguments, |
551 Element enclosingElement, Element existingElement, Element newElement) | 556 Element enclosingElement, Element existingElement, Element newElement) |
552 : super(messageKind, messageArguments, enclosingElement, existingElement, | 557 : super(messageKind, messageArguments, enclosingElement, existingElement, |
553 newElement); | 558 newElement); |
554 | 559 |
555 void diagnose(Element context, DiagnosticListener listener) { | 560 List<DiagnosticMessage> computeInfos( |
| 561 Element context, |
| 562 DiagnosticListener listener) { |
| 563 List<DiagnosticMessage> infos = <DiagnosticMessage>[]; |
556 Setlet ambiguousElements = flatten(); | 564 Setlet ambiguousElements = flatten(); |
557 MessageKind code = (ambiguousElements.length == 1) | 565 MessageKind code = (ambiguousElements.length == 1) |
558 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; | 566 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; |
559 LibraryElementX importer = context.library; | 567 LibraryElementX importer = context.library; |
560 for (Element element in ambiguousElements) { | 568 for (Element element in ambiguousElements) { |
561 var arguments = {'name': element.name}; | 569 Map arguments = {'name': element.name}; |
562 listener.reportInfo(element, code, arguments); | 570 infos.add(listener.createMessage(element, code, arguments)); |
563 listener.withCurrentElement(importer, () { | 571 listener.withCurrentElement(importer, () { |
564 for (ImportElement import in importer.importers.getImports(element)) { | 572 for (ImportElement import in importer.importers.getImports(element)) { |
565 listener.reportInfo( | 573 infos.add(listener.createMessage( |
566 import, MessageKind.IMPORTED_HERE, arguments); | 574 import, MessageKind.IMPORTED_HERE, arguments)); |
567 } | 575 } |
568 }); | 576 }); |
569 } | 577 } |
| 578 return infos; |
570 } | 579 } |
571 } | 580 } |
572 | 581 |
573 /// Element synthesized to recover from a duplicated member of an element. | 582 /// Element synthesized to recover from a duplicated member of an element. |
574 class DuplicatedElementX extends AmbiguousElementX { | 583 class DuplicatedElementX extends AmbiguousElementX { |
575 DuplicatedElementX( | 584 DuplicatedElementX( |
576 MessageKind messageKind, | 585 MessageKind messageKind, |
577 Map messageArguments, | 586 Map messageArguments, |
578 Element enclosingElement, Element existingElement, Element newElement) | 587 Element enclosingElement, Element existingElement, Element newElement) |
579 : super(messageKind, messageArguments, enclosingElement, existingElement, | 588 : super(messageKind, messageArguments, enclosingElement, existingElement, |
(...skipping 13 matching lines...) Expand all Loading... |
593 } | 602 } |
594 | 603 |
595 void add(Element element, DiagnosticListener listener) { | 604 void add(Element element, DiagnosticListener listener) { |
596 String name = element.name; | 605 String name = element.name; |
597 if (element.isAccessor) { | 606 if (element.isAccessor) { |
598 addAccessor(element, contents[name], listener); | 607 addAccessor(element, contents[name], listener); |
599 } else { | 608 } else { |
600 Element existing = contents.putIfAbsent(name, () => element); | 609 Element existing = contents.putIfAbsent(name, () => element); |
601 if (!identical(existing, element)) { | 610 if (!identical(existing, element)) { |
602 listener.reportError( | 611 listener.reportError( |
603 element, MessageKind.DUPLICATE_DEFINITION, {'name': name}); | 612 listener.createMessage( |
604 listener.reportInfo(existing, | 613 element, |
605 MessageKind.EXISTING_DEFINITION, {'name': name}); | 614 MessageKind.DUPLICATE_DEFINITION, |
| 615 {'name': name}), |
| 616 <DiagnosticMessage>[ |
| 617 listener.createMessage( |
| 618 existing, |
| 619 MessageKind.EXISTING_DEFINITION, |
| 620 {'name': name}), |
| 621 ]); |
606 } | 622 } |
607 } | 623 } |
608 } | 624 } |
609 | 625 |
610 /** | 626 /** |
611 * Adds a definition for an [accessor] (getter or setter) to a scope. | 627 * Adds a definition for an [accessor] (getter or setter) to a scope. |
612 * The definition binds to an abstract field that can hold both a getter | 628 * The definition binds to an abstract field that can hold both a getter |
613 * and a setter. | 629 * and a setter. |
614 * | 630 * |
615 * The abstract field is added once, for the first getter or setter, and | 631 * The abstract field is added once, for the first getter or setter, and |
616 * reused if the other one is also added. | 632 * reused if the other one is also added. |
617 * The abstract field should not be treated as a proper member of the | 633 * The abstract field should not be treated as a proper member of the |
618 * container, it's simply a way to return two results for one lookup. | 634 * container, it's simply a way to return two results for one lookup. |
619 * That is, the getter or setter does not have the abstract field as enclosing | 635 * That is, the getter or setter does not have the abstract field as enclosing |
620 * element, they are enclosed by the class or compilation unit, as is the | 636 * element, they are enclosed by the class or compilation unit, as is the |
621 * abstract field. | 637 * abstract field. |
622 */ | 638 */ |
623 void addAccessor(AccessorElementX accessor, | 639 void addAccessor(AccessorElementX accessor, |
624 Element existing, | 640 Element existing, |
625 DiagnosticListener listener) { | 641 DiagnosticListener listener) { |
626 void reportError(Element other) { | 642 void reportError(Element other) { |
627 listener.reportError(accessor, | 643 listener.reportError( |
628 MessageKind.DUPLICATE_DEFINITION, | 644 listener.createMessage( |
629 {'name': accessor.name}); | 645 accessor, |
630 listener.reportInfo( | 646 MessageKind.DUPLICATE_DEFINITION, |
631 other, MessageKind.EXISTING_DEFINITION, {'name': accessor.name}); | 647 {'name': accessor.name}), |
| 648 <DiagnosticMessage>[ |
| 649 listener.createMessage( |
| 650 other, |
| 651 MessageKind.EXISTING_DEFINITION, |
| 652 {'name': accessor.name}), |
| 653 ]); |
632 | 654 |
633 contents[accessor.name] = new DuplicatedElementX( | 655 contents[accessor.name] = new DuplicatedElementX( |
634 MessageKind.DUPLICATE_DEFINITION, {'name': accessor.name}, | 656 MessageKind.DUPLICATE_DEFINITION, {'name': accessor.name}, |
635 accessor.memberContext.enclosingElement, other, accessor); | 657 accessor.memberContext.enclosingElement, other, accessor); |
636 } | 658 } |
637 | 659 |
638 if (existing != null) { | 660 if (existing != null) { |
639 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { | 661 if (!identical(existing.kind, ElementKind.ABSTRACT_FIELD)) { |
640 reportError(existing); | 662 reportError(existing); |
641 return; | 663 return; |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
715 implementationLibrary.addMember(element, listener); | 737 implementationLibrary.addMember(element, listener); |
716 } else { | 738 } else { |
717 library.addMember(element, listener); | 739 library.addMember(element, listener); |
718 } | 740 } |
719 } | 741 } |
720 | 742 |
721 void setPartOf(PartOf tag, DiagnosticListener listener) { | 743 void setPartOf(PartOf tag, DiagnosticListener listener) { |
722 LibraryElementX library = enclosingElement; | 744 LibraryElementX library = enclosingElement; |
723 if (library.entryCompilationUnit == this) { | 745 if (library.entryCompilationUnit == this) { |
724 partTag = tag; | 746 partTag = tag; |
725 listener.reportError(tag, MessageKind.IMPORT_PART_OF); | 747 listener.reportErrorMessage( |
| 748 tag, MessageKind.IMPORT_PART_OF); |
726 return; | 749 return; |
727 } | 750 } |
728 if (!localMembers.isEmpty) { | 751 if (!localMembers.isEmpty) { |
729 listener.reportError(tag, MessageKind.BEFORE_TOP_LEVEL); | 752 listener.reportErrorMessage( |
| 753 tag, MessageKind.BEFORE_TOP_LEVEL); |
730 return; | 754 return; |
731 } | 755 } |
732 if (partTag != null) { | 756 if (partTag != null) { |
733 listener.reportWarning(tag, MessageKind.DUPLICATED_PART_OF); | 757 listener.reportWarningMessage(tag, MessageKind.DUPLICATED_PART_OF); |
734 return; | 758 return; |
735 } | 759 } |
736 partTag = tag; | 760 partTag = tag; |
737 LibraryName libraryTag = library.libraryTag; | 761 LibraryName libraryTag = library.libraryTag; |
738 String actualName = tag.name.toString(); | 762 String actualName = tag.name.toString(); |
739 if (libraryTag != null) { | 763 if (libraryTag != null) { |
740 String expectedName = libraryTag.name.toString(); | 764 String expectedName = libraryTag.name.toString(); |
741 if (expectedName != actualName) { | 765 if (expectedName != actualName) { |
742 listener.reportWarning(tag.name, | 766 listener.reportWarningMessage( |
| 767 tag.name, |
743 MessageKind.LIBRARY_NAME_MISMATCH, | 768 MessageKind.LIBRARY_NAME_MISMATCH, |
744 {'libraryName': expectedName}); | 769 {'libraryName': expectedName}); |
745 } | 770 } |
746 } else { | 771 } else { |
747 listener.reportWarning(library, | 772 listener.reportWarning( |
748 MessageKind.MISSING_LIBRARY_NAME, | 773 listener.createMessage( |
749 {'libraryName': actualName}); | 774 library, |
750 listener.reportInfo(tag.name, | 775 MessageKind.MISSING_LIBRARY_NAME, |
751 MessageKind.THIS_IS_THE_PART_OF_TAG); | 776 {'libraryName': actualName}), |
| 777 <DiagnosticMessage>[ |
| 778 listener.createMessage( |
| 779 tag.name, |
| 780 MessageKind.THIS_IS_THE_PART_OF_TAG), |
| 781 ]); |
752 } | 782 } |
753 } | 783 } |
754 | 784 |
755 bool get hasMembers => !localMembers.isEmpty; | 785 bool get hasMembers => !localMembers.isEmpty; |
756 | 786 |
757 Element get analyzableElement => library; | 787 Element get analyzableElement => library; |
758 | 788 |
759 accept(ElementVisitor visitor, arg) { | 789 accept(ElementVisitor visitor, arg) { |
760 return visitor.visitCompilationUnitElement(this, arg); | 790 return visitor.visitCompilationUnitElement(this, arg); |
761 } | 791 } |
(...skipping 1854 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2616 bool get hasLocalScopeMembers => !localScope.isEmpty; | 2646 bool get hasLocalScopeMembers => !localScope.isEmpty; |
2617 | 2647 |
2618 void addMember(Element element, DiagnosticListener listener) { | 2648 void addMember(Element element, DiagnosticListener listener) { |
2619 localMembersCache = null; | 2649 localMembersCache = null; |
2620 localMembersReversed = localMembersReversed.prepend(element); | 2650 localMembersReversed = localMembersReversed.prepend(element); |
2621 addToScope(element, listener); | 2651 addToScope(element, listener); |
2622 } | 2652 } |
2623 | 2653 |
2624 void addToScope(Element element, DiagnosticListener listener) { | 2654 void addToScope(Element element, DiagnosticListener listener) { |
2625 if (element.isField && element.name == name) { | 2655 if (element.isField && element.name == name) { |
2626 listener.reportError(element, MessageKind.MEMBER_USES_CLASS_NAME); | 2656 listener.reportErrorMessage( |
| 2657 element, MessageKind.MEMBER_USES_CLASS_NAME); |
2627 } | 2658 } |
2628 localScope.add(element, listener); | 2659 localScope.add(element, listener); |
2629 } | 2660 } |
2630 | 2661 |
2631 Element localLookup(String elementName) { | 2662 Element localLookup(String elementName) { |
2632 Element result = localScope.lookup(elementName); | 2663 Element result = localScope.lookup(elementName); |
2633 if (result == null && isPatch) { | 2664 if (result == null && isPatch) { |
2634 result = origin.localLookup(elementName); | 2665 result = origin.localLookup(elementName); |
2635 } | 2666 } |
2636 return result; | 2667 return result; |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3070 AstElement get definingElement; | 3101 AstElement get definingElement; |
3071 | 3102 |
3072 bool get hasResolvedAst => definingElement.hasTreeElements; | 3103 bool get hasResolvedAst => definingElement.hasTreeElements; |
3073 | 3104 |
3074 ResolvedAst get resolvedAst { | 3105 ResolvedAst get resolvedAst { |
3075 return new ResolvedAst(declaration, | 3106 return new ResolvedAst(declaration, |
3076 definingElement.node, definingElement.treeElements); | 3107 definingElement.node, definingElement.treeElements); |
3077 } | 3108 } |
3078 | 3109 |
3079 } | 3110 } |
OLD | NEW |