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

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

Issue 1955403002: Skip spurious constants in deferred computation. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 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
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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.expressions; 5 library dart2js.constants.expressions;
6 6
7 import '../common.dart'; 7 import '../common.dart';
8 import '../constants/constant_system.dart'; 8 import '../constants/constant_system.dart';
9 import '../core_types.dart'; 9 import '../core_types.dart';
10 import '../dart_types.dart'; 10 import '../dart_types.dart';
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 if (hashCode != other.hashCode) return false; 117 if (hashCode != other.hashCode) return false;
118 return _equals(other); 118 return _equals(other);
119 } 119 }
120 120
121 String toString() { 121 String toString() {
122 assertDebugMode('Use ConstantExpression.toDartText() or ' 122 assertDebugMode('Use ConstantExpression.toDartText() or '
123 'ConstantExpression.toStructuredText() instead of ' 123 'ConstantExpression.toStructuredText() instead of '
124 'ConstantExpression.toString()'); 124 'ConstantExpression.toString()');
125 return toDartText(); 125 return toDartText();
126 } 126 }
127
128 /// Returns `true` if this expression is implicitly constant, that is, that
129 /// it doesn't declare its constness with the 'const' keyword.
130 ///
131 /// Implicit constants are simple literals, like bool, int and string
132 /// literals, constant references and compositions of implicit constants.
133 /// Explicit constants are constructor constants, and constant map and list
134 /// literals.
135 bool get isImplicit => true;
136
137 /// Returns `true` if this expression is only potentially constant, that is,
138 /// if it contains positional or named references, used to defined constant
Siggi Cherem (dart-lang) 2016/05/09 20:03:04 to defined => to define?
Johnni Winther 2016/05/10 09:26:16 Done.
139 /// constructors.
140 bool get isPotential => true;
Siggi Cherem (dart-lang) 2016/05/09 20:03:04 should we make this a final field instead? In all
Johnni Winther 2016/05/10 09:26:15 I think it'll only be need for asserts, in which c
127 } 141 }
128 142
129 /// A synthetic constant used to recover from errors. 143 /// A synthetic constant used to recover from errors.
130 class ErroneousConstantExpression extends ConstantExpression { 144 class ErroneousConstantExpression extends ConstantExpression {
131 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; 145 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS;
132 146
133 accept(ConstantExpressionVisitor visitor, [context]) { 147 accept(ConstantExpressionVisitor visitor, [context]) {
134 // Do nothing. This is an error. 148 // Do nothing. This is an error.
135 } 149 }
136 150
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 accept(ConstantExpressionVisitor visitor, [context]) { 190 accept(ConstantExpressionVisitor visitor, [context]) {
177 throw "unsupported"; 191 throw "unsupported";
178 } 192 }
179 193
180 @override 194 @override
181 bool _equals(SyntheticConstantExpression other) { 195 bool _equals(SyntheticConstantExpression other) {
182 return value == other.value; 196 return value == other.value;
183 } 197 }
184 198
185 ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC; 199 ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC;
200
201 @override
202 bool get isPotential => false;
203
204 @override
205 bool get isImplicit => false;
186 } 206 }
187 207
188 /// A boolean, int, double, string, or null constant. 208 /// A boolean, int, double, string, or null constant.
189 abstract class PrimitiveConstantExpression extends ConstantExpression { 209 abstract class PrimitiveConstantExpression extends ConstantExpression {
190 /// The primitive value of this contant expression. 210 /// The primitive value of this contant expression.
191 get primitiveValue; 211 get primitiveValue;
192 } 212 }
193 213
194 /// Boolean literal constant. 214 /// Boolean literal constant.
195 class BoolConstantExpression extends PrimitiveConstantExpression { 215 class BoolConstantExpression extends PrimitiveConstantExpression {
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 if (type != other.type) return false; 435 if (type != other.type) return false;
416 if (values.length != other.values.length) return false; 436 if (values.length != other.values.length) return false;
417 for (int i = 0; i < values.length; i++) { 437 for (int i = 0; i < values.length; i++) {
418 if (values[i] != other.values[i]) return false; 438 if (values[i] != other.values[i]) return false;
419 } 439 }
420 return true; 440 return true;
421 } 441 }
422 442
423 @override 443 @override
424 DartType getKnownType(CoreTypes coreTypes) => type; 444 DartType getKnownType(CoreTypes coreTypes) => type;
445
446 @override
447 bool get isImplicit => false;
448
449 @override
450 bool get isPotential => values.any((e) => e.isPotential);
425 } 451 }
426 452
427 /// Literal map constant. 453 /// Literal map constant.
428 class MapConstantExpression extends ConstantExpression { 454 class MapConstantExpression extends ConstantExpression {
429 final InterfaceType type; 455 final InterfaceType type;
430 final List<ConstantExpression> keys; 456 final List<ConstantExpression> keys;
431 final List<ConstantExpression> values; 457 final List<ConstantExpression> values;
432 458
433 MapConstantExpression(this.type, this.keys, this.values); 459 MapConstantExpression(this.type, this.keys, this.values);
434 460
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 if (values.length != other.values.length) return false; 510 if (values.length != other.values.length) return false;
485 for (int i = 0; i < values.length; i++) { 511 for (int i = 0; i < values.length; i++) {
486 if (keys[i] != other.keys[i]) return false; 512 if (keys[i] != other.keys[i]) return false;
487 if (values[i] != other.values[i]) return false; 513 if (values[i] != other.values[i]) return false;
488 } 514 }
489 return true; 515 return true;
490 } 516 }
491 517
492 @override 518 @override
493 DartType getKnownType(CoreTypes coreTypes) => type; 519 DartType getKnownType(CoreTypes coreTypes) => type;
520
521 @override
522 bool get isImplicit => false;
523
524 @override
525 bool get isPotential {
526 return keys.any((e) => e.isPotential) || values.any((e) => e.isPotential);
527 }
494 } 528 }
495 529
496 /// Invocation of a const constructor. 530 /// Invocation of a const constructor.
497 class ConstructedConstantExpression extends ConstantExpression { 531 class ConstructedConstantExpression extends ConstantExpression {
498 final InterfaceType type; 532 final InterfaceType type;
499 final ConstructorElement target; 533 final ConstructorElement target;
500 final CallStructure callStructure; 534 final CallStructure callStructure;
501 final List<ConstantExpression> arguments; 535 final List<ConstantExpression> arguments;
502 536
503 ConstructedConstantExpression( 537 ConstructedConstantExpression(
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 @override 598 @override
565 bool _equals(ConstructedConstantExpression other) { 599 bool _equals(ConstructedConstantExpression other) {
566 if (type != other.type) return false; 600 if (type != other.type) return false;
567 if (target != other.target) return false; 601 if (target != other.target) return false;
568 if (callStructure != other.callStructure) return false; 602 if (callStructure != other.callStructure) return false;
569 for (int i = 0; i < arguments.length; i++) { 603 for (int i = 0; i < arguments.length; i++) {
570 if (arguments[i] != other.arguments[i]) return false; 604 if (arguments[i] != other.arguments[i]) return false;
571 } 605 }
572 return true; 606 return true;
573 } 607 }
608
609 @override
610 bool get isImplicit => false;
611
612 @override
613 bool get isPotential {
614 return arguments.any((e) => e.isPotential);
615 }
574 } 616 }
575 617
576 /// String literal with juxtaposition and/or interpolations. 618 /// String literal with juxtaposition and/or interpolations.
577 class ConcatenateConstantExpression extends ConstantExpression { 619 class ConcatenateConstantExpression extends ConstantExpression {
578 final List<ConstantExpression> expressions; 620 final List<ConstantExpression> expressions;
579 621
580 ConcatenateConstantExpression(this.expressions); 622 ConcatenateConstantExpression(this.expressions);
581 623
582 ConstantExpressionKind get kind => ConstantExpressionKind.CONCATENATE; 624 ConstantExpressionKind get kind => ConstantExpressionKind.CONCATENATE;
583 625
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 bool _equals(ConcatenateConstantExpression other) { 685 bool _equals(ConcatenateConstantExpression other) {
644 if (expressions.length != other.expressions.length) return false; 686 if (expressions.length != other.expressions.length) return false;
645 for (int i = 0; i < expressions.length; i++) { 687 for (int i = 0; i < expressions.length; i++) {
646 if (expressions[i] != other.expressions[i]) return false; 688 if (expressions[i] != other.expressions[i]) return false;
647 } 689 }
648 return true; 690 return true;
649 } 691 }
650 692
651 @override 693 @override
652 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType; 694 DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
695
696 @override
697 bool get isPotential {
698 return expressions.any((e) => e.isPotential);
699 }
653 } 700 }
654 701
655 /// Symbol literal. 702 /// Symbol literal.
656 class SymbolConstantExpression extends ConstantExpression { 703 class SymbolConstantExpression extends ConstantExpression {
657 final String name; 704 final String name;
658 705
659 SymbolConstantExpression(this.name); 706 SymbolConstantExpression(this.name);
660 707
661 ConstantExpressionKind get kind => ConstantExpressionKind.SYMBOL; 708 ConstantExpressionKind get kind => ConstantExpressionKind.SYMBOL;
662 709
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 return 13 * operator.hashCode + 17 * left.hashCode + 19 * right.hashCode; 935 return 13 * operator.hashCode + 17 * left.hashCode + 19 * right.hashCode;
889 } 936 }
890 937
891 @override 938 @override
892 bool _equals(BinaryConstantExpression other) { 939 bool _equals(BinaryConstantExpression other) {
893 return operator == other.operator && 940 return operator == other.operator &&
894 left == other.left && 941 left == other.left &&
895 right == other.right; 942 right == other.right;
896 } 943 }
897 944
945 @override
946 bool get isPotential {
947 return left.isPotential || right.isPotential;
948 }
949
898 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const { 950 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const {
899 BinaryOperatorKind.EQ: 6, 951 BinaryOperatorKind.EQ: 6,
900 BinaryOperatorKind.NOT_EQ: 6, 952 BinaryOperatorKind.NOT_EQ: 6,
901 BinaryOperatorKind.LOGICAL_AND: 5, 953 BinaryOperatorKind.LOGICAL_AND: 5,
902 BinaryOperatorKind.LOGICAL_OR: 4, 954 BinaryOperatorKind.LOGICAL_OR: 4,
903 BinaryOperatorKind.XOR: 9, 955 BinaryOperatorKind.XOR: 9,
904 BinaryOperatorKind.AND: 10, 956 BinaryOperatorKind.AND: 10,
905 BinaryOperatorKind.OR: 8, 957 BinaryOperatorKind.OR: 8,
906 BinaryOperatorKind.SHR: 11, 958 BinaryOperatorKind.SHR: 11,
907 BinaryOperatorKind.SHL: 11, 959 BinaryOperatorKind.SHL: 11,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
961 return 17 * left.hashCode + 19 * right.hashCode; 1013 return 17 * left.hashCode + 19 * right.hashCode;
962 } 1014 }
963 1015
964 @override 1016 @override
965 bool _equals(IdenticalConstantExpression other) { 1017 bool _equals(IdenticalConstantExpression other) {
966 return left == other.left && right == other.right; 1018 return left == other.left && right == other.right;
967 } 1019 }
968 1020
969 @override 1021 @override
970 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType; 1022 DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
1023
1024 @override
1025 bool get isPotential {
1026 return left.isPotential || right.isPotential;
1027 }
971 } 1028 }
972 1029
973 /// A unary constant expression like `-a`. 1030 /// A unary constant expression like `-a`.
974 class UnaryConstantExpression extends ConstantExpression { 1031 class UnaryConstantExpression extends ConstantExpression {
975 final UnaryOperator operator; 1032 final UnaryOperator operator;
976 final ConstantExpression expression; 1033 final ConstantExpression expression;
977 1034
978 UnaryConstantExpression(this.operator, this.expression) { 1035 UnaryConstantExpression(this.operator, this.expression) {
979 assert(PRECEDENCE_MAP[operator.kind] != null); 1036 assert(PRECEDENCE_MAP[operator.kind] != null);
980 } 1037 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 @override 1071 @override
1015 bool _equals(UnaryConstantExpression other) { 1072 bool _equals(UnaryConstantExpression other) {
1016 return operator == other.operator && expression == other.expression; 1073 return operator == other.operator && expression == other.expression;
1017 } 1074 }
1018 1075
1019 @override 1076 @override
1020 DartType getKnownType(CoreTypes coreTypes) { 1077 DartType getKnownType(CoreTypes coreTypes) {
1021 return expression.getKnownType(coreTypes); 1078 return expression.getKnownType(coreTypes);
1022 } 1079 }
1023 1080
1081 @override
1082 bool get isPotential {
1083 return expression.isPotential;
1084 }
1085
1024 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const { 1086 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const {
1025 UnaryOperatorKind.NOT: 14, 1087 UnaryOperatorKind.NOT: 14,
1026 UnaryOperatorKind.COMPLEMENT: 14, 1088 UnaryOperatorKind.COMPLEMENT: 14,
1027 UnaryOperatorKind.NEGATE: 14, 1089 UnaryOperatorKind.NEGATE: 14,
1028 }; 1090 };
1029 } 1091 }
1030 1092
1031 /// A string length constant expression like `a.length`. 1093 /// A string length constant expression like `a.length`.
1032 class StringLengthConstantExpression extends ConstantExpression { 1094 class StringLengthConstantExpression extends ConstantExpression {
1033 final ConstantExpression expression; 1095 final ConstantExpression expression;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1069 return 23 * expression.hashCode; 1131 return 23 * expression.hashCode;
1070 } 1132 }
1071 1133
1072 @override 1134 @override
1073 bool _equals(StringLengthConstantExpression other) { 1135 bool _equals(StringLengthConstantExpression other) {
1074 return expression == other.expression; 1136 return expression == other.expression;
1075 } 1137 }
1076 1138
1077 @override 1139 @override
1078 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType; 1140 DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
1141
1142 @override
1143 bool get isPotential {
1144 return expression.isPotential;
1145 }
1079 } 1146 }
1080 1147
1081 /// A constant conditional expression like `a ? b : c`. 1148 /// A constant conditional expression like `a ? b : c`.
1082 class ConditionalConstantExpression extends ConstantExpression { 1149 class ConditionalConstantExpression extends ConstantExpression {
1083 final ConstantExpression condition; 1150 final ConstantExpression condition;
1084 final ConstantExpression trueExp; 1151 final ConstantExpression trueExp;
1085 final ConstantExpression falseExp; 1152 final ConstantExpression falseExp;
1086 1153
1087 ConditionalConstantExpression(this.condition, this.trueExp, this.falseExp); 1154 ConditionalConstantExpression(this.condition, this.trueExp, this.falseExp);
1088 1155
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1142 1209
1143 @override 1210 @override
1144 DartType getKnownType(CoreTypes coreTypes) { 1211 DartType getKnownType(CoreTypes coreTypes) {
1145 DartType trueType = trueExp.getKnownType(coreTypes); 1212 DartType trueType = trueExp.getKnownType(coreTypes);
1146 DartType falseType = falseExp.getKnownType(coreTypes); 1213 DartType falseType = falseExp.getKnownType(coreTypes);
1147 if (trueType == falseType) { 1214 if (trueType == falseType) {
1148 return trueType; 1215 return trueType;
1149 } 1216 }
1150 return null; 1217 return null;
1151 } 1218 }
1219
1220 @override
1221 bool get isPotential {
1222 return condition.isPotential || trueExp.isPotential || falseExp.isPotential;
1223 }
1152 } 1224 }
1153 1225
1154 /// A reference to a position parameter. 1226 /// A reference to a position parameter.
1155 class PositionalArgumentReference extends ConstantExpression { 1227 class PositionalArgumentReference extends ConstantExpression {
1156 final int index; 1228 final int index;
1157 1229
1158 PositionalArgumentReference(this.index); 1230 PositionalArgumentReference(this.index);
1159 1231
1160 ConstantExpressionKind get kind { 1232 ConstantExpressionKind get kind {
1161 return ConstantExpressionKind.POSITIONAL_REFERENCE; 1233 return ConstantExpressionKind.POSITIONAL_REFERENCE;
(...skipping 16 matching lines...) Expand all
1178 int _computeHashCode() => 13 * index.hashCode; 1250 int _computeHashCode() => 13 * index.hashCode;
1179 1251
1180 @override 1252 @override
1181 bool _equals(PositionalArgumentReference other) => index == other.index; 1253 bool _equals(PositionalArgumentReference other) => index == other.index;
1182 1254
1183 @override 1255 @override
1184 ConstantValue evaluate( 1256 ConstantValue evaluate(
1185 Environment environment, ConstantSystem constantSystem) { 1257 Environment environment, ConstantSystem constantSystem) {
1186 throw new UnsupportedError('PositionalArgumentReference.evaluate'); 1258 throw new UnsupportedError('PositionalArgumentReference.evaluate');
1187 } 1259 }
1260
1261 @override
1262 bool get isPotential {
1263 return true;
1264 }
1188 } 1265 }
1189 1266
1190 /// A reference to a named parameter. 1267 /// A reference to a named parameter.
1191 class NamedArgumentReference extends ConstantExpression { 1268 class NamedArgumentReference extends ConstantExpression {
1192 final String name; 1269 final String name;
1193 1270
1194 NamedArgumentReference(this.name); 1271 NamedArgumentReference(this.name);
1195 1272
1196 ConstantExpressionKind get kind { 1273 ConstantExpressionKind get kind {
1197 return ConstantExpressionKind.NAMED_REFERENCE; 1274 return ConstantExpressionKind.NAMED_REFERENCE;
(...skipping 16 matching lines...) Expand all
1214 int _computeHashCode() => 13 * name.hashCode; 1291 int _computeHashCode() => 13 * name.hashCode;
1215 1292
1216 @override 1293 @override
1217 bool _equals(NamedArgumentReference other) => name == other.name; 1294 bool _equals(NamedArgumentReference other) => name == other.name;
1218 1295
1219 @override 1296 @override
1220 ConstantValue evaluate( 1297 ConstantValue evaluate(
1221 Environment environment, ConstantSystem constantSystem) { 1298 Environment environment, ConstantSystem constantSystem) {
1222 throw new UnsupportedError('NamedArgumentReference.evaluate'); 1299 throw new UnsupportedError('NamedArgumentReference.evaluate');
1223 } 1300 }
1301
1302 @override
1303 bool get isPotential {
1304 return true;
1305 }
1224 } 1306 }
1225 1307
1226 abstract class FromEnvironmentConstantExpression extends ConstantExpression { 1308 abstract class FromEnvironmentConstantExpression extends ConstantExpression {
1227 final ConstantExpression name; 1309 final ConstantExpression name;
1228 final ConstantExpression defaultValue; 1310 final ConstantExpression defaultValue;
1229 1311
1230 FromEnvironmentConstantExpression(this.name, this.defaultValue); 1312 FromEnvironmentConstantExpression(this.name, this.defaultValue);
1231 1313
1232 @override 1314 @override
1233 int _computeHashCode() { 1315 int _computeHashCode() {
1234 return 13 * name.hashCode + 17 * defaultValue.hashCode; 1316 return 13 * name.hashCode + 17 * defaultValue.hashCode;
1235 } 1317 }
1236 1318
1237 @override 1319 @override
1238 bool _equals(FromEnvironmentConstantExpression other) { 1320 bool _equals(FromEnvironmentConstantExpression other) {
1239 return name == other.name && defaultValue == other.defaultValue; 1321 return name == other.name && defaultValue == other.defaultValue;
1240 } 1322 }
1323
1324 @override
1325 bool get isImplicit {
1326 return false;
1327 }
1328
1329 @override
1330 bool get isPotential {
1331 return name.isPotential ||
1332 (defaultValue != null && defaultValue.isPotential);
1333 }
1241 } 1334 }
1242 1335
1243 /// A `const bool.fromEnvironment` constant. 1336 /// A `const bool.fromEnvironment` constant.
1244 class BoolFromEnvironmentConstantExpression 1337 class BoolFromEnvironmentConstantExpression
1245 extends FromEnvironmentConstantExpression { 1338 extends FromEnvironmentConstantExpression {
1246 BoolFromEnvironmentConstantExpression( 1339 BoolFromEnvironmentConstantExpression(
1247 ConstantExpression name, ConstantExpression defaultValue) 1340 ConstantExpression name, ConstantExpression defaultValue)
1248 : super(name, defaultValue); 1341 : super(name, defaultValue);
1249 1342
1250 ConstantExpressionKind get kind { 1343 ConstantExpressionKind get kind {
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1464 1557
1465 @override 1558 @override
1466 bool _equals(DeferredConstantExpression other) { 1559 bool _equals(DeferredConstantExpression other) {
1467 return expression == other.expression; 1560 return expression == other.expression;
1468 } 1561 }
1469 1562
1470 @override 1563 @override
1471 accept(ConstantExpressionVisitor visitor, [context]) { 1564 accept(ConstantExpressionVisitor visitor, [context]) {
1472 return visitor.visitDeferred(this, context); 1565 return visitor.visitDeferred(this, context);
1473 } 1566 }
1567
1568 @override
1569 bool get isPotential {
1570 return expression.isPotential;
1571 }
1474 } 1572 }
1475 1573
1476 abstract class ConstantExpressionVisitor<R, A> { 1574 abstract class ConstantExpressionVisitor<R, A> {
1477 const ConstantExpressionVisitor(); 1575 const ConstantExpressionVisitor();
1478 1576
1479 R visit(ConstantExpression constant, A context) { 1577 R visit(ConstantExpression constant, A context) {
1480 return constant.accept(this, context); 1578 return constant.accept(this, context);
1481 } 1579 }
1482 1580
1483 R visitBool(BoolConstantExpression exp, A context); 1581 R visitBool(BoolConstantExpression exp, A context);
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
1772 visit(exp.name); 1870 visit(exp.name);
1773 if (exp.defaultValue != null) { 1871 if (exp.defaultValue != null) {
1774 sb.write(', defaultValue: '); 1872 sb.write(', defaultValue: ');
1775 visit(exp.defaultValue); 1873 visit(exp.defaultValue);
1776 } 1874 }
1777 sb.write(')'); 1875 sb.write(')');
1778 } 1876 }
1779 1877
1780 String toString() => sb.toString(); 1878 String toString() => sb.toString();
1781 } 1879 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698