Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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.modelx; | 5 library elements.modelx; |
| 6 | 6 |
| 7 import 'dart:collection' show LinkedHashMap; | 7 import 'dart:collection' show LinkedHashMap; |
| 8 | 8 |
| 9 import 'elements.dart'; | 9 import 'elements.dart'; |
| 10 import '../../compiler.dart' as api; | 10 import '../../compiler.dart' as api; |
| (...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 370 */ | 370 */ |
| 371 final Element newElement; | 371 final Element newElement; |
| 372 | 372 |
| 373 AmbiguousElementX(this.messageKind, this.messageArguments, | 373 AmbiguousElementX(this.messageKind, this.messageArguments, |
| 374 Element enclosingElement, Element existingElement, Element newElement) | 374 Element enclosingElement, Element existingElement, Element newElement) |
| 375 : this.existingElement = existingElement, | 375 : this.existingElement = existingElement, |
| 376 this.newElement = newElement, | 376 this.newElement = newElement, |
| 377 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); | 377 super(existingElement.name, ElementKind.AMBIGUOUS, enclosingElement); |
| 378 | 378 |
| 379 bool isAmbiguous() => true; | 379 bool isAmbiguous() => true; |
| 380 | |
| 381 Set flatten() { | |
| 382 Element element = this; | |
| 383 var set = new Set(); | |
| 384 while (element.isAmbiguous()) { | |
| 385 AmbiguousElement ambiguous = element; | |
| 386 set.add(ambiguous.newElement); | |
| 387 element = ambiguous.existingElement; | |
| 388 } | |
| 389 set.add(element); | |
| 390 return set; | |
| 391 } | |
| 392 | |
| 393 void diagnose(Element context, DiagnosticListener listener) { | |
| 394 Set ambiguousElements = flatten(); | |
| 395 MessageKind code = (ambiguousElements.length == 1) | |
| 396 ? MessageKind.AMBIGUOUS_REEXPORT : MessageKind.AMBIGUOUS_LOCATION; | |
| 397 LibraryElementX importer = context.getLibrary(); | |
| 398 for (Element element in ambiguousElements) { | |
| 399 var arguments = {'element': element}; | |
| 400 listener.reportInfo(element, code, arguments); | |
| 401 var importers = importer.importers[element]; | |
|
Johnni Winther
2013/06/06 12:28:31
Type this variable.
ahe
2013/06/06 13:56:16
Done.
| |
| 402 listener.withCurrentElement(importer, () { | |
| 403 for (; !importers.isEmpty; importers = importers.tail) { | |
| 404 listener.reportInfo( | |
| 405 importers.head, MessageKind.IMPORTED_HERE, arguments); | |
| 406 } | |
| 407 }); | |
| 408 } | |
| 409 } | |
| 380 } | 410 } |
| 381 | 411 |
| 382 class ScopeX { | 412 class ScopeX { |
| 383 final Map<SourceString, Element> contents = new Map<SourceString, Element>(); | 413 final Map<SourceString, Element> contents = new Map<SourceString, Element>(); |
| 384 | 414 |
| 385 bool get isEmpty => contents.isEmpty; | 415 bool get isEmpty => contents.isEmpty; |
| 386 Iterable<Element> get values => contents.values; | 416 Iterable<Element> get values => contents.values; |
| 387 | 417 |
| 388 Element lookup(SourceString name) { | 418 Element lookup(SourceString name) { |
| 389 return contents[name]; | 419 return contents[name]; |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 559 final LibraryElementX origin; | 589 final LibraryElementX origin; |
| 560 | 590 |
| 561 /** | 591 /** |
| 562 * Map for elements imported through import declarations. | 592 * Map for elements imported through import declarations. |
| 563 * | 593 * |
| 564 * Addition to the map is performed by [addImport]. Lookup is done trough | 594 * Addition to the map is performed by [addImport]. Lookup is done trough |
| 565 * [find]. | 595 * [find]. |
| 566 */ | 596 */ |
| 567 final Map<SourceString, Element> importScope; | 597 final Map<SourceString, Element> importScope; |
| 568 | 598 |
| 599 /// A mapping from an imported element to the "import" tag. | |
| 600 final Map<Element, Link<Import>> importers; | |
| 601 | |
| 569 /** | 602 /** |
| 570 * Link for elements exported either through export declarations or through | 603 * Link for elements exported either through export declarations or through |
| 571 * declaration. This field should not be accessed directly but instead through | 604 * declaration. This field should not be accessed directly but instead through |
| 572 * the [exports] getter. | 605 * the [exports] getter. |
| 573 * | 606 * |
| 574 * [LibraryDependencyHandler] sets this field through [setExports] when the | 607 * [LibraryDependencyHandler] sets this field through [setExports] when the |
| 575 * library is loaded. | 608 * library is loaded. |
| 576 */ | 609 */ |
| 577 Link<Element> slotForExports; | 610 Link<Element> slotForExports; |
| 578 | 611 |
| 579 final Map<LibraryDependency, LibraryElement> tagMapping = | 612 final Map<LibraryDependency, LibraryElement> tagMapping = |
| 580 new LinkedHashMap<LibraryDependency, LibraryElement>(); | 613 new LinkedHashMap<LibraryDependency, LibraryElement>(); |
| 581 | 614 |
| 582 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) | 615 LibraryElementX(Script script, [Uri canonicalUri, LibraryElement this.origin]) |
| 583 : this.canonicalUri = ((canonicalUri == null) ? script.uri : canonicalUri), | 616 : this.canonicalUri = ((canonicalUri == null) ? script.uri : canonicalUri), |
| 584 importScope = new Map<SourceString, Element>(), | 617 importScope = new Map<SourceString, Element>(), |
| 618 importers = new Map<SourceString, Element>(), | |
| 585 super(new SourceString(script.name), ElementKind.LIBRARY, null) { | 619 super(new SourceString(script.name), ElementKind.LIBRARY, null) { |
| 586 entryCompilationUnit = new CompilationUnitElementX(script, this); | 620 entryCompilationUnit = new CompilationUnitElementX(script, this); |
| 587 if (isPatch) { | 621 if (isPatch) { |
| 588 origin.patch = this; | 622 origin.patch = this; |
| 589 } | 623 } |
| 590 } | 624 } |
| 591 | 625 |
| 592 bool get isPatched => patch != null; | 626 bool get isPatched => patch != null; |
| 593 bool get isPatch => origin != null; | 627 bool get isPatch => origin != null; |
| 594 | 628 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 621 | 655 |
| 622 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; | 656 LibraryElement getLibraryFromTag(LibraryDependency tag) => tagMapping[tag]; |
| 623 | 657 |
| 624 /** | 658 /** |
| 625 * Adds [element] to the import scope of this library. | 659 * Adds [element] to the import scope of this library. |
| 626 * | 660 * |
| 627 * If an element by the same name is already in the imported scope, an | 661 * If an element by the same name is already in the imported scope, an |
| 628 * [ErroneousElement] will be put in the imported scope, allowing for the | 662 * [ErroneousElement] will be put in the imported scope, allowing for the |
| 629 * detection of ambiguous uses of imported names. | 663 * detection of ambiguous uses of imported names. |
| 630 */ | 664 */ |
| 631 void addImport(Element element, DiagnosticListener listener) { | 665 void addImport(Element element, Import import, DiagnosticListener listener) { |
| 666 importers[element] = | |
| 667 importers.putIfAbsent(element, () => const Link<Import>()) | |
| 668 .prepend(import); | |
| 632 Element existing = importScope[element.name]; | 669 Element existing = importScope[element.name]; |
| 633 if (existing != null) { | 670 if (existing != null) { |
| 634 // TODO(johnniwinther): Provide access to the import tags from which | 671 // TODO(johnniwinther): Provide access to the import tags from which |
| 635 // the elements came. | 672 // the elements came. |
| 636 importScope[element.name] = new AmbiguousElementX( | 673 importScope[element.name] = new AmbiguousElementX( |
| 637 MessageKind.DUPLICATE_IMPORT, {'name': element.name}, | 674 MessageKind.DUPLICATE_IMPORT, {'name': element.name}, |
| 638 this, existing, element); | 675 this, existing, element); |
| 639 } else { | 676 } else { |
| 640 importScope[element.name] = element; | 677 importScope[element.name] = element; |
| 641 } | 678 } |
| (...skipping 1500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2142 | 2179 |
| 2143 MetadataAnnotation ensureResolved(Compiler compiler) { | 2180 MetadataAnnotation ensureResolved(Compiler compiler) { |
| 2144 if (resolutionState == STATE_NOT_STARTED) { | 2181 if (resolutionState == STATE_NOT_STARTED) { |
| 2145 compiler.resolver.resolveMetadataAnnotation(this); | 2182 compiler.resolver.resolveMetadataAnnotation(this); |
| 2146 } | 2183 } |
| 2147 return this; | 2184 return this; |
| 2148 } | 2185 } |
| 2149 | 2186 |
| 2150 String toString() => 'MetadataAnnotation($value, $resolutionState)'; | 2187 String toString() => 'MetadataAnnotation($value, $resolutionState)'; |
| 2151 } | 2188 } |
| OLD | NEW |