Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/mirrors_used.dart

Issue 614993002: Rename Constant to ConstantValue and ConstExp to ConstantExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 'constants/expressions.dart'; 7 import 'constants/expressions.dart';
8 import 'constants/values.dart' show 8 import 'constants/values.dart' show
9 Constant, 9 ConstantValue,
10 ConstructedConstant, 10 ConstructedConstantValue,
11 ListConstant, 11 ListConstantValue,
12 StringConstant, 12 StringConstantValue,
13 TypeConstant; 13 TypeConstantValue;
14 14
15 import 'dart_types.dart' show 15 import 'dart_types.dart' show
16 DartType, 16 DartType,
17 InterfaceType, 17 InterfaceType,
18 TypeKind; 18 TypeKind;
19 19
20 import 'dart2jslib.dart' show 20 import 'dart2jslib.dart' show
21 Compiler, 21 Compiler,
22 CompilerTask, 22 CompilerTask,
23 ConstantCompiler, 23 ConstantCompiler,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 128 }
129 129
130 /// Call-back from the resolver to analyze MirorsUsed annotations. The result 130 /// Call-back from the resolver to analyze MirorsUsed annotations. The result
131 /// is stored in [analyzer] and later used to compute 131 /// is stored in [analyzer] and later used to compute
132 /// [:analyzer.mergedMirrorUsage:]. 132 /// [:analyzer.mergedMirrorUsage:].
133 void validate(NewExpression node, TreeElements mapping) { 133 void validate(NewExpression node, TreeElements mapping) {
134 for (Node argument in node.send.arguments) { 134 for (Node argument in node.send.arguments) {
135 NamedArgument named = argument.asNamedArgument(); 135 NamedArgument named = argument.asNamedArgument();
136 if (named == null) continue; 136 if (named == null) continue;
137 ConstantCompiler constantCompiler = compiler.resolver.constantCompiler; 137 ConstantCompiler constantCompiler = compiler.resolver.constantCompiler;
138 Constant value = 138 ConstantValue value =
139 constantCompiler.compileNode(named.expression, mapping).value; 139 constantCompiler.compileNode(named.expression, mapping).value;
140 140
141 MirrorUsageBuilder builder = 141 MirrorUsageBuilder builder =
142 new MirrorUsageBuilder( 142 new MirrorUsageBuilder(
143 analyzer, mapping.analyzedElement.library, named.expression, 143 analyzer, mapping.analyzedElement.library, named.expression,
144 value, mapping); 144 value, mapping);
145 145
146 if (named.name.source == 'symbols') { 146 if (named.name.source == 'symbols') {
147 analyzer.cachedStrings[value] = 147 analyzer.cachedStrings[value] =
148 builder.convertConstantToUsageList(value, onlyStrings: true); 148 builder.convertConstantToUsageList(value, onlyStrings: true);
149 } else if (named.name.source == 'targets') { 149 } else if (named.name.source == 'targets') {
150 analyzer.cachedElements[value] = 150 analyzer.cachedElements[value] =
151 builder.resolveUsageList(builder.convertConstantToUsageList(value)); 151 builder.resolveUsageList(builder.convertConstantToUsageList(value));
152 } else if (named.name.source == 'metaTargets') { 152 } else if (named.name.source == 'metaTargets') {
153 analyzer.cachedElements[value] = 153 analyzer.cachedElements[value] =
154 builder.resolveUsageList(builder.convertConstantToUsageList(value)); 154 builder.resolveUsageList(builder.convertConstantToUsageList(value));
155 } else if (named.name.source == 'override') { 155 } else if (named.name.source == 'override') {
156 analyzer.cachedElements[value] = 156 analyzer.cachedElements[value] =
157 builder.resolveUsageList(builder.convertConstantToUsageList(value)); 157 builder.resolveUsageList(builder.convertConstantToUsageList(value));
158 } 158 }
159 } 159 }
160 } 160 }
161 } 161 }
162 162
163 class MirrorUsageAnalyzer { 163 class MirrorUsageAnalyzer {
164 final Compiler compiler; 164 final Compiler compiler;
165 final MirrorUsageAnalyzerTask task; 165 final MirrorUsageAnalyzerTask task;
166 List<LibraryElement> wildcard; 166 List<LibraryElement> wildcard;
167 final Set<LibraryElement> librariesWithUsage; 167 final Set<LibraryElement> librariesWithUsage;
168 final Map<Constant, List<String>> cachedStrings; 168 final Map<ConstantValue, List<String>> cachedStrings;
169 final Map<Constant, List<Element>> cachedElements; 169 final Map<ConstantValue, List<Element>> cachedElements;
170 MirrorUsage mergedMirrorUsage; 170 MirrorUsage mergedMirrorUsage;
171 171
172 MirrorUsageAnalyzer(Compiler compiler, this.task) 172 MirrorUsageAnalyzer(Compiler compiler, this.task)
173 : compiler = compiler, 173 : compiler = compiler,
174 librariesWithUsage = new Set<LibraryElement>(), 174 librariesWithUsage = new Set<LibraryElement>(),
175 cachedStrings = new Map<Constant, List<String>>(), 175 cachedStrings = new Map<ConstantValue, List<String>>(),
176 cachedElements = new Map<Constant, List<Element>>(); 176 cachedElements = new Map<ConstantValue, List<Element>>();
177 177
178 /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also 178 /// Collect and merge all @MirrorsUsed annotations. As a side-effect, also
179 /// compute which libraries have the annotation (which is used by 179 /// compute which libraries have the annotation (which is used by
180 /// [MirrorUsageAnalyzerTask.hasMirrorUsage]). 180 /// [MirrorUsageAnalyzerTask.hasMirrorUsage]).
181 void run() { 181 void run() {
182 wildcard = compiler.libraryLoader.libraries.toList(); 182 wildcard = compiler.libraryLoader.libraries.toList();
183 Map<LibraryElement, List<MirrorUsage>> usageMap = 183 Map<LibraryElement, List<MirrorUsage>> usageMap =
184 collectMirrorsUsedAnnotation(); 184 collectMirrorsUsedAnnotation();
185 propagateOverrides(usageMap); 185 propagateOverrides(usageMap);
186 Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>(); 186 Set<LibraryElement> librariesWithoutUsage = new Set<LibraryElement>();
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 if (metaTargets == null) { 319 if (metaTargets == null) {
320 metaTargets = b.metaTargets; 320 metaTargets = b.metaTargets;
321 } else if (metaTargets != wildcard && b.metaTargets != null) { 321 } else if (metaTargets != wildcard && b.metaTargets != null) {
322 metaTargets.addAll(b.metaTargets); 322 metaTargets.addAll(b.metaTargets);
323 } 323 }
324 return new MirrorUsage(symbols, targets, metaTargets, null); 324 return new MirrorUsage(symbols, targets, metaTargets, null);
325 } 325 }
326 326
327 /// Convert a [constant] to an instance of [MirrorUsage] using information 327 /// Convert a [constant] to an instance of [MirrorUsage] using information
328 /// that was resolved during [MirrorUsageAnalyzerTask.validate]. 328 /// that was resolved during [MirrorUsageAnalyzerTask.validate].
329 MirrorUsage buildUsage(ConstructedConstant constant) { 329 MirrorUsage buildUsage(ConstructedConstantValue constant) {
330 Map<Element, Constant> fields = constant.fieldElements; 330 Map<Element, ConstantValue> fields = constant.fieldElements;
331 VariableElement symbolsField = compiler.mirrorsUsedClass.lookupLocalMember( 331 VariableElement symbolsField = compiler.mirrorsUsedClass.lookupLocalMember(
332 'symbols'); 332 'symbols');
333 VariableElement targetsField = compiler.mirrorsUsedClass.lookupLocalMember( 333 VariableElement targetsField = compiler.mirrorsUsedClass.lookupLocalMember(
334 'targets'); 334 'targets');
335 VariableElement metaTargetsField = 335 VariableElement metaTargetsField =
336 compiler.mirrorsUsedClass.lookupLocalMember( 336 compiler.mirrorsUsedClass.lookupLocalMember(
337 'metaTargets'); 337 'metaTargets');
338 VariableElement overrideField = compiler.mirrorsUsedClass.lookupLocalMember( 338 VariableElement overrideField = compiler.mirrorsUsedClass.lookupLocalMember(
339 'override'); 339 'override');
340 340
(...skipping 23 matching lines...) Expand all
364 'override = $override' 364 'override = $override'
365 ')'; 365 ')';
366 366
367 } 367 }
368 } 368 }
369 369
370 class MirrorUsageBuilder { 370 class MirrorUsageBuilder {
371 final MirrorUsageAnalyzer analyzer; 371 final MirrorUsageAnalyzer analyzer;
372 final LibraryElement enclosingLibrary; 372 final LibraryElement enclosingLibrary;
373 final Spannable spannable; 373 final Spannable spannable;
374 final Constant constant; 374 final ConstantValue constant;
375 final TreeElements elements; 375 final TreeElements elements;
376 376
377 MirrorUsageBuilder( 377 MirrorUsageBuilder(
378 this.analyzer, 378 this.analyzer,
379 this.enclosingLibrary, 379 this.enclosingLibrary,
380 this.spannable, 380 this.spannable,
381 this.constant, 381 this.constant,
382 this.elements); 382 this.elements);
383 383
384 Compiler get compiler => analyzer.compiler; 384 Compiler get compiler => analyzer.compiler;
385 385
386 /// Convert a constant to a list of [String] and [Type] values. If the 386 /// Convert a constant to a list of [String] and [Type] values. If the
387 /// constant is a single [String], it is assumed to be a comma-separated list 387 /// constant is a single [String], it is assumed to be a comma-separated list
388 /// of qualified names. If the constant is a [Type] t, the result is [:[t]:]. 388 /// of qualified names. If the constant is a [Type] t, the result is [:[t]:].
389 /// Otherwise, the constant is assumed to represent a list of strings (each a 389 /// Otherwise, the constant is assumed to represent a list of strings (each a
390 /// qualified name) and types, and such a list is constructed. If 390 /// qualified name) and types, and such a list is constructed. If
391 /// [onlyStrings] is true, the returned list is a [:List<String>:] and any 391 /// [onlyStrings] is true, the returned list is a [:List<String>:] and any
392 /// [Type] values are treated as an error (meaning that the value is ignored 392 /// [Type] values are treated as an error (meaning that the value is ignored
393 /// and a hint is emitted). 393 /// and a hint is emitted).
394 List convertConstantToUsageList( 394 List convertConstantToUsageList(
395 Constant constant, { bool onlyStrings: false }) { 395 ConstantValue constant, { bool onlyStrings: false }) {
396 if (constant.isNull) { 396 if (constant.isNull) {
397 return null; 397 return null;
398 } else if (constant.isList) { 398 } else if (constant.isList) {
399 ListConstant list = constant; 399 ListConstantValue list = constant;
400 List result = onlyStrings ? <String> [] : []; 400 List result = onlyStrings ? <String> [] : [];
401 for (Constant entry in list.entries) { 401 for (ConstantValue entry in list.entries) {
402 if (entry.isString) { 402 if (entry.isString) {
403 StringConstant string = entry; 403 StringConstantValue string = entry;
404 result.add(string.value.slowToString()); 404 result.add(string.primitiveValue.slowToString());
405 } else if (!onlyStrings && entry.isType) { 405 } else if (!onlyStrings && entry.isType) {
406 TypeConstant type = entry; 406 TypeConstantValue type = entry;
407 result.add(type.representedType); 407 result.add(type.representedType);
408 } else { 408 } else {
409 Spannable node = positionOf(entry); 409 Spannable node = positionOf(entry);
410 MessageKind kind = onlyStrings 410 MessageKind kind = onlyStrings
411 ? MessageKind.MIRRORS_EXPECTED_STRING 411 ? MessageKind.MIRRORS_EXPECTED_STRING
412 : MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE; 412 : MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE;
413 compiler.reportHint( 413 compiler.reportHint(
414 node, 414 node,
415 kind, {'name': node, 'type': apiTypeOf(entry)}); 415 kind, {'name': node, 'type': apiTypeOf(entry)});
416 } 416 }
417 } 417 }
418 return result; 418 return result;
419 } else if (!onlyStrings && constant.isType) { 419 } else if (!onlyStrings && constant.isType) {
420 TypeConstant type = constant; 420 TypeConstantValue type = constant;
421 return [type.representedType]; 421 return [type.representedType];
422 } else if (constant.isString) { 422 } else if (constant.isString) {
423 StringConstant string = constant; 423 StringConstantValue string = constant;
424 var iterable = 424 var iterable =
425 string.value.slowToString().split(',').map((e) => e.trim()); 425 string.primitiveValue.slowToString().split(',').map((e) => e.trim());
426 return onlyStrings ? new List<String>.from(iterable) : iterable.toList(); 426 return onlyStrings ? new List<String>.from(iterable) : iterable.toList();
427 } else { 427 } else {
428 Spannable node = positionOf(constant); 428 Spannable node = positionOf(constant);
429 MessageKind kind = onlyStrings 429 MessageKind kind = onlyStrings
430 ? MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST 430 ? MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST
431 : MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST; 431 : MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST;
432 compiler.reportHint( 432 compiler.reportHint(
433 node, 433 node,
434 kind, {'name': node, 'type': apiTypeOf(constant)}); 434 kind, {'name': node, 'type': apiTypeOf(constant)});
435 return null; 435 return null;
436 } 436 }
437 } 437 }
438 438
439 /// Find the first non-implementation interface of constant. 439 /// Find the first non-implementation interface of constant.
440 DartType apiTypeOf(Constant constant) { 440 DartType apiTypeOf(ConstantValue constant) {
441 DartType type = constant.computeType(compiler); 441 DartType type = constant.computeType(compiler);
442 LibraryElement library = type.element.library; 442 LibraryElement library = type.element.library;
443 if (type.isInterfaceType && library.isInternalLibrary) { 443 if (type.isInterfaceType && library.isInternalLibrary) {
444 InterfaceType interface = type; 444 InterfaceType interface = type;
445 ClassElement cls = type.element; 445 ClassElement cls = type.element;
446 cls.ensureResolved(compiler); 446 cls.ensureResolved(compiler);
447 for (DartType supertype in cls.allSupertypes) { 447 for (DartType supertype in cls.allSupertypes) {
448 if (supertype.isInterfaceType 448 if (supertype.isInterfaceType
449 && !supertype.element.library.isInternalLibrary) { 449 && !supertype.element.library.isInternalLibrary) {
450 return interface.asInstanceOf(supertype.element); 450 return interface.asInstanceOf(supertype.element);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
556 if (element.isClass) { 556 if (element.isClass) {
557 ClassElement cls = element; 557 ClassElement cls = element;
558 cls.ensureResolved(compiler); 558 cls.ensureResolved(compiler);
559 } 559 }
560 return scope.localLookup(name); 560 return scope.localLookup(name);
561 } 561 }
562 return null; 562 return null;
563 } 563 }
564 564
565 /// Attempt to find a [Spannable] corresponding to constant. 565 /// Attempt to find a [Spannable] corresponding to constant.
566 Spannable positionOf(Constant constant) { 566 Spannable positionOf(ConstantValue constant) {
567 Node node; 567 Node node;
568 elements.forEachConstantNode((Node n, ConstExp c) { 568 elements.forEachConstantNode((Node n, ConstantExpression c) {
569 if (node == null && c.value == constant) { 569 if (node == null && c.value == constant) {
570 node = n; 570 node = n;
571 } 571 }
572 }); 572 });
573 if (node == null) { 573 if (node == null) {
574 // TODO(ahe): Returning [spannable] here leads to confusing error 574 // TODO(ahe): Returning [spannable] here leads to confusing error
575 // messages. For example, consider: 575 // messages. For example, consider:
576 // @MirrorsUsed(targets: fisk) 576 // @MirrorsUsed(targets: fisk)
577 // import 'dart:mirrors'; 577 // import 'dart:mirrors';
578 // 578 //
579 // const fisk = const [main]; 579 // const fisk = const [main];
580 // 580 //
581 // main() {} 581 // main() {}
582 // 582 //
583 // The message is: 583 // The message is:
584 // example.dart:1:23: Hint: Can't use 'fisk' here because ... 584 // example.dart:1:23: Hint: Can't use 'fisk' here because ...
585 // Did you forget to add quotes? 585 // Did you forget to add quotes?
586 // @MirrorsUsed(targets: fisk) 586 // @MirrorsUsed(targets: fisk)
587 // ^^^^ 587 // ^^^^
588 // 588 //
589 // Instead of saying 'fisk' should pretty print the problematic constant 589 // Instead of saying 'fisk' should pretty print the problematic constant
590 // value. 590 // value.
591 return spannable; 591 return spannable;
592 } 592 }
593 return node; 593 return node;
594 } 594 }
595 } 595 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698