| 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 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 98 MirrorUsageAnalyzerTask(Compiler compiler) | 98 MirrorUsageAnalyzerTask(Compiler compiler) |
| 99 : super(compiler) { | 99 : super(compiler) { |
| 100 analyzer = new MirrorUsageAnalyzer(compiler, this); | 100 analyzer = new MirrorUsageAnalyzer(compiler, this); |
| 101 } | 101 } |
| 102 | 102 |
| 103 /// Collect @MirrorsUsed annotations in all libraries. Called by the | 103 /// Collect @MirrorsUsed annotations in all libraries. Called by the |
| 104 /// compiler after all libraries are loaded, but before resolution. | 104 /// compiler after all libraries are loaded, but before resolution. |
| 105 void analyzeUsage(LibraryElement mainApp) { | 105 void analyzeUsage(LibraryElement mainApp) { |
| 106 if (compiler.mirrorsLibrary == null) return; | 106 if (compiler.mirrorsLibrary == null) return; |
| 107 measure(analyzer.run); | 107 measure(analyzer.run); |
| 108 List /*<String|Element>*/ symbols = analyzer.mergedMirrorUsage.symbols; | 108 List<String> symbols = analyzer.mergedMirrorUsage.symbols; |
| 109 List<Element> targets = analyzer.mergedMirrorUsage.targets; | 109 List<Element> targets = analyzer.mergedMirrorUsage.targets; |
| 110 List<Element> metaTargets = analyzer.mergedMirrorUsage.metaTargets; | 110 List<Element> metaTargets = analyzer.mergedMirrorUsage.metaTargets; |
| 111 compiler.backend.registerMirrorUsage( | 111 compiler.backend.registerMirrorUsage( |
| 112 symbols == null ? null : new Set/*<String|Element>*/.from(symbols), | 112 symbols == null ? null : new Set<String>.from(symbols), |
| 113 targets == null ? null : new Set<Element>.from(targets), | 113 targets == null ? null : new Set<Element>.from(targets), |
| 114 metaTargets == null ? null : new Set<Element>.from(metaTargets)); | 114 metaTargets == null ? null : new Set<Element>.from(metaTargets)); |
| 115 librariesWithUsage = analyzer.librariesWithUsage; | 115 librariesWithUsage = analyzer.librariesWithUsage; |
| 116 } | 116 } |
| 117 | 117 |
| 118 /// Is there a @MirrorsUsed annotation in the library of [element]? Used by | 118 /// Is there a @MirrorsUsed annotation in the library of [element]? Used by |
| 119 /// the resolver to suppress hints about using new Symbol or | 119 /// the resolver to suppress hints about using new Symbol or |
| 120 /// MirrorSystem.getName. | 120 /// MirrorSystem.getName. |
| 121 bool hasMirrorUsage(Element element) { | 121 bool hasMirrorUsage(Element element) { |
| 122 LibraryElement library = element.getLibrary(); | 122 LibraryElement library = element.getLibrary(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 139 ConstantMapper mapper = | 139 ConstantMapper mapper = |
| 140 new ConstantMapper(compiler.constantHandler, mapping, compiler); | 140 new ConstantMapper(compiler.constantHandler, mapping, compiler); |
| 141 named.expression.accept(mapper); | 141 named.expression.accept(mapper); |
| 142 | 142 |
| 143 MirrorUsageBuilder builder = | 143 MirrorUsageBuilder builder = |
| 144 new MirrorUsageBuilder( | 144 new MirrorUsageBuilder( |
| 145 analyzer, mapping.currentElement.getLibrary(), named.expression, | 145 analyzer, mapping.currentElement.getLibrary(), named.expression, |
| 146 value, mapper.constantToNodeMap); | 146 value, mapper.constantToNodeMap); |
| 147 | 147 |
| 148 if (named.name.source == 'symbols') { | 148 if (named.name.source == 'symbols') { |
| 149 analyzer.cachedValues[value] = | 149 analyzer.cachedStrings[value] = |
| 150 builder.convertToListOfStrings( | 150 builder.convertToListOfStrings( |
| 151 builder.convertConstantToUsageList(value, onlyStrings: true)); | 151 builder.convertConstantToUsageList(value, onlyStrings: true)); |
| 152 } else if (named.name.source == 'targets') { | 152 } else if (named.name.source == 'targets') { |
| 153 analyzer.cachedValues[value] = | 153 analyzer.cachedElements[value] = |
| 154 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 154 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| 155 } else if (named.name.source == 'metaTargets') { | 155 } else if (named.name.source == 'metaTargets') { |
| 156 analyzer.cachedValues[value] = | 156 analyzer.cachedElements[value] = |
| 157 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 157 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| 158 } else if (named.name.source == 'override') { | 158 } else if (named.name.source == 'override') { |
| 159 analyzer.cachedValues[value] = | 159 analyzer.cachedElements[value] = |
| 160 builder.resolveUsageList(builder.convertConstantToUsageList(value)); | 160 builder.resolveUsageList(builder.convertConstantToUsageList(value)); |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 } | 164 } |
| 165 | 165 |
| 166 class MirrorUsageAnalyzer { | 166 class MirrorUsageAnalyzer { |
| 167 final Compiler compiler; | 167 final Compiler compiler; |
| 168 final MirrorUsageAnalyzerTask task; | 168 final MirrorUsageAnalyzerTask task; |
| 169 List<LibraryElement> wildcard; | 169 List<LibraryElement> wildcard; |
| 170 final Set<LibraryElement> librariesWithUsage; | 170 final Set<LibraryElement> librariesWithUsage; |
| 171 final Map<Constant, List> cachedValues; | 171 final Map<Constant, List<String>> cachedStrings; |
| 172 final Map<Constant, List<Element>> cachedElements; |
| 172 MirrorUsage mergedMirrorUsage; | 173 MirrorUsage mergedMirrorUsage; |
| 173 | 174 |
| 174 MirrorUsageAnalyzer(Compiler compiler, this.task) | 175 MirrorUsageAnalyzer(Compiler compiler, this.task) |
| 175 : compiler = compiler, | 176 : compiler = compiler, |
| 176 librariesWithUsage = new Set<LibraryElement>(), | 177 librariesWithUsage = new Set<LibraryElement>(), |
| 177 cachedValues = new Map<Constant, List>(); | 178 cachedStrings = new Map<Constant, List<String>>(), |
| 179 cachedElements = new Map<Constant, List<Element>>(); |
| 178 | 180 |
| 179 /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also | 181 /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also |
| 180 /// compute which libraries have the annotation (which is used by | 182 /// compute which libraries have the annotation (which is used by |
| 181 /// [MirrorUsageAnalyzerTask.hasMirrorUsage]). | 183 /// [MirrorUsageAnalyzerTask.hasMirrorUsage]). |
| 182 void run() { | 184 void run() { |
| 183 wildcard = compiler.libraries.values.toList(); | 185 wildcard = compiler.libraries.values.toList(); |
| 184 Map<LibraryElement, List<MirrorUsage>> usageMap = | 186 Map<LibraryElement, List<MirrorUsage>> usageMap = |
| 185 collectMirrorsUsedAnnotation(); | 187 collectMirrorsUsedAnnotation(); |
| 186 propagateOverrides(usageMap); | 188 propagateOverrides(usageMap); |
| 187 Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>(); | 189 Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>(); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 /// ignored. | 299 /// ignored. |
| 298 MirrorUsage merge(MirrorUsage a, MirrorUsage b) { | 300 MirrorUsage merge(MirrorUsage a, MirrorUsage b) { |
| 299 // TOOO(ahe): Should be an instance method on MirrorUsage. | 301 // TOOO(ahe): Should be an instance method on MirrorUsage. |
| 300 if (a.symbols == null && a.targets == null && a.metaTargets == null) { | 302 if (a.symbols == null && a.targets == null && a.metaTargets == null) { |
| 301 return b; | 303 return b; |
| 302 } else if ( | 304 } else if ( |
| 303 b.symbols == null && b.targets == null && b.metaTargets == null) { | 305 b.symbols == null && b.targets == null && b.metaTargets == null) { |
| 304 return a; | 306 return a; |
| 305 } | 307 } |
| 306 // TODO(ahe): Test the following cases. | 308 // TODO(ahe): Test the following cases. |
| 307 List /*<String|Element>*/ symbols = a.symbols; | 309 List<String> symbols = a.symbols; |
| 308 if (symbols == null) { | 310 if (symbols == null) { |
| 309 symbols = b.symbols; | 311 symbols = b.symbols; |
| 310 } else if (b.symbols != null) { | 312 } else if (b.symbols != null) { |
| 311 symbols.addAll(b.symbols); | 313 symbols.addAll(b.symbols); |
| 312 } | 314 } |
| 313 List<Element> targets = a.targets; | 315 List<Element> targets = a.targets; |
| 314 if (targets == null) { | 316 if (targets == null) { |
| 315 targets = b.targets; | 317 targets = b.targets; |
| 316 } else if (targets != wildcard && b.targets != null) { | 318 } else if (targets != wildcard && b.targets != null) { |
| 317 targets.addAll(b.targets); | 319 targets.addAll(b.targets); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 333 'symbols'); | 335 'symbols'); |
| 334 VariableElement targetsField = compiler.mirrorsUsedClass.lookupLocalMember( | 336 VariableElement targetsField = compiler.mirrorsUsedClass.lookupLocalMember( |
| 335 'targets'); | 337 'targets'); |
| 336 VariableElement metaTargetsField = | 338 VariableElement metaTargetsField = |
| 337 compiler.mirrorsUsedClass.lookupLocalMember( | 339 compiler.mirrorsUsedClass.lookupLocalMember( |
| 338 'metaTargets'); | 340 'metaTargets'); |
| 339 VariableElement overrideField = compiler.mirrorsUsedClass.lookupLocalMember( | 341 VariableElement overrideField = compiler.mirrorsUsedClass.lookupLocalMember( |
| 340 'override'); | 342 'override'); |
| 341 | 343 |
| 342 return new MirrorUsage( | 344 return new MirrorUsage( |
| 343 cachedValues[fields[symbolsField]], | 345 cachedStrings[fields[symbolsField]], |
| 344 cachedValues[fields[targetsField]], | 346 cachedElements[fields[targetsField]], |
| 345 cachedValues[fields[metaTargetsField]], | 347 cachedElements[fields[metaTargetsField]], |
| 346 cachedValues[fields[overrideField]]); | 348 cachedElements[fields[overrideField]]); |
| 347 } | 349 } |
| 348 } | 350 } |
| 349 | 351 |
| 350 /// Used to represent a resolved MirrorsUsed constant. | 352 /// Used to represent a resolved MirrorsUsed constant. |
| 351 class MirrorUsage { | 353 class MirrorUsage { |
| 352 final List /* <String|Element> */ symbols; | 354 final List<String> symbols; |
| 353 final List<Element> targets; | 355 final List<Element> targets; |
| 354 final List<Element> metaTargets; | 356 final List<Element> metaTargets; |
| 355 final List<Element> override; | 357 final List<Element> override; |
| 356 | 358 |
| 357 MirrorUsage(this.symbols, this.targets, this.metaTargets, this.override); | 359 MirrorUsage(this.symbols, this.targets, this.metaTargets, this.override); |
| 358 | 360 |
| 359 String toString() { | 361 String toString() { |
| 360 return | 362 return |
| 361 'MirrorUsage(' | 363 'MirrorUsage(' |
| 362 'symbols = $symbols, ' | 364 'symbols = $symbols, ' |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 // @MirrorsUsed(targets: fisk) | 591 // @MirrorsUsed(targets: fisk) |
| 590 // ^^^^ | 592 // ^^^^ |
| 591 // | 593 // |
| 592 // Instead of saying 'fisk' should pretty print the problematic constant | 594 // Instead of saying 'fisk' should pretty print the problematic constant |
| 593 // value. | 595 // value. |
| 594 return spannable; | 596 return spannable; |
| 595 } | 597 } |
| 596 return node; | 598 return node; |
| 597 } | 599 } |
| 598 } | 600 } |
| OLD | NEW |