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 // 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 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 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 Loading... | |
| 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'), |
|
ahe
2012/10/09 13:07:50
Good catch!
| |
| 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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 610 } | 613 } |
| 611 | 614 |
| 612 /** | 615 /** |
| 613 * Adds [element] to the import scope of this library. | 616 * Adds [element] to the import scope of this library. |
| 614 * | 617 * |
| 615 * If an element by the same name is already in the imported scope, an | 618 * 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 | 619 * [ErroneousElement] will be put in the imported scope, allowing for the |
| 617 * detection of ambiguous uses of imported names. | 620 * detection of ambiguous uses of imported names. |
| 618 */ | 621 */ |
| 619 void addImport(Element element, DiagnosticListener listener) { | 622 void addImport(Element element, DiagnosticListener listener) { |
| 620 Element existing = importScope.putIfAbsent(element.name, () => element); | 623 Element existing = importScope[element.name]; |
| 621 if (existing !== element && existing !== null) { | 624 importScope.putIfAbsent(element.name, () => element); |
|
ahe
2012/10/09 13:07:50
This should be:
Element existing = importScope.pu
Johnni Winther
2012/10/09 13:50:07
Changed to not use [putIfAbsent].
| |
| 625 if (existing !== null) { | |
| 622 if (!existing.isErroneous()) { | 626 if (!existing.isErroneous()) { |
| 623 // TODO(johnniwinther): Provide access to both the new and existing | 627 // TODO(johnniwinther): Provide access to both the new and existing |
| 624 // elements. | 628 // elements. |
| 625 importScope[element.name] = new ErroneousElement( | 629 importScope[element.name] = new ErroneousElement( |
| 626 MessageKind.DUPLICATE_IMPORT, | 630 MessageKind.DUPLICATE_IMPORT, |
| 627 [element.name], element.name, this); | 631 [element.name], element.name, this); |
| 628 } | 632 } |
| 629 } | 633 } |
| 630 } | 634 } |
| 631 | 635 |
| 636 bool get exportsHandled => _exports !== null; | |
|
ahe
2012/10/09 13:07:50
What is the purpose of this method?
Johnni Winther
2012/10/09 13:50:07
To test whether the export scope has been computed
| |
| 637 | |
| 638 /** | |
| 639 * Link for elements exported either through export declarations or through | |
| 640 * declaration. | |
| 641 * | |
| 642 * [ImportExportHandler] sets this map when the library is loaded. | |
| 643 */ | |
| 644 Link<Element> _exports; | |
|
ahe
2012/10/09 13:07:50
Why is this private, and why is it not with all th
Johnni Winther
2012/10/09 13:50:07
It is private so that setExports can ensure that i
ahe
2012/10/09 14:41:33
How does privacy ensure that it can only be set on
Johnni Winther
2012/10/10 09:20:59
It doesn't. Renamed to [slotForExports] and commen
| |
| 645 | |
| 646 Link<Element> get exports { | |
| 647 assert(invariant(this, exportsHandled, | |
| 648 message: 'Exports not handled on $this')); | |
| 649 return _exports; | |
| 650 } | |
| 651 | |
| 652 void setExports(Iterable<Element> iterable) { | |
|
ahe
2012/10/09 13:07:50
Why is this not a setter?
Johnni Winther
2012/10/09 13:50:07
Because it is not symmetric to the getter. It has
Bob Nystrom
2012/10/09 16:20:37
I agree with Johnni, I wouldn't make this a setter
| |
| 653 assert(invariant(this, !exportsHandled, | |
| 654 message: 'Exports already set to $_exports on $this')); | |
| 655 assert(invariant(this, iterable !== null)); | |
| 656 var builder = new LinkBuilder<Element>(); | |
| 657 for (Element export in iterable) { | |
| 658 builder.addLast(export); | |
| 659 } | |
| 660 _exports = builder.toLink(); | |
| 661 } | |
| 662 | |
| 632 LibraryElement getLibrary() => isPatch ? origin : this; | 663 LibraryElement getLibrary() => isPatch ? origin : this; |
| 633 | 664 |
| 634 /** | 665 /** |
| 635 * Look up a top-level element in this library. The element could | 666 * Look up a top-level element in this library. The element could |
| 636 * potentially have been imported from another library. Returns | 667 * potentially have been imported from another library. Returns |
| 637 * null if no such element exist and an [ErroneousElement] if multiple | 668 * null if no such element exist and an [ErroneousElement] if multiple |
| 638 * elements have been imported. | 669 * elements have been imported. |
| 639 */ | 670 */ |
| 640 Element find(SourceString elementName) { | 671 Element find(SourceString elementName) { |
| 641 Element result = localScope[elementName]; | 672 Element result = localScope[elementName]; |
| 642 if (result === null) { | 673 if (result === null) { |
| 643 result = importScope[elementName]; | 674 result = importScope[elementName]; |
| 644 } | 675 } |
| 645 return result; | 676 return result; |
| 646 } | 677 } |
| 647 | 678 |
| 648 /** Look up a top-level element in this library, but only look for | 679 /** Look up a top-level element in this library, but only look for |
| 649 * non-imported elements. Returns null if no such element exist. */ | 680 * non-imported elements. Returns null if no such element exist. */ |
| 650 Element findLocal(SourceString elementName) { | 681 Element findLocal(SourceString elementName) { |
| 651 // TODO(johnniwinther): How to handle injected elements in the patch | 682 // TODO(johnniwinther): How to handle injected elements in the patch |
| 652 // library? | 683 // library? |
| 653 Element result = localScope[elementName]; | 684 Element result = localScope[elementName]; |
| 654 if (result === null || result.getLibrary() != this) return null; | 685 if (result === null || result.getLibrary() != this) return null; |
| 655 return result; | 686 return result; |
| 656 } | 687 } |
| 657 | 688 |
| 658 void forEachExport(f(Element element)) { | 689 void forEachExport(f(Element element)) { |
| 659 localScope.forEach((_, Element e) { | 690 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 } | 691 } |
| 668 | 692 |
| 669 void forEachLocalMember(f(Element element)) { | 693 void forEachLocalMember(f(Element element)) { |
| 670 if (isPatch) { | 694 if (isPatch) { |
| 671 // Patch libraries traverse both origin and injected members. | 695 // Patch libraries traverse both origin and injected members. |
| 672 origin.localMembers.forEach(f); | 696 origin.localMembers.forEach(f); |
| 673 | 697 |
| 674 void filterPatch(Element element) { | 698 void filterPatch(Element element) { |
| 675 if (!element.isPatch) { | 699 if (!element.isPatch) { |
| 676 // Do not traverse the patch members. | 700 // Do not traverse the patch members. |
| (...skipping 1236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1913 | 1937 |
| 1914 MetadataAnnotation ensureResolved(Compiler compiler) { | 1938 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 1915 if (resolutionState == STATE_NOT_STARTED) { | 1939 if (resolutionState == STATE_NOT_STARTED) { |
| 1916 compiler.resolver.resolveMetadataAnnotation(this); | 1940 compiler.resolver.resolveMetadataAnnotation(this); |
| 1917 } | 1941 } |
| 1918 return this; | 1942 return this; |
| 1919 } | 1943 } |
| 1920 | 1944 |
| 1921 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 1945 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 1922 } | 1946 } |
| OLD | NEW |