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

Side by Side Diff: pkg/compiler/lib/src/constants/values.dart

Issue 2199593003: Add kind to ConstantValue. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Rebased Created 4 years, 4 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
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/constant_emitter.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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.constants.values; 5 library dart2js.constants.values;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../core_types.dart'; 8 import '../core_types.dart';
9 import '../dart_types.dart'; 9 import '../dart_types.dart';
10 import '../elements/elements.dart' 10 import '../elements/elements.dart'
11 show FieldElement, FunctionElement, PrefixElement; 11 show FieldElement, FunctionElement, PrefixElement;
12 import '../tree/dartstring.dart'; 12 import '../tree/dartstring.dart';
13 import '../util/util.dart' show Hashing; 13 import '../util/util.dart' show Hashing;
14 14
15 enum ConstantValueKind {
16 FUNCTION,
17 NULL,
18 INT,
19 DOUBLE,
20 BOOL,
21 STRING,
22 LIST,
23 MAP,
24 CONSTRUCTED,
25 TYPE,
26 INTERCEPTOR,
27 SYNTHETIC,
28 DEFERRED,
29 NON_CONSTANT,
30 }
31
15 abstract class ConstantValueVisitor<R, A> { 32 abstract class ConstantValueVisitor<R, A> {
16 const ConstantValueVisitor(); 33 const ConstantValueVisitor();
17 34
18 R visitFunction(FunctionConstantValue constant, A arg); 35 R visitFunction(FunctionConstantValue constant, A arg);
19 R visitNull(NullConstantValue constant, A arg); 36 R visitNull(NullConstantValue constant, A arg);
20 R visitInt(IntConstantValue constant, A arg); 37 R visitInt(IntConstantValue constant, A arg);
21 R visitDouble(DoubleConstantValue constant, A arg); 38 R visitDouble(DoubleConstantValue constant, A arg);
22 R visitBool(BoolConstantValue constant, A arg); 39 R visitBool(BoolConstantValue constant, A arg);
23 R visitString(StringConstantValue constant, A arg); 40 R visitString(StringConstantValue constant, A arg);
24 R visitList(ListConstantValue constant, A arg); 41 R visitList(ListConstantValue constant, A arg);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 /// expression from the value so the unparse of these is best effort. 94 /// expression from the value so the unparse of these is best effort.
78 /// 95 ///
79 /// For the synthetic constants, [DeferredConstantValue], 96 /// For the synthetic constants, [DeferredConstantValue],
80 /// [SyntheticConstantValue], [InterceptorConstantValue] the unparse is 97 /// [SyntheticConstantValue], [InterceptorConstantValue] the unparse is
81 /// descriptive only. 98 /// descriptive only.
82 String toDartText(); 99 String toDartText();
83 100
84 /// Returns a structured representation of this constant suited for debugging. 101 /// Returns a structured representation of this constant suited for debugging.
85 String toStructuredText(); 102 String toStructuredText();
86 103
104 ConstantValueKind get kind;
105
87 String toString() { 106 String toString() {
88 assertDebugMode("Use ConstantValue.toDartText() or " 107 assertDebugMode("Use ConstantValue.toDartText() or "
89 "ConstantValue.toStructuredText() " 108 "ConstantValue.toStructuredText() "
90 "instead of ConstantValue.toString()."); 109 "instead of ConstantValue.toString().");
91 return toStructuredText(); 110 return toStructuredText();
92 } 111 }
93 } 112 }
94 113
95 class FunctionConstantValue extends ConstantValue { 114 class FunctionConstantValue extends ConstantValue {
96 FunctionElement element; 115 FunctionElement element;
(...skipping 14 matching lines...) Expand all
111 DartString toDartString() { 130 DartString toDartString() {
112 return new DartString.literal(element.name); 131 return new DartString.literal(element.name);
113 } 132 }
114 133
115 DartType getType(CoreTypes types) => element.type; 134 DartType getType(CoreTypes types) => element.type;
116 135
117 int get hashCode => (17 * element.hashCode) & 0x7fffffff; 136 int get hashCode => (17 * element.hashCode) & 0x7fffffff;
118 137
119 accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg); 138 accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg);
120 139
140 ConstantValueKind get kind => ConstantValueKind.FUNCTION;
141
121 String toDartText() { 142 String toDartText() {
122 if (element.isStatic) { 143 if (element.isStatic) {
123 return '${element.enclosingClass.name}.${element.name}'; 144 return '${element.enclosingClass.name}.${element.name}';
124 } else { 145 } else {
125 return '${element.name}'; 146 return '${element.name}';
126 } 147 }
127 } 148 }
128 149
129 String toStructuredText() { 150 String toStructuredText() {
130 return 'FunctionConstant(${toDartText()})'; 151 return 'FunctionConstant(${toDartText()})';
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 191
171 DartType getType(CoreTypes types) => types.nullType; 192 DartType getType(CoreTypes types) => types.nullType;
172 193
173 // The magic constant has no meaning. It is just a random value. 194 // The magic constant has no meaning. It is just a random value.
174 int get hashCode => 785965825; 195 int get hashCode => 785965825;
175 196
176 DartString toDartString() => const LiteralDartString("null"); 197 DartString toDartString() => const LiteralDartString("null");
177 198
178 accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg); 199 accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg);
179 200
201 ConstantValueKind get kind => ConstantValueKind.NULL;
202
180 String toStructuredText() => 'NullConstant'; 203 String toStructuredText() => 'NullConstant';
181 } 204 }
182 205
183 abstract class NumConstantValue extends PrimitiveConstantValue { 206 abstract class NumConstantValue extends PrimitiveConstantValue {
184 const NumConstantValue(); 207 const NumConstantValue();
185 208
186 num get primitiveValue; 209 num get primitiveValue;
187 210
188 bool get isNum => true; 211 bool get isNum => true;
189 } 212 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 } 274 }
252 275
253 int get hashCode => primitiveValue & Hashing.SMI_MASK; 276 int get hashCode => primitiveValue & Hashing.SMI_MASK;
254 277
255 DartString toDartString() { 278 DartString toDartString() {
256 return new DartString.literal(primitiveValue.toString()); 279 return new DartString.literal(primitiveValue.toString());
257 } 280 }
258 281
259 accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg); 282 accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg);
260 283
284 ConstantValueKind get kind => ConstantValueKind.INT;
285
261 String toStructuredText() => 'IntConstant(${toDartText()})'; 286 String toStructuredText() => 'IntConstant(${toDartText()})';
262 } 287 }
263 288
264 class DoubleConstantValue extends NumConstantValue { 289 class DoubleConstantValue extends NumConstantValue {
265 final double primitiveValue; 290 final double primitiveValue;
266 291
267 factory DoubleConstantValue(double value) { 292 factory DoubleConstantValue(double value) {
268 if (value.isNaN) { 293 if (value.isNaN) {
269 return const DoubleConstantValue._internal(double.NAN); 294 return const DoubleConstantValue._internal(double.NAN);
270 } else if (value == double.INFINITY) { 295 } else if (value == double.INFINITY) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 } 338 }
314 339
315 int get hashCode => primitiveValue.hashCode; 340 int get hashCode => primitiveValue.hashCode;
316 341
317 DartString toDartString() { 342 DartString toDartString() {
318 return new DartString.literal(primitiveValue.toString()); 343 return new DartString.literal(primitiveValue.toString());
319 } 344 }
320 345
321 accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg); 346 accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
322 347
348 ConstantValueKind get kind => ConstantValueKind.DOUBLE;
349
323 String toStructuredText() => 'DoubleConstant(${toDartText()})'; 350 String toStructuredText() => 'DoubleConstant(${toDartText()})';
324 } 351 }
325 352
326 abstract class BoolConstantValue extends PrimitiveConstantValue { 353 abstract class BoolConstantValue extends PrimitiveConstantValue {
327 factory BoolConstantValue(value) { 354 factory BoolConstantValue(value) {
328 return value ? new TrueConstantValue() : new FalseConstantValue(); 355 return value ? new TrueConstantValue() : new FalseConstantValue();
329 } 356 }
330 357
331 const BoolConstantValue._internal(); 358 const BoolConstantValue._internal();
332 359
333 bool get isBool => true; 360 bool get isBool => true;
334 361
335 DartType getType(CoreTypes types) => types.boolType; 362 DartType getType(CoreTypes types) => types.boolType;
336 363
337 BoolConstantValue negate(); 364 BoolConstantValue negate();
338 365
339 accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg); 366 accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg);
340 367
368 ConstantValueKind get kind => ConstantValueKind.BOOL;
369
341 String toStructuredText() => 'BoolConstant(${toDartText()})'; 370 String toStructuredText() => 'BoolConstant(${toDartText()})';
342 } 371 }
343 372
344 class TrueConstantValue extends BoolConstantValue { 373 class TrueConstantValue extends BoolConstantValue {
345 factory TrueConstantValue() => const TrueConstantValue._internal(); 374 factory TrueConstantValue() => const TrueConstantValue._internal();
346 375
347 const TrueConstantValue._internal() : super._internal(); 376 const TrueConstantValue._internal() : super._internal();
348 377
349 bool get isTrue => true; 378 bool get isTrue => true;
350 379
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 return hashCode == otherString.hashCode && 436 return hashCode == otherString.hashCode &&
408 primitiveValue == otherString.primitiveValue; 437 primitiveValue == otherString.primitiveValue;
409 } 438 }
410 439
411 DartString toDartString() => primitiveValue; 440 DartString toDartString() => primitiveValue;
412 441
413 int get length => primitiveValue.length; 442 int get length => primitiveValue.length;
414 443
415 accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg); 444 accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg);
416 445
446 ConstantValueKind get kind => ConstantValueKind.STRING;
447
417 // TODO(johnniwinther): Ensure correct escaping. 448 // TODO(johnniwinther): Ensure correct escaping.
418 String toDartText() => '"${primitiveValue.slowToString()}"'; 449 String toDartText() => '"${primitiveValue.slowToString()}"';
419 450
420 String toStructuredText() => 'StringConstant(${toDartText()})'; 451 String toStructuredText() => 'StringConstant(${toDartText()})';
421 } 452 }
422 453
423 abstract class ObjectConstantValue extends ConstantValue { 454 abstract class ObjectConstantValue extends ConstantValue {
424 final InterfaceType type; 455 final InterfaceType type;
425 456
426 ObjectConstantValue(this.type); 457 ObjectConstantValue(this.type);
(...skipping 23 matching lines...) Expand all
450 return other is TypeConstantValue && 481 return other is TypeConstantValue &&
451 representedType == other.representedType; 482 representedType == other.representedType;
452 } 483 }
453 484
454 int get hashCode => representedType.hashCode * 13; 485 int get hashCode => representedType.hashCode * 13;
455 486
456 List<ConstantValue> getDependencies() => const <ConstantValue>[]; 487 List<ConstantValue> getDependencies() => const <ConstantValue>[];
457 488
458 accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg); 489 accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg);
459 490
491 ConstantValueKind get kind => ConstantValueKind.TYPE;
492
460 String toDartText() => '$representedType'; 493 String toDartText() => '$representedType';
461 494
462 String toStructuredText() => 'TypeConstant(${representedType})'; 495 String toStructuredText() => 'TypeConstant(${representedType})';
463 } 496 }
464 497
465 class ListConstantValue extends ObjectConstantValue { 498 class ListConstantValue extends ObjectConstantValue {
466 final List<ConstantValue> entries; 499 final List<ConstantValue> entries;
467 final int hashCode; 500 final int hashCode;
468 501
469 ListConstantValue(InterfaceType type, List<ConstantValue> entries) 502 ListConstantValue(InterfaceType type, List<ConstantValue> entries)
(...skipping 15 matching lines...) Expand all
485 } 518 }
486 return true; 519 return true;
487 } 520 }
488 521
489 List<ConstantValue> getDependencies() => entries; 522 List<ConstantValue> getDependencies() => entries;
490 523
491 int get length => entries.length; 524 int get length => entries.length;
492 525
493 accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg); 526 accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg);
494 527
528 ConstantValueKind get kind => ConstantValueKind.LIST;
529
495 String toDartText() { 530 String toDartText() {
496 StringBuffer sb = new StringBuffer(); 531 StringBuffer sb = new StringBuffer();
497 _unparseTypeArguments(sb); 532 _unparseTypeArguments(sb);
498 sb.write('['); 533 sb.write('[');
499 for (int i = 0; i < length; i++) { 534 for (int i = 0; i < length; i++) {
500 if (i > 0) sb.write(','); 535 if (i > 0) sb.write(',');
501 sb.write(entries[i].toDartText()); 536 sb.write(entries[i].toDartText());
502 } 537 }
503 sb.write(']'); 538 sb.write(']');
504 return sb.toString(); 539 return sb.toString();
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
560 int get length => keys.length; 595 int get length => keys.length;
561 596
562 ConstantValue lookup(ConstantValue key) { 597 ConstantValue lookup(ConstantValue key) {
563 var lookupMap = _lookupMap ??= 598 var lookupMap = _lookupMap ??=
564 new Map<ConstantValue, ConstantValue>.fromIterables(keys, values); 599 new Map<ConstantValue, ConstantValue>.fromIterables(keys, values);
565 return lookupMap[key]; 600 return lookupMap[key];
566 } 601 }
567 602
568 accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg); 603 accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
569 604
605 ConstantValueKind get kind => ConstantValueKind.MAP;
606
570 String toDartText() { 607 String toDartText() {
571 StringBuffer sb = new StringBuffer(); 608 StringBuffer sb = new StringBuffer();
572 _unparseTypeArguments(sb); 609 _unparseTypeArguments(sb);
573 sb.write('{'); 610 sb.write('{');
574 for (int i = 0; i < length; i++) { 611 for (int i = 0; i < length; i++) {
575 if (i > 0) sb.write(','); 612 if (i > 0) sb.write(',');
576 sb.write(keys[i].toDartText()); 613 sb.write(keys[i].toDartText());
577 sb.write(':'); 614 sb.write(':');
578 sb.write(values[i].toDartText()); 615 sb.write(values[i].toDartText());
579 } 616 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 int get hashCode => dispatchedType.hashCode * 43; 651 int get hashCode => dispatchedType.hashCode * 43;
615 652
616 List<ConstantValue> getDependencies() => const <ConstantValue>[]; 653 List<ConstantValue> getDependencies() => const <ConstantValue>[];
617 654
618 accept(ConstantValueVisitor visitor, arg) { 655 accept(ConstantValueVisitor visitor, arg) {
619 return visitor.visitInterceptor(this, arg); 656 return visitor.visitInterceptor(this, arg);
620 } 657 }
621 658
622 DartType getType(CoreTypes types) => const DynamicType(); 659 DartType getType(CoreTypes types) => const DynamicType();
623 660
661 ConstantValueKind get kind => ConstantValueKind.INTERCEPTOR;
662
624 String toDartText() { 663 String toDartText() {
625 return 'interceptor($dispatchedType)'; 664 return 'interceptor($dispatchedType)';
626 } 665 }
627 666
628 String toStructuredText() { 667 String toStructuredText() {
629 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})'; 668 return 'InterceptorConstant(${dispatchedType.getStringAsDeclared("o")})';
630 } 669 }
631 } 670 }
632 671
633 class SyntheticConstantValue extends ConstantValue { 672 class SyntheticConstantValue extends ConstantValue {
634 final payload; 673 final payload;
635 final kind; 674 final valueKind;
636 675
637 SyntheticConstantValue(this.kind, this.payload); 676 SyntheticConstantValue(this.valueKind, this.payload);
638 677
639 bool get isDummy => true; 678 bool get isDummy => true;
640 679
641 bool operator ==(other) { 680 bool operator ==(other) {
642 return other is SyntheticConstantValue && payload == other.payload; 681 return other is SyntheticConstantValue && payload == other.payload;
643 } 682 }
644 683
645 get hashCode => payload.hashCode * 17 + kind.hashCode; 684 get hashCode => payload.hashCode * 17 + valueKind.hashCode;
646 685
647 List<ConstantValue> getDependencies() => const <ConstantValue>[]; 686 List<ConstantValue> getDependencies() => const <ConstantValue>[];
648 687
649 accept(ConstantValueVisitor visitor, arg) { 688 accept(ConstantValueVisitor visitor, arg) {
650 return visitor.visitSynthetic(this, arg); 689 return visitor.visitSynthetic(this, arg);
651 } 690 }
652 691
653 DartType getType(CoreTypes types) => const DynamicType(); 692 DartType getType(CoreTypes types) => const DynamicType();
654 693
655 String toDartText() => 'synthetic($kind, $payload)'; 694 ConstantValueKind get kind => ConstantValueKind.SYNTHETIC;
656 695
657 String toStructuredText() => 'SyntheticConstant($kind, $payload)'; 696 String toDartText() => 'synthetic($valueKind, $payload)';
697
698 String toStructuredText() => 'SyntheticConstant($valueKind, $payload)';
658 } 699 }
659 700
660 class ConstructedConstantValue extends ObjectConstantValue { 701 class ConstructedConstantValue extends ObjectConstantValue {
661 // TODO(johnniwinther): Make [fields] private to avoid misuse of the map 702 // TODO(johnniwinther): Make [fields] private to avoid misuse of the map
662 // ordering and mutability. 703 // ordering and mutability.
663 final Map<FieldElement, ConstantValue> fields; 704 final Map<FieldElement, ConstantValue> fields;
664 final int hashCode; 705 final int hashCode;
665 706
666 ConstructedConstantValue( 707 ConstructedConstantValue(
667 InterfaceType type, Map<FieldElement, ConstantValue> fields) 708 InterfaceType type, Map<FieldElement, ConstantValue> fields)
(...skipping 18 matching lines...) Expand all
686 } 727 }
687 return true; 728 return true;
688 } 729 }
689 730
690 List<ConstantValue> getDependencies() => fields.values.toList(); 731 List<ConstantValue> getDependencies() => fields.values.toList();
691 732
692 accept(ConstantValueVisitor visitor, arg) { 733 accept(ConstantValueVisitor visitor, arg) {
693 return visitor.visitConstructed(this, arg); 734 return visitor.visitConstructed(this, arg);
694 } 735 }
695 736
737 ConstantValueKind get kind => ConstantValueKind.CONSTRUCTED;
738
696 String toDartText() { 739 String toDartText() {
697 StringBuffer sb = new StringBuffer(); 740 StringBuffer sb = new StringBuffer();
698 sb.write(type.name); 741 sb.write(type.name);
699 _unparseTypeArguments(sb); 742 _unparseTypeArguments(sb);
700 sb.write('('); 743 sb.write('(');
701 int i = 0; 744 int i = 0;
702 fields.forEach((FieldElement field, ConstantValue value) { 745 fields.forEach((FieldElement field, ConstantValue value) {
703 if (i > 0) sb.write(','); 746 if (i > 0) sb.write(',');
704 sb.write(field.name); 747 sb.write(field.name);
705 sb.write('='); 748 sb.write('=');
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
745 } 788 }
746 789
747 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff; 790 get hashCode => (referenced.hashCode * 17 + prefix.hashCode) & 0x3fffffff;
748 791
749 List<ConstantValue> getDependencies() => <ConstantValue>[referenced]; 792 List<ConstantValue> getDependencies() => <ConstantValue>[referenced];
750 793
751 accept(ConstantValueVisitor visitor, arg) => visitor.visitDeferred(this, arg); 794 accept(ConstantValueVisitor visitor, arg) => visitor.visitDeferred(this, arg);
752 795
753 DartType getType(CoreTypes types) => referenced.getType(types); 796 DartType getType(CoreTypes types) => referenced.getType(types);
754 797
798 ConstantValueKind get kind => ConstantValueKind.DEFERRED;
799
755 String toDartText() => 'deferred(${referenced.toDartText()})'; 800 String toDartText() => 'deferred(${referenced.toDartText()})';
756 801
757 String toStructuredText() { 802 String toStructuredText() {
758 return 'DeferredConstant(${referenced.toStructuredText()})'; 803 return 'DeferredConstant(${referenced.toStructuredText()})';
759 } 804 }
760 } 805 }
761 806
762 /// A constant value resulting from a non constant or erroneous constant 807 /// A constant value resulting from a non constant or erroneous constant
763 /// expression. 808 /// expression.
764 // TODO(johnniwinther): Expand this to contain the error kind. 809 // TODO(johnniwinther): Expand this to contain the error kind.
765 class NonConstantValue extends ConstantValue { 810 class NonConstantValue extends ConstantValue {
766 bool get isConstant => false; 811 bool get isConstant => false;
767 812
768 @override 813 @override
769 accept(ConstantValueVisitor visitor, arg) { 814 accept(ConstantValueVisitor visitor, arg) {
770 return visitor.visitNonConstant(this, arg); 815 return visitor.visitNonConstant(this, arg);
771 } 816 }
772 817
773 @override 818 @override
774 List<ConstantValue> getDependencies() => const <ConstantValue>[]; 819 List<ConstantValue> getDependencies() => const <ConstantValue>[];
775 820
776 @override 821 @override
777 DartType getType(CoreTypes types) => const DynamicType(); 822 DartType getType(CoreTypes types) => const DynamicType();
778 823
824 ConstantValueKind get kind => ConstantValueKind.NON_CONSTANT;
825
779 @override 826 @override
780 String toStructuredText() => 'NonConstant'; 827 String toStructuredText() => 'NonConstant';
781 828
782 @override 829 @override
783 String toDartText() => '>>non-constant<<'; 830 String toDartText() => '>>non-constant<<';
784 } 831 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/js_backend/constant_emitter.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698