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

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: Updated cf. comments. 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. This field should not be accessed directly but instead through
594 * the [exports] getter.
595 *
596 * [LibraryDependencyHandler] sets this field through [setExports] when the
597 * library is loaded.
598 */
599 Link<Element> slotForExports;
600
588 LibraryElement(Script script, [Uri uri, LibraryElement this.origin]) 601 LibraryElement(Script script, [Uri uri, LibraryElement this.origin])
589 : this.uri = ((uri === null) ? script.uri : uri), 602 : this.uri = ((uri === null) ? script.uri : uri),
590 importScope = new Map<SourceString, Element>(), 603 importScope = new Map<SourceString, Element>(),
591 super(new SourceString(script.name), ElementKind.LIBRARY, null) { 604 super(new SourceString(script.name), ElementKind.LIBRARY, null) {
592 entryCompilationUnit = new CompilationUnitElement(script, this); 605 entryCompilationUnit = new CompilationUnitElement(script, this);
593 if (isPatch) { 606 if (isPatch) {
594 origin.patch = this; 607 origin.patch = this;
595 } 608 }
596 } 609 }
597 610
(...skipping 12 matching lines...) Expand all
610 } 623 }
611 624
612 /** 625 /**
613 * Adds [element] to the import scope of this library. 626 * Adds [element] to the import scope of this library.
614 * 627 *
615 * If an element by the same name is already in the imported scope, an 628 * 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 629 * [ErroneousElement] will be put in the imported scope, allowing for the
617 * detection of ambiguous uses of imported names. 630 * detection of ambiguous uses of imported names.
618 */ 631 */
619 void addImport(Element element, DiagnosticListener listener) { 632 void addImport(Element element, DiagnosticListener listener) {
620 Element existing = importScope.putIfAbsent(element.name, () => element); 633 Element existing = importScope[element.name];
621 if (existing !== element && existing !== null) { 634 if (existing !== null) {
622 if (!existing.isErroneous()) { 635 if (!existing.isErroneous()) {
623 // TODO(johnniwinther): Provide access to both the new and existing 636 // TODO(johnniwinther): Provide access to both the new and existing
624 // elements. 637 // elements.
625 importScope[element.name] = new ErroneousElement( 638 importScope[element.name] = new ErroneousElement(
626 MessageKind.DUPLICATE_IMPORT, 639 MessageKind.DUPLICATE_IMPORT,
627 [element.name], element.name, this); 640 [element.name], element.name, this);
628 } 641 }
642 } else {
643 importScope[element.name] = element;
629 } 644 }
630 } 645 }
631 646
647 /**
648 * Returns [:true:] if the export scope has already been computed for this
649 * library.
650 */
651 bool get exportsHandled => slotForExports !== null;
652
653 Link<Element> get exports {
654 assert(invariant(this, exportsHandled,
655 message: 'Exports not handled on $this'));
656 return slotForExports;
657 }
658
659 /**
660 * Sets the export scope of this library. This method can only be called once.
661 */
662 void setExports(Iterable<Element> exportedElements) {
663 assert(invariant(this, !exportsHandled,
664 message: 'Exports already set to $slotForExports on $this'));
665 assert(invariant(this, exportedElements !== null));
666 var builder = new LinkBuilder<Element>();
667 for (Element export in exportedElements) {
668 builder.addLast(export);
669 }
670 slotForExports = builder.toLink();
671 }
672
632 LibraryElement getLibrary() => isPatch ? origin : this; 673 LibraryElement getLibrary() => isPatch ? origin : this;
633 674
634 /** 675 /**
635 * Look up a top-level element in this library. The element could 676 * Look up a top-level element in this library. The element could
636 * potentially have been imported from another library. Returns 677 * potentially have been imported from another library. Returns
637 * null if no such element exist and an [ErroneousElement] if multiple 678 * null if no such element exist and an [ErroneousElement] if multiple
638 * elements have been imported. 679 * elements have been imported.
639 */ 680 */
640 Element find(SourceString elementName) { 681 Element find(SourceString elementName) {
641 Element result = localScope[elementName]; 682 Element result = localScope[elementName];
642 if (result === null) { 683 if (result === null) {
643 result = importScope[elementName]; 684 result = importScope[elementName];
644 } 685 }
645 return result; 686 return result;
646 } 687 }
647 688
648 /** Look up a top-level element in this library, but only look for 689 /** Look up a top-level element in this library, but only look for
649 * non-imported elements. Returns null if no such element exist. */ 690 * non-imported elements. Returns null if no such element exist. */
650 Element findLocal(SourceString elementName) { 691 Element findLocal(SourceString elementName) {
651 // TODO(johnniwinther): How to handle injected elements in the patch 692 // TODO(johnniwinther): How to handle injected elements in the patch
652 // library? 693 // library?
653 Element result = localScope[elementName]; 694 Element result = localScope[elementName];
654 if (result === null || result.getLibrary() != this) return null; 695 if (result === null || result.getLibrary() != this) return null;
655 return result; 696 return result;
656 } 697 }
657 698
658 void forEachExport(f(Element element)) { 699 void forEachExport(f(Element element)) {
659 localScope.forEach((_, Element e) { 700 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 } 701 }
668 702
669 void forEachLocalMember(f(Element element)) { 703 void forEachLocalMember(f(Element element)) {
670 if (isPatch) { 704 if (isPatch) {
671 // Patch libraries traverse both origin and injected members. 705 // Patch libraries traverse both origin and injected members.
672 origin.localMembers.forEach(f); 706 origin.localMembers.forEach(f);
673 707
674 void filterPatch(Element element) { 708 void filterPatch(Element element) {
675 if (!element.isPatch) { 709 if (!element.isPatch) {
676 // Do not traverse the patch members. 710 // Do not traverse the patch members.
(...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1913 1947
1914 MetadataAnnotation ensureResolved(Compiler compiler) { 1948 MetadataAnnotation ensureResolved(Compiler compiler) {
1915 if (resolutionState == STATE_NOT_STARTED) { 1949 if (resolutionState == STATE_NOT_STARTED) {
1916 compiler.resolver.resolveMetadataAnnotation(this); 1950 compiler.resolver.resolveMetadataAnnotation(this);
1917 } 1951 }
1918 return this; 1952 return this;
1919 } 1953 }
1920 1954
1921 String toString() => 'MetadataAnnotation($value, $resolutionState)'; 1955 String toString() => 'MetadataAnnotation($value, $resolutionState)';
1922 } 1956 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/dart_backend/utils.dart ('k') | lib/compiler/implementation/leg.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698