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