Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 #import('../tree/tree.dart'); | 9 #import('../tree/tree.dart'); |
| 10 #import('../scanner/scannerlib.dart'); | 10 #import('../scanner/scannerlib.dart'); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 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 ERRONEOUS = | |
|
Lasse Reichstein Nielsen
2012/09/28 07:45:36
It should be called ERROR - a noun - and not ERRON
Johnni Winther
2012/10/09 09:47:10
Done.
| |
| 108 const ElementKind('erroneous', ElementCategory.NONE); | |
| 109 | |
| 107 toString() => id; | 110 toString() => id; |
| 108 } | 111 } |
| 109 | 112 |
| 110 class Element implements Hashable, Spannable { | 113 class Element implements Hashable, 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 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 * to check for unresolvable elements instead of | 367 * to check for unresolvable elements instead of |
| 365 * [: element == null :]. | 368 * [: element == null :]. |
| 366 */ | 369 */ |
| 367 class ErroneousElement extends Element { | 370 class ErroneousElement extends Element { |
| 368 final MessageKind messageKind; | 371 final MessageKind messageKind; |
| 369 final List messageArguments; | 372 final List messageArguments; |
| 370 final SourceString targetName; | 373 final SourceString targetName; |
| 371 | 374 |
| 372 ErroneousElement(this.messageKind, this.messageArguments, | 375 ErroneousElement(this.messageKind, this.messageArguments, |
| 373 this.targetName, Element enclosing) | 376 this.targetName, Element enclosing) |
| 374 : super(const SourceString('erroneous element'), null, enclosing); | 377 : super(const SourceString('erroneous element'), |
| 378 ElementKind.ERRONEOUS, enclosing); | |
| 375 | 379 |
| 376 isErroneous() => true; | 380 isErroneous() => true; |
| 377 | 381 |
| 378 unsupported() { | 382 unsupported() { |
| 379 throw 'unsupported operation on erroneous element'; | 383 throw 'unsupported operation on erroneous element'; |
| 380 } | 384 } |
| 381 | 385 |
| 382 SourceString get name => unsupported(); | 386 SourceString get name => unsupported(); |
| 383 ElementKind get kind => unsupported(); | |
| 384 Link<MetadataAnnotation> get metadata => unsupported(); | 387 Link<MetadataAnnotation> get metadata => unsupported(); |
| 385 | 388 |
| 386 getLibrary() => enclosingElement.getLibrary(); | 389 getLibrary() => enclosingElement.getLibrary(); |
| 387 } | 390 } |
| 388 | 391 |
| 389 class ErroneousFunctionElement extends ErroneousElement | 392 class ErroneousFunctionElement extends ErroneousElement |
| 390 implements FunctionElement { | 393 implements FunctionElement { |
| 391 ErroneousFunctionElement(MessageKind messageKind, List messageArguments, | 394 ErroneousFunctionElement(MessageKind messageKind, List messageArguments, |
| 392 SourceString targetName, Element enclosing) | 395 SourceString targetName, Element enclosing) |
| 393 : super(messageKind, messageArguments, targetName, enclosing); | 396 : super(messageKind, messageArguments, targetName, enclosing); |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 LibraryElement patch = null; | 546 LibraryElement patch = null; |
| 544 | 547 |
| 545 /** | 548 /** |
| 546 * Map for elements imported through import declarations. | 549 * Map for elements imported through import declarations. |
| 547 * | 550 * |
| 548 * Addition to the map is performed by [addImport]. Lookup is done trough | 551 * Addition to the map is performed by [addImport]. Lookup is done trough |
| 549 * [find]. | 552 * [find]. |
| 550 */ | 553 */ |
| 551 final Map<SourceString, Element> importScope; | 554 final Map<SourceString, Element> importScope; |
| 552 | 555 |
| 556 /** | |
| 557 * Map for elements exported either through export declarations or through | |
| 558 * declaration. | |
| 559 * | |
| 560 * [ImportExportHandler] sets this map when the library is loaded. | |
| 561 */ | |
| 562 Map<SourceString, Element> _exportScope; | |
| 563 | |
| 564 Map<SourceString, Element> get exportScope { | |
|
Lasse Reichstein Nielsen
2012/09/28 07:45:36
Please don't export the map. Someone will just do
Bob Nystrom
2012/09/28 16:41:27
Drive-by comment: I see stuff like this frequently
Johnni Winther
2012/10/09 09:47:10
Changed to used a linked list.
| |
| 565 assert(invariant(this, _exportScope !== null)); | |
| 566 return _exportScope; | |
| 567 } | |
| 568 | |
| 569 void set exportScope(Map<SourceString, Element> map) { | |
| 570 assert(invariant(this, _exportScope === null)); | |
| 571 assert(invariant(this, map !== null)); | |
| 572 _exportScope = map; | |
| 573 } | |
| 574 | |
| 553 LibraryElement(Script script, [Uri uri]) | 575 LibraryElement(Script script, [Uri uri]) |
| 554 : this.uri = ((uri === null) ? script.uri : uri), | 576 : this.uri = ((uri === null) ? script.uri : uri), |
| 555 importScope = new Map<SourceString, Element>(), | 577 importScope = new Map<SourceString, Element>(), |
| 556 super(new SourceString(script.name), ElementKind.LIBRARY, null) { | 578 super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
| 557 entryCompilationUnit = new CompilationUnitElement(script, this); | 579 entryCompilationUnit = new CompilationUnitElement(script, this); |
| 558 } | 580 } |
| 559 | 581 |
| 560 | |
| 561 bool get isPatched => patch !== null; | 582 bool get isPatched => patch !== null; |
| 562 | 583 |
| 563 void addCompilationUnit(CompilationUnitElement element) { | 584 void addCompilationUnit(CompilationUnitElement element) { |
| 564 compilationUnits = compilationUnits.prepend(element); | 585 compilationUnits = compilationUnits.prepend(element); |
| 565 } | 586 } |
| 566 | 587 |
| 567 void addTag(LibraryTag tag, DiagnosticListener listener) { | 588 void addTag(LibraryTag tag, DiagnosticListener listener) { |
| 568 tags = tags.prepend(tag); | 589 tags = tags.prepend(tag); |
| 569 } | 590 } |
| 570 | 591 |
| 571 /** | 592 /** |
| 572 * Adds [element] to the import scope of this library. | 593 * Adds [element] to the import scope of this library. |
| 573 * | 594 * |
| 574 * If an element by the same name is already in the imported scope, an | 595 * If an element by the same name is already in the imported scope, an |
| 575 * [ErroneousElement] will be put in the imported scope, allowing for the | 596 * [ErroneousElement] will be put in the imported scope, allowing for the |
| 576 * detection of ambiguous uses of imported names. | 597 * detection of ambiguous uses of imported names. |
| 577 */ | 598 */ |
| 578 void addImport(Element element, DiagnosticListener listener) { | 599 void addImport(Element element, DiagnosticListener listener) { |
| 579 Element existing = importScope.putIfAbsent(element.name, () => element); | 600 SourceString name = element.name; |
| 601 Element existing = importScope.putIfAbsent(name, () => element); | |
| 580 if (existing !== element && existing !== null) { | 602 if (existing !== element && existing !== null) { |
|
Lasse Reichstein Nielsen
2012/09/28 07:45:36
Add a comment that you are not following the curre
Johnni Winther
2012/10/09 09:47:10
Implementation changed to follow spec.
| |
| 581 if (!existing.isErroneous()) { | 603 if (!existing.isErroneous()) { |
| 582 // TODO(johnniwinther): Provide access to both the new and existing | 604 // TODO(johnniwinther): Provide access to both the new and existing |
| 583 // elements. | 605 // elements. |
| 584 importScope[element.name] = new ErroneousElement( | 606 importScope[name] = new ErroneousElement( |
| 585 MessageKind.DUPLICATE_IMPORT, | 607 MessageKind.DUPLICATE_IMPORT, |
| 586 [element.name], element.name, this); | 608 [name], name, this); |
| 587 } | 609 } |
| 588 } | 610 } |
| 589 } | 611 } |
| 590 | 612 |
| 591 | |
| 592 /** | 613 /** |
| 593 * Look up a top-level element in this library. The element could | 614 * Look up a top-level element in this library. The element could |
| 594 * potentially have been imported from another library. Returns | 615 * potentially have been imported from another library. Returns |
| 595 * null if no such element exist and an [ErroneousElement] if multiple | 616 * null if no such element exist and an [ErroneousElement] if multiple |
| 596 * elements have been imported. | 617 * elements have been imported. |
| 597 */ | 618 */ |
| 598 Element find(SourceString elementName) { | 619 Element find(SourceString elementName) { |
| 599 Element result = localScope[elementName]; | 620 Element result = localScope[elementName]; |
| 600 if (result === null) { | 621 if (result === null) { |
| 601 result = importScope[elementName]; | 622 result = importScope[elementName]; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 613 | 634 |
| 614 void forEachExport(f(Element element)) { | 635 void forEachExport(f(Element element)) { |
| 615 localScope.forEach((_, Element e) { | 636 localScope.forEach((_, Element e) { |
| 616 if (this === e.getLibrary() | 637 if (this === e.getLibrary() |
| 617 && e.kind !== ElementKind.PREFIX | 638 && e.kind !== ElementKind.PREFIX |
| 618 && e.kind !== ElementKind.FOREIGN | 639 && e.kind !== ElementKind.FOREIGN |
| 619 && !e.name.isPrivate()) { | 640 && !e.name.isPrivate()) { |
| 620 f(e); | 641 f(e); |
| 621 } | 642 } |
| 622 }); | 643 }); |
| 644 exportScope.forEach((_, Element e) => f(e)); | |
| 623 } | 645 } |
| 624 | 646 |
| 625 bool hasLibraryName() => libraryTag !== null; | 647 bool hasLibraryName() => libraryTag !== null; |
| 626 | 648 |
| 627 /** | 649 /** |
| 628 * Returns the library name (as defined by the #library tag) or for script | 650 * Returns the library name (as defined by the #library tag) or for script |
| 629 * (which have no #library tag) the script file name. The latter case is used | 651 * (which have no #library tag) the script file name. The latter case is used |
| 630 * to private 'library name' for scripts to use for instance in dartdoc. | 652 * to private 'library name' for scripts to use for instance in dartdoc. |
| 631 */ | 653 */ |
| 632 String getLibraryOrScriptName() { | 654 String getLibraryOrScriptName() { |
| (...skipping 1198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1831 | 1853 |
| 1832 MetadataAnnotation ensureResolved(Compiler compiler) { | 1854 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 1833 if (resolutionState == STATE_NOT_STARTED) { | 1855 if (resolutionState == STATE_NOT_STARTED) { |
| 1834 compiler.resolver.resolveMetadataAnnotation(this); | 1856 compiler.resolver.resolveMetadataAnnotation(this); |
| 1835 } | 1857 } |
| 1836 return this; | 1858 return this; |
| 1837 } | 1859 } |
| 1838 | 1860 |
| 1839 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 1861 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 1840 } | 1862 } |
| OLD | NEW |