| 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 dart2js.mirrors_used; | 5 library dart2js.mirrors_used; |
| 6 | 6 |
| 7 import 'dart2jslib.dart' show | 7 import 'dart2jslib.dart' show |
| 8 Compiler, | 8 Compiler, |
| 9 CompilerTask, | 9 CompilerTask, |
| 10 Constant, | 10 Constant, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 symbols == null ? null : new Set<String>.from(symbols), | 110 symbols == null ? null : new Set<String>.from(symbols), |
| 111 targets == null ? null : new Set<Element>.from(targets), | 111 targets == null ? null : new Set<Element>.from(targets), |
| 112 metaTargets == null ? null : new Set<Element>.from(metaTargets)); | 112 metaTargets == null ? null : new Set<Element>.from(metaTargets)); |
| 113 librariesWithUsage = analyzer.librariesWithUsage; | 113 librariesWithUsage = analyzer.librariesWithUsage; |
| 114 } | 114 } |
| 115 | 115 |
| 116 /// Is there a @MirrorsUsed annotation in the library of [element]? Used by | 116 /// Is there a @MirrorsUsed annotation in the library of [element]? Used by |
| 117 /// the resolver to suppress hints about using new Symbol or | 117 /// the resolver to suppress hints about using new Symbol or |
| 118 /// MirrorSystem.getName. | 118 /// MirrorSystem.getName. |
| 119 bool hasMirrorUsage(Element element) { | 119 bool hasMirrorUsage(Element element) { |
| 120 LibraryElement library = element.getLibrary(); | 120 LibraryElement library = element.library; |
| 121 // Internal libraries always have implicit mirror usage. | 121 // Internal libraries always have implicit mirror usage. |
| 122 return library.isInternalLibrary | 122 return library.isInternalLibrary |
| 123 || (librariesWithUsage != null | 123 || (librariesWithUsage != null |
| 124 && librariesWithUsage.contains(library)); | 124 && librariesWithUsage.contains(library)); |
| 125 } | 125 } |
| 126 | 126 |
| 127 /// Call-back from the resolver to analyze MirorsUsed annotations. The result | 127 /// Call-back from the resolver to analyze MirorsUsed annotations. The result |
| 128 /// is stored in [analyzer] and later used to compute | 128 /// is stored in [analyzer] and later used to compute |
| 129 /// [:analyzer.mergedMirrorUsage:]. | 129 /// [:analyzer.mergedMirrorUsage:]. |
| 130 void validate(NewExpression node, TreeElements mapping) { | 130 void validate(NewExpression node, TreeElements mapping) { |
| 131 for (Node argument in node.send.arguments) { | 131 for (Node argument in node.send.arguments) { |
| 132 NamedArgument named = argument.asNamedArgument(); | 132 NamedArgument named = argument.asNamedArgument(); |
| 133 if (named == null) continue; | 133 if (named == null) continue; |
| 134 ConstantCompiler constantCompiler = compiler.resolver.constantCompiler; | 134 ConstantCompiler constantCompiler = compiler.resolver.constantCompiler; |
| 135 Constant value = constantCompiler.compileNode(named.expression, mapping); | 135 Constant value = constantCompiler.compileNode(named.expression, mapping); |
| 136 | 136 |
| 137 MirrorUsageBuilder builder = | 137 MirrorUsageBuilder builder = |
| 138 new MirrorUsageBuilder( | 138 new MirrorUsageBuilder( |
| 139 analyzer, mapping.currentElement.getLibrary(), named.expression, | 139 analyzer, mapping.currentElement.library, named.expression, |
| 140 value, mapping); | 140 value, mapping); |
| 141 | 141 |
| 142 if (named.name.source == 'symbols') { | 142 if (named.name.source == 'symbols') { |
| 143 analyzer.cachedStrings[value] = | 143 analyzer.cachedStrings[value] = |
| 144 builder.convertConstantToUsageList(value, onlyStrings: true); | 144 builder.convertConstantToUsageList(value, onlyStrings: true); |
| 145 } else if (named.name.source == 'targets') { | 145 } else if (named.name.source == 'targets') { |
| 146 analyzer.cachedElements[value] = | 146 analyzer.cachedElements[value] = |
| 147 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 147 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| 148 } else if (named.name.source == 'metaTargets') { | 148 } else if (named.name.source == 'metaTargets') { |
| 149 analyzer.cachedElements[value] = | 149 analyzer.cachedElements[value] = |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 428 compiler.reportHint( | 428 compiler.reportHint( |
| 429 node, | 429 node, |
| 430 kind, {'name': node, 'type': apiTypeOf(constant)}); | 430 kind, {'name': node, 'type': apiTypeOf(constant)}); |
| 431 return null; | 431 return null; |
| 432 } | 432 } |
| 433 } | 433 } |
| 434 | 434 |
| 435 /// Find the first non-implementation interface of constant. | 435 /// Find the first non-implementation interface of constant. |
| 436 DartType apiTypeOf(Constant constant) { | 436 DartType apiTypeOf(Constant constant) { |
| 437 DartType type = constant.computeType(compiler); | 437 DartType type = constant.computeType(compiler); |
| 438 LibraryElement library = type.element.getLibrary(); | 438 LibraryElement library = type.element.library; |
| 439 if (type.kind == TypeKind.INTERFACE && library.isInternalLibrary) { | 439 if (type.kind == TypeKind.INTERFACE && library.isInternalLibrary) { |
| 440 InterfaceType interface = type; | 440 InterfaceType interface = type; |
| 441 ClassElement cls = type.element; | 441 ClassElement cls = type.element; |
| 442 cls.ensureResolved(compiler); | 442 cls.ensureResolved(compiler); |
| 443 for (DartType supertype in cls.allSupertypes) { | 443 for (DartType supertype in cls.allSupertypes) { |
| 444 if (supertype.kind == TypeKind.INTERFACE | 444 if (supertype.kind == TypeKind.INTERFACE |
| 445 && !supertype.element.getLibrary().isInternalLibrary) { | 445 && !supertype.element.library.isInternalLibrary) { |
| 446 return interface.asInstanceOf(supertype.element); | 446 return interface.asInstanceOf(supertype.element); |
| 447 } | 447 } |
| 448 } | 448 } |
| 449 } | 449 } |
| 450 return type; | 450 return type; |
| 451 } | 451 } |
| 452 | 452 |
| 453 /// Convert a list of strings and types to a list of elements. Types are | 453 /// Convert a list of strings and types to a list of elements. Types are |
| 454 /// converted to their corresponding element, and strings are resolved as | 454 /// converted to their corresponding element, and strings are resolved as |
| 455 /// follows: | 455 /// follows: |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 519 return resolveLocalExpression(element, identifiers.sublist(1)); | 519 return resolveLocalExpression(element, identifiers.sublist(1)); |
| 520 } | 520 } |
| 521 } | 521 } |
| 522 | 522 |
| 523 /// Resolve [identifiers] in [element]'s local members. | 523 /// Resolve [identifiers] in [element]'s local members. |
| 524 Element resolveLocalExpression(Element element, List<String> identifiers) { | 524 Element resolveLocalExpression(Element element, List<String> identifiers) { |
| 525 Element current = element; | 525 Element current = element; |
| 526 for (String identifier in identifiers) { | 526 for (String identifier in identifiers) { |
| 527 Element e = findLocalMemberIn(current, identifier); | 527 Element e = findLocalMemberIn(current, identifier); |
| 528 if (e == null) { | 528 if (e == null) { |
| 529 if (current.isLibrary()) { | 529 if (current.isLibrary) { |
| 530 LibraryElement library = current; | 530 LibraryElement library = current; |
| 531 compiler.reportHint( | 531 compiler.reportHint( |
| 532 spannable, MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY, | 532 spannable, MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY, |
| 533 {'name': identifiers[0], | 533 {'name': identifiers[0], |
| 534 'library': library.getLibraryOrScriptName()}); | 534 'library': library.getLibraryOrScriptName()}); |
| 535 } else { | 535 } else { |
| 536 compiler.reportHint( | 536 compiler.reportHint( |
| 537 spannable, MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT, | 537 spannable, MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT, |
| 538 {'name': identifier, 'element': current.name}); | 538 {'name': identifier, 'element': current.name}); |
| 539 } | 539 } |
| 540 return current; | 540 return current; |
| 541 } | 541 } |
| 542 current = e; | 542 current = e; |
| 543 } | 543 } |
| 544 return current; | 544 return current; |
| 545 } | 545 } |
| 546 | 546 |
| 547 /// Helper method to lookup members in a [ScopeContainerElement]. If | 547 /// Helper method to lookup members in a [ScopeContainerElement]. If |
| 548 /// [element] is not a ScopeContainerElement, return null. | 548 /// [element] is not a ScopeContainerElement, return null. |
| 549 Element findLocalMemberIn(Element element, String name) { | 549 Element findLocalMemberIn(Element element, String name) { |
| 550 if (element is ScopeContainerElement) { | 550 if (element is ScopeContainerElement) { |
| 551 ScopeContainerElement scope = element; | 551 ScopeContainerElement scope = element; |
| 552 if (element.isClass()) { | 552 if (element.isClass) { |
| 553 ClassElement cls = element; | 553 ClassElement cls = element; |
| 554 cls.ensureResolved(compiler); | 554 cls.ensureResolved(compiler); |
| 555 } | 555 } |
| 556 return scope.localLookup(name); | 556 return scope.localLookup(name); |
| 557 } | 557 } |
| 558 return null; | 558 return null; |
| 559 } | 559 } |
| 560 | 560 |
| 561 /// Attempt to find a [Spannable] corresponding to constant. | 561 /// Attempt to find a [Spannable] corresponding to constant. |
| 562 Spannable positionOf(Constant constant) { | 562 Spannable positionOf(Constant constant) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 582 // @MirrorsUsed(targets: fisk) | 582 // @MirrorsUsed(targets: fisk) |
| 583 // ^^^^ | 583 // ^^^^ |
| 584 // | 584 // |
| 585 // Instead of saying 'fisk' should pretty print the problematic constant | 585 // Instead of saying 'fisk' should pretty print the problematic constant |
| 586 // value. | 586 // value. |
| 587 return spannable; | 587 return spannable; |
| 588 } | 588 } |
| 589 return node; | 589 return node; |
| 590 } | 590 } |
| 591 } | 591 } |
| OLD | NEW |