| 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, |
| 11 ConstantCompiler, |
| 11 ConstructedConstant, | 12 ConstructedConstant, |
| 12 ListConstant, | 13 ListConstant, |
| 13 MessageKind, | 14 MessageKind, |
| 14 StringConstant, | 15 StringConstant, |
| 15 TreeElements, | 16 TreeElements, |
| 16 TypeConstant, | 17 TypeConstant, |
| 17 invariant; | 18 invariant; |
| 18 | 19 |
| 19 import 'elements/elements.dart' show | 20 import 'elements/elements.dart' show |
| 20 ClassElement, | 21 ClassElement, |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 && librariesWithUsage.contains(library)); | 127 && librariesWithUsage.contains(library)); |
| 127 } | 128 } |
| 128 | 129 |
| 129 /// Call-back from the resolver to analyze MirorsUsed annotations. The result | 130 /// Call-back from the resolver to analyze MirorsUsed annotations. The result |
| 130 /// is stored in [analyzer] and later used to compute | 131 /// is stored in [analyzer] and later used to compute |
| 131 /// [:analyzer.mergedMirrorUsage:]. | 132 /// [:analyzer.mergedMirrorUsage:]. |
| 132 void validate(NewExpression node, TreeElements mapping) { | 133 void validate(NewExpression node, TreeElements mapping) { |
| 133 for (Node argument in node.send.arguments) { | 134 for (Node argument in node.send.arguments) { |
| 134 NamedArgument named = argument.asNamedArgument(); | 135 NamedArgument named = argument.asNamedArgument(); |
| 135 if (named == null) continue; | 136 if (named == null) continue; |
| 136 Constant value = compiler.constantHandler.compileNodeWithDefinitions( | 137 ConstantCompiler constantCompiler = compiler.resolver.constantCompiler; |
| 137 named.expression, mapping, isConst: true); | 138 Constant value = constantCompiler.compileNode(named.expression, mapping); |
| 138 | |
| 139 ConstantMapper mapper = | |
| 140 new ConstantMapper(compiler.constantHandler, mapping, compiler); | |
| 141 named.expression.accept(mapper); | |
| 142 | 139 |
| 143 MirrorUsageBuilder builder = | 140 MirrorUsageBuilder builder = |
| 144 new MirrorUsageBuilder( | 141 new MirrorUsageBuilder( |
| 145 analyzer, mapping.currentElement.getLibrary(), named.expression, | 142 analyzer, mapping.currentElement.getLibrary(), named.expression, |
| 146 value, mapper.constantToNodeMap); | 143 value, mapping); |
| 147 | 144 |
| 148 if (named.name.source == 'symbols') { | 145 if (named.name.source == 'symbols') { |
| 149 analyzer.cachedStrings[value] = | 146 analyzer.cachedStrings[value] = |
| 150 builder.convertConstantToUsageList(value, onlyStrings: true); | 147 builder.convertConstantToUsageList(value, onlyStrings: true); |
| 151 } else if (named.name.source == 'targets') { | 148 } else if (named.name.source == 'targets') { |
| 152 analyzer.cachedElements[value] = | 149 analyzer.cachedElements[value] = |
| 153 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 150 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| 154 } else if (named.name.source == 'metaTargets') { | 151 } else if (named.name.source == 'metaTargets') { |
| 155 analyzer.cachedElements[value] = | 152 analyzer.cachedElements[value] = |
| 156 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 153 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 ')'; | 364 ')'; |
| 368 | 365 |
| 369 } | 366 } |
| 370 } | 367 } |
| 371 | 368 |
| 372 class MirrorUsageBuilder { | 369 class MirrorUsageBuilder { |
| 373 final MirrorUsageAnalyzer analyzer; | 370 final MirrorUsageAnalyzer analyzer; |
| 374 final LibraryElement enclosingLibrary; | 371 final LibraryElement enclosingLibrary; |
| 375 final Spannable spannable; | 372 final Spannable spannable; |
| 376 final Constant constant; | 373 final Constant constant; |
| 377 final Map<Constant, Node> constantToNodeMap; | 374 final TreeElements elements; |
| 378 | 375 |
| 379 MirrorUsageBuilder( | 376 MirrorUsageBuilder( |
| 380 this.analyzer, | 377 this.analyzer, |
| 381 this.enclosingLibrary, | 378 this.enclosingLibrary, |
| 382 this.spannable, | 379 this.spannable, |
| 383 this.constant, | 380 this.constant, |
| 384 this.constantToNodeMap); | 381 this.elements); |
| 385 | 382 |
| 386 Compiler get compiler => analyzer.compiler; | 383 Compiler get compiler => analyzer.compiler; |
| 387 | 384 |
| 388 /// Convert a constant to a list of [String] and [Type] values. If the | 385 /// Convert a constant to a list of [String] and [Type] values. If the |
| 389 /// constant is a single [String], it is assumed to be a comma-separated list | 386 /// constant is a single [String], it is assumed to be a comma-separated list |
| 390 /// of qualified names. If the constant is a [Type] t, the result is [:[t]:]. | 387 /// of qualified names. If the constant is a [Type] t, the result is [:[t]:]. |
| 391 /// Otherwise, the constant is assumed to represent a list of strings (each a | 388 /// Otherwise, the constant is assumed to represent a list of strings (each a |
| 392 /// qualified name) and types, and such a list is constructed. If | 389 /// qualified name) and types, and such a list is constructed. If |
| 393 /// [onlyStrings] is true, the returned list is a [:List<String>:] and any | 390 /// [onlyStrings] is true, the returned list is a [:List<String>:] and any |
| 394 /// [Type] values are treated as an error (meaning that the value is ignored | 391 /// [Type] values are treated as an error (meaning that the value is ignored |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 559 ClassElement cls = element; | 556 ClassElement cls = element; |
| 560 cls.ensureResolved(compiler); | 557 cls.ensureResolved(compiler); |
| 561 } | 558 } |
| 562 return scope.localLookup(name); | 559 return scope.localLookup(name); |
| 563 } | 560 } |
| 564 return null; | 561 return null; |
| 565 } | 562 } |
| 566 | 563 |
| 567 /// Attempt to find a [Spannable] corresponding to constant. | 564 /// Attempt to find a [Spannable] corresponding to constant. |
| 568 Spannable positionOf(Constant constant) { | 565 Spannable positionOf(Constant constant) { |
| 569 Node node = constantToNodeMap[constant]; | 566 Node node; |
| 567 elements.forEachConstantNode((Node n, Constant c) { |
| 568 if (node == null && c == constant) { |
| 569 node = n; |
| 570 } |
| 571 }); |
| 570 if (node == null) { | 572 if (node == null) { |
| 571 // TODO(ahe): Returning [spannable] here leads to confusing error | 573 // TODO(ahe): Returning [spannable] here leads to confusing error |
| 572 // messages. For example, consider: | 574 // messages. For example, consider: |
| 573 // @MirrorsUsed(targets: fisk) | 575 // @MirrorsUsed(targets: fisk) |
| 574 // import 'dart:mirrors'; | 576 // import 'dart:mirrors'; |
| 575 // | 577 // |
| 576 // const fisk = const [main]; | 578 // const fisk = const [main]; |
| 577 // | 579 // |
| 578 // main() {} | 580 // main() {} |
| 579 // | 581 // |
| 580 // The message is: | 582 // The message is: |
| 581 // example.dart:1:23: Hint: Can't use 'fisk' here because ... | 583 // example.dart:1:23: Hint: Can't use 'fisk' here because ... |
| 582 // Did you forget to add quotes? | 584 // Did you forget to add quotes? |
| 583 // @MirrorsUsed(targets: fisk) | 585 // @MirrorsUsed(targets: fisk) |
| 584 // ^^^^ | 586 // ^^^^ |
| 585 // | 587 // |
| 586 // Instead of saying 'fisk' should pretty print the problematic constant | 588 // Instead of saying 'fisk' should pretty print the problematic constant |
| 587 // value. | 589 // value. |
| 588 return spannable; | 590 return spannable; |
| 589 } | 591 } |
| 590 return node; | 592 return node; |
| 591 } | 593 } |
| 592 } | 594 } |
| OLD | NEW |