Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(460)

Side by Side Diff: lib/compiler/implementation/elements/elements.dart

Issue 10990060: Added support for exports and re-exports. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Status updated. Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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'); 5 #library('elements');
6 6
7 #import('dart:uri'); 7 #import('dart:uri');
8 8
9 // TODO(ahe): Rename prefix to 'api' when VM bug is fixed. 9 // TODO(ahe): Rename prefix to 'api' when VM bug is fixed.
10 #import('../../compiler.dart', prefix: 'api_e'); 10 #import('../../compiler.dart', prefix: 'api_e');
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 static const ElementKind TYPEDEF = 97 static const ElementKind TYPEDEF =
98 const ElementKind('typedef', ElementCategory.ALIAS); 98 const ElementKind('typedef', ElementCategory.ALIAS);
99 99
100 static const ElementKind STATEMENT = 100 static const ElementKind STATEMENT =
101 const ElementKind('statement', ElementCategory.NONE); 101 const ElementKind('statement', ElementCategory.NONE);
102 static const ElementKind LABEL = 102 static const ElementKind LABEL =
103 const ElementKind('label', ElementCategory.NONE); 103 const ElementKind('label', ElementCategory.NONE);
104 static const ElementKind VOID = 104 static const ElementKind VOID =
105 const ElementKind('void', ElementCategory.NONE); 105 const ElementKind('void', ElementCategory.NONE);
106 106
107 static const ElementKind ERROR =
108 const ElementKind('error', ElementCategory.NONE);
109
107 toString() => id; 110 toString() => id;
108 } 111 }
109 112
110 class Element implements Spannable { 113 class Element implements Spannable {
111 final SourceString name; 114 final SourceString name;
112 final ElementKind kind; 115 final ElementKind kind;
113 final Element enclosingElement; 116 final Element enclosingElement;
114 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>(); 117 Link<MetadataAnnotation> metadata = const EmptyLink<MetadataAnnotation>();
115 118
116 Element(this.name, this.kind, this.enclosingElement) { 119 Element(this.name, this.kind, this.enclosingElement) {
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 * to check for unresolvable elements instead of 354 * to check for unresolvable elements instead of
352 * [: element == null :]. 355 * [: element == null :].
353 */ 356 */
354 class ErroneousElement extends Element { 357 class ErroneousElement extends Element {
355 final MessageKind messageKind; 358 final MessageKind messageKind;
356 final List messageArguments; 359 final List messageArguments;
357 final SourceString targetName; 360 final SourceString targetName;
358 361
359 ErroneousElement(this.messageKind, this.messageArguments, 362 ErroneousElement(this.messageKind, this.messageArguments,
360 this.targetName, Element enclosing) 363 this.targetName, Element enclosing)
361 : super(const SourceString('erroneous element'), null, enclosing); 364 : super(const SourceString('erroneous element'),
365 ElementKind.ERROR, enclosing);
362 366
363 isErroneous() => true; 367 isErroneous() => true;
364 368
365 unsupported() { 369 unsupported() {
366 throw 'unsupported operation on erroneous element'; 370 throw 'unsupported operation on erroneous element';
367 } 371 }
368 372
369 SourceString get name => unsupported(); 373 SourceString get name => unsupported();
370 ElementKind get kind => unsupported();
371 Link<MetadataAnnotation> get metadata => unsupported(); 374 Link<MetadataAnnotation> get metadata => unsupported();
372 375
373 getLibrary() => enclosingElement.getLibrary(); 376 getLibrary() => enclosingElement.getLibrary();
374 } 377 }
375 378
376 class ErroneousFunctionElement extends ErroneousElement 379 class ErroneousFunctionElement extends ErroneousElement
377 implements FunctionElement { 380 implements FunctionElement {
378 ErroneousFunctionElement(MessageKind messageKind, List messageArguments, 381 ErroneousFunctionElement(MessageKind messageKind, List messageArguments,
379 SourceString targetName, Element enclosing) 382 SourceString targetName, Element enclosing)
380 : super(messageKind, messageArguments, targetName, enclosing); 383 : super(messageKind, messageArguments, targetName, enclosing);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 final LibraryElement origin; 581 final LibraryElement origin;
579 582
580 /** 583 /**
581 * Map for elements imported through import declarations. 584 * Map for elements imported through import declarations.
582 * 585 *
583 * Addition to the map is performed by [addImport]. Lookup is done trough 586 * Addition to the map is performed by [addImport]. Lookup is done trough
584 * [find]. 587 * [find].
585 */ 588 */
586 final Map<SourceString, Element> importScope; 589 final Map<SourceString, Element> importScope;
587 590
591 /**
592 * Link for elements exported either through export declarations or through
593 * declaration.
594 *
595 * [LibraryDependencyHandler] sets this map when the library is loaded.
Lasse Reichstein Nielsen 2012/10/10 08:07:33 It's the classic set-once pattern. I would prefer
Johnni Winther 2012/10/10 09:20:59 Done.
596 */
597 Link<Element> _exports;
598
588 LibraryElement(Script script, [Uri uri, LibraryElement this.origin]) 599 LibraryElement(Script script, [Uri uri, LibraryElement this.origin])
589 : this.uri = ((uri === null) ? script.uri : uri), 600 : this.uri = ((uri === null) ? script.uri : uri),
590 importScope = new Map<SourceString, Element>(), 601 importScope = new Map<SourceString, Element>(),
591 super(new SourceString(script.name), ElementKind.LIBRARY, null) { 602 super(new SourceString(script.name), ElementKind.LIBRARY, null) {
592 entryCompilationUnit = new CompilationUnitElement(script, this); 603 entryCompilationUnit = new CompilationUnitElement(script, this);
593 if (isPatch) { 604 if (isPatch) {
594 origin.patch = this; 605 origin.patch = this;
595 } 606 }
596 } 607 }
597 608
(...skipping 12 matching lines...) Expand all
610 } 621 }
611 622
612 /** 623 /**
613 * Adds [element] to the import scope of this library. 624 * Adds [element] to the import scope of this library.
614 * 625 *
615 * If an element by the same name is already in the imported scope, an 626 * If an element by the same name is already in the imported scope, an
616 * [ErroneousElement] will be put in the imported scope, allowing for the 627 * [ErroneousElement] will be put in the imported scope, allowing for the
617 * detection of ambiguous uses of imported names. 628 * detection of ambiguous uses of imported names.
618 */ 629 */
619 void addImport(Element element, DiagnosticListener listener) { 630 void addImport(Element element, DiagnosticListener listener) {
620 Element existing = importScope.putIfAbsent(element.name, () => element); 631 Element existing = importScope[element.name];
621 if (existing !== element && existing !== null) { 632 if (existing !== null) {
622 if (!existing.isErroneous()) { 633 if (!existing.isErroneous()) {
623 // TODO(johnniwinther): Provide access to both the new and existing 634 // TODO(johnniwinther): Provide access to both the new and existing
624 // elements. 635 // elements.
625 importScope[element.name] = new ErroneousElement( 636 importScope[element.name] = new ErroneousElement(
626 MessageKind.DUPLICATE_IMPORT, 637 MessageKind.DUPLICATE_IMPORT,
627 [element.name], element.name, this); 638 [element.name], element.name, this);
628 } 639 }
640 } else {
641 importScope[element.name] = element;
629 } 642 }
630 } 643 }
631 644
645 /**
646 * Returns [:true:] if the export scope has already been computed for this
647 * library.
648 */
649 bool get exportsHandled => _exports !== null;
650
651 Link<Element> get exports {
652 assert(invariant(this, exportsHandled,
653 message: 'Exports not handled on $this'));
654 return _exports;
655 }
656
657 /**
658 * Sets the export scope of this library. This method can only be called once.
659 */
660 void setExports(Iterable<Element> iterable) {
Lasse Reichstein Nielsen 2012/10/10 08:07:33 'iterable' -> 'exportedElements'. Name for the mea
Johnni Winther 2012/10/10 09:20:59 Done.
661 assert(invariant(this, !exportsHandled,
662 message: 'Exports already set to $_exports on $this'));
663 assert(invariant(this, iterable !== null));
664 var builder = new LinkBuilder<Element>();
665 for (Element export in iterable) {
666 builder.addLast(export);
667 }
668 _exports = builder.toLink();
669 }
670
632 LibraryElement getLibrary() => isPatch ? origin : this; 671 LibraryElement getLibrary() => isPatch ? origin : this;
633 672
634 /** 673 /**
635 * Look up a top-level element in this library. The element could 674 * Look up a top-level element in this library. The element could
636 * potentially have been imported from another library. Returns 675 * potentially have been imported from another library. Returns
637 * null if no such element exist and an [ErroneousElement] if multiple 676 * null if no such element exist and an [ErroneousElement] if multiple
638 * elements have been imported. 677 * elements have been imported.
639 */ 678 */
640 Element find(SourceString elementName) { 679 Element find(SourceString elementName) {
641 Element result = localScope[elementName]; 680 Element result = localScope[elementName];
642 if (result === null) { 681 if (result === null) {
643 result = importScope[elementName]; 682 result = importScope[elementName];
644 } 683 }
645 return result; 684 return result;
646 } 685 }
647 686
648 /** Look up a top-level element in this library, but only look for 687 /** Look up a top-level element in this library, but only look for
649 * non-imported elements. Returns null if no such element exist. */ 688 * non-imported elements. Returns null if no such element exist. */
650 Element findLocal(SourceString elementName) { 689 Element findLocal(SourceString elementName) {
651 // TODO(johnniwinther): How to handle injected elements in the patch 690 // TODO(johnniwinther): How to handle injected elements in the patch
652 // library? 691 // library?
653 Element result = localScope[elementName]; 692 Element result = localScope[elementName];
654 if (result === null || result.getLibrary() != this) return null; 693 if (result === null || result.getLibrary() != this) return null;
655 return result; 694 return result;
656 } 695 }
657 696
658 void forEachExport(f(Element element)) { 697 void forEachExport(f(Element element)) {
659 localScope.forEach((_, Element e) { 698 exports.forEach((Element e) => f(e));
660 if (this === e.getLibrary()
661 && e.kind !== ElementKind.PREFIX
662 && e.kind !== ElementKind.FOREIGN
663 && !e.name.isPrivate()) {
664 f(e);
665 }
666 });
667 } 699 }
668 700
669 void forEachLocalMember(f(Element element)) { 701 void forEachLocalMember(f(Element element)) {
670 if (isPatch) { 702 if (isPatch) {
671 // Patch libraries traverse both origin and injected members. 703 // Patch libraries traverse both origin and injected members.
672 origin.localMembers.forEach(f); 704 origin.localMembers.forEach(f);
673 705
674 void filterPatch(Element element) { 706 void filterPatch(Element element) {
675 if (!element.isPatch) { 707 if (!element.isPatch) {
676 // Do not traverse the patch members. 708 // Do not traverse the patch members.
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1913 1945
1914 MetadataAnnotation ensureResolved(Compiler compiler) { 1946 MetadataAnnotation ensureResolved(Compiler compiler) {
1915 if (resolutionState == STATE_NOT_STARTED) { 1947 if (resolutionState == STATE_NOT_STARTED) {
1916 compiler.resolver.resolveMetadataAnnotation(this); 1948 compiler.resolver.resolveMetadataAnnotation(this);
1917 } 1949 }
1918 return this; 1950 return this;
1919 } 1951 }
1920 1952
1921 String toString() => 'MetadataAnnotation($value, $resolutionState)'; 1953 String toString() => 'MetadataAnnotation($value, $resolutionState)';
1922 } 1954 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698