| 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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 * except [isErroneous] will currently throw an exception. (This might | 358 * except [isErroneous] will currently throw an exception. (This might |
| 359 * change when we actually want more information on the erroneous element, | 359 * change when we actually want more information on the erroneous element, |
| 360 * e.g., the name of the element we were trying to resolve.) | 360 * e.g., the name of the element we were trying to resolve.) |
| 361 * | 361 * |
| 362 * Code that cannot not handle an [ErroneousElement] should use | 362 * Code that cannot not handle an [ErroneousElement] should use |
| 363 * [: Element.isInvalid(element) :] | 363 * [: Element.isInvalid(element) :] |
| 364 * to check for unresolvable elements instead of | 364 * to check for unresolvable elements instead of |
| 365 * [: element == null :]. | 365 * [: element == null :]. |
| 366 */ | 366 */ |
| 367 class ErroneousElement extends Element { | 367 class ErroneousElement extends Element { |
| 368 final Message errorMessage; | 368 final MessageKind messageKind; |
| 369 final List messageArguments; |
| 369 final SourceString targetName; | 370 final SourceString targetName; |
| 370 | 371 |
| 371 ErroneousElement(this.errorMessage, this.targetName, Element enclosing) | 372 ErroneousElement(this.messageKind, this.messageArguments, |
| 373 this.targetName, Element enclosing) |
| 372 : super(const SourceString('erroneous element'), null, enclosing); | 374 : super(const SourceString('erroneous element'), null, enclosing); |
| 373 | 375 |
| 374 isErroneous() => true; | 376 isErroneous() => true; |
| 375 | 377 |
| 376 unsupported() { | 378 unsupported() { |
| 377 throw 'unsupported operation on erroneous element'; | 379 throw 'unsupported operation on erroneous element'; |
| 378 } | 380 } |
| 379 | 381 |
| 380 SourceString get name => unsupported(); | 382 SourceString get name => unsupported(); |
| 381 ElementKind get kind => unsupported(); | 383 ElementKind get kind => unsupported(); |
| 382 Link<MetadataAnnotation> get metadata => unsupported(); | 384 Link<MetadataAnnotation> get metadata => unsupported(); |
| 383 | 385 |
| 384 getLibrary() => enclosingElement.getLibrary(); | 386 getLibrary() => enclosingElement.getLibrary(); |
| 385 } | 387 } |
| 386 | 388 |
| 387 class ErroneousFunctionElement extends ErroneousElement | 389 class ErroneousFunctionElement extends ErroneousElement |
| 388 implements FunctionElement { | 390 implements FunctionElement { |
| 389 ErroneousFunctionElement(Message errorMessage, SourceString targetName, | 391 ErroneousFunctionElement(MessageKind messageKind, List messageArguments, |
| 390 Element enclosing) | 392 SourceString targetName, Element enclosing) |
| 391 : super(errorMessage, targetName, enclosing); | 393 : super(messageKind, messageArguments, targetName, enclosing); |
| 392 | 394 |
| 393 get type => unsupported(); | 395 get type => unsupported(); |
| 394 get cachedNode => unsupported(); | 396 get cachedNode => unsupported(); |
| 395 get functionSignature => unsupported(); | 397 get functionSignature => unsupported(); |
| 396 get patch => unsupported(); | 398 get patch => unsupported(); |
| 397 get origin => unsupported(); | 399 get origin => unsupported(); |
| 398 get defaultImplementation => unsupported(); | 400 get defaultImplementation => unsupported(); |
| 399 bool get isPatched => unsupported(); | 401 bool get isPatched => unsupported(); |
| 400 bool get isPatch => unsupported(); | 402 bool get isPatch => unsupported(); |
| 401 setPatch(patch) => unsupported(); | 403 setPatch(patch) => unsupported(); |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 class LibraryElement extends ScopeContainerElement { | 533 class LibraryElement extends ScopeContainerElement { |
| 532 final Uri uri; | 534 final Uri uri; |
| 533 CompilationUnitElement entryCompilationUnit; | 535 CompilationUnitElement entryCompilationUnit; |
| 534 Link<CompilationUnitElement> compilationUnits = | 536 Link<CompilationUnitElement> compilationUnits = |
| 535 const EmptyLink<CompilationUnitElement>(); | 537 const EmptyLink<CompilationUnitElement>(); |
| 536 Link<LibraryTag> tags = const EmptyLink<LibraryTag>(); | 538 Link<LibraryTag> tags = const EmptyLink<LibraryTag>(); |
| 537 LibraryTag libraryTag; | 539 LibraryTag libraryTag; |
| 538 bool canUseNative = false; | 540 bool canUseNative = false; |
| 539 LibraryElement patch = null; | 541 LibraryElement patch = null; |
| 540 | 542 |
| 543 /** |
| 544 * Map for elements imported through import declarations. |
| 545 * |
| 546 * Addition to the map is performed by [addImport]. Lookup is done trough |
| 547 * [find]. |
| 548 */ |
| 549 final Map<SourceString, Element> importScope; |
| 550 |
| 541 LibraryElement(Script script, [Uri uri]) | 551 LibraryElement(Script script, [Uri uri]) |
| 542 : this.uri = ((uri === null) ? script.uri : uri), | 552 : this.uri = ((uri === null) ? script.uri : uri), |
| 553 importScope = new Map<SourceString, Element>(), |
| 543 super(new SourceString(script.name), ElementKind.LIBRARY, null) { | 554 super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
| 544 entryCompilationUnit = new CompilationUnitElement(script, this); | 555 entryCompilationUnit = new CompilationUnitElement(script, this); |
| 545 } | 556 } |
| 546 | 557 |
| 547 | 558 |
| 548 bool get isPatched => patch !== null; | 559 bool get isPatched => patch !== null; |
| 549 | 560 |
| 550 void addCompilationUnit(CompilationUnitElement element) { | 561 void addCompilationUnit(CompilationUnitElement element) { |
| 551 compilationUnits = compilationUnits.prepend(element); | 562 compilationUnits = compilationUnits.prepend(element); |
| 552 } | 563 } |
| 553 | 564 |
| 554 void addTag(LibraryTag tag, DiagnosticListener listener) { | 565 void addTag(LibraryTag tag, DiagnosticListener listener) { |
| 555 tags = tags.prepend(tag); | 566 tags = tags.prepend(tag); |
| 556 } | 567 } |
| 557 | 568 |
| 558 /** Look up a top-level element in this library. The element could | 569 /** |
| 559 * potentially have been imported from another library. Returns | 570 * Adds [element] to the import scope of this library. |
| 560 * null if no such element exist. */ | 571 * |
| 572 * If an element by the same name is already in the imported scope, an |
| 573 * [ErroneousElement] will be put in the imported scope, allowing for the |
| 574 * detection of ambiguous uses of imported names. |
| 575 */ |
| 576 void addImport(Element element, DiagnosticListener listener) { |
| 577 Element existing = importScope.putIfAbsent(element.name, () => element); |
| 578 if (existing !== element && existing !== null) { |
| 579 if (!existing.isErroneous()) { |
| 580 // TODO(johnniwinther): Provide access to both the new and existing |
| 581 // elements. |
| 582 importScope[element.name] = new ErroneousElement( |
| 583 MessageKind.DUPLICATE_IMPORT, |
| 584 [element.name], element.name, this); |
| 585 } |
| 586 } |
| 587 } |
| 588 |
| 589 |
| 590 /** |
| 591 * Look up a top-level element in this library. The element could |
| 592 * potentially have been imported from another library. Returns |
| 593 * null if no such element exist and an [ErroneousElement] if multiple |
| 594 * elements have been imported. |
| 595 */ |
| 561 Element find(SourceString elementName) { | 596 Element find(SourceString elementName) { |
| 562 return localScope[elementName]; | 597 Element result = localScope[elementName]; |
| 598 if (result === null) { |
| 599 result = importScope[elementName]; |
| 600 } |
| 601 return result; |
| 563 } | 602 } |
| 564 | 603 |
| 565 /** Look up a top-level element in this library, but only look for | 604 /** Look up a top-level element in this library, but only look for |
| 566 * non-imported elements. Returns null if no such element exist. */ | 605 * non-imported elements. Returns null if no such element exist. */ |
| 567 Element findLocal(SourceString elementName) { | 606 Element findLocal(SourceString elementName) { |
| 568 Element result = localScope[elementName]; | 607 Element result = localScope[elementName]; |
| 569 if (result === null || result.getLibrary() != this) return null; | 608 if (result === null || result.getLibrary() != this) return null; |
| 570 return result; | 609 return result; |
| 571 } | 610 } |
| 572 | 611 |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1751 | 1790 |
| 1752 MetadataAnnotation ensureResolved(Compiler compiler) { | 1791 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 1753 if (resolutionState == STATE_NOT_STARTED) { | 1792 if (resolutionState == STATE_NOT_STARTED) { |
| 1754 compiler.resolver.resolveMetadataAnnotation(this); | 1793 compiler.resolver.resolveMetadataAnnotation(this); |
| 1755 } | 1794 } |
| 1756 return this; | 1795 return this; |
| 1757 } | 1796 } |
| 1758 | 1797 |
| 1759 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 1798 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 1760 } | 1799 } |
| OLD | NEW |