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

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

Issue 1050133006: Add structural equality to ConstantExpression. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebased Created 5 years, 8 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) 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 '../dart2jslib.dart' show assertDebugMode; 7 import '../dart2jslib.dart' show assertDebugMode;
8 import '../dart_types.dart'; 8 import '../dart_types.dart';
9 import '../elements/elements.dart' show 9 import '../elements/elements.dart' show
10 ConstructorElement,
10 Element, 11 Element,
11 FunctionElement, 12 FunctionElement,
12 VariableElement; 13 VariableElement;
13 import '../resolution/operators.dart'; 14 import '../resolution/operators.dart';
14 import '../universe/universe.dart' show CallStructure; 15 import '../universe/universe.dart' show CallStructure;
15 import 'values.dart'; 16 import 'values.dart';
16 17
18 enum ConstantExpressionKind {
19 BINARY,
20 BOOL,
21 CONCATENATE,
22 CONDITIONAL,
23 CONSTRUCTED,
24 DOUBLE,
25 ERRONEOUS,
26 FUNCTION,
27 IDENTICAL,
28 INT,
29 LIST,
30 MAP,
31 NULL,
32 STRING,
33 SYMBOL,
34 TYPE,
35 UNARY,
36 VARIABLE,
37 }
38
17 /// An expression that is a compile-time constant. 39 /// An expression that is a compile-time constant.
18 /// 40 ///
19 /// Whereas [ConstantValue] represent a compile-time value, a 41 /// Whereas [ConstantValue] represent a compile-time value, a
20 /// [ConstantExpression] represents an expression for creating a constant. 42 /// [ConstantExpression] represents an expression for creating a constant.
21 /// 43 ///
22 /// There is no one-to-one mapping between [ConstantExpression] and 44 /// There is no one-to-one mapping between [ConstantExpression] and
23 /// [ConstantValue], because different expressions can denote the same constant. 45 /// [ConstantValue], because different expressions can denote the same constant.
24 /// For instance, multiple `const` constructors may be used to create the same 46 /// For instance, multiple `const` constructors may be used to create the same
25 /// object, and different `const` variables may hold the same value. 47 /// object, and different `const` variables may hold the same value.
26 abstract class ConstantExpression { 48 abstract class ConstantExpression {
49 int _hashCode;
50
51 ConstantExpressionKind get kind;
52
27 /// Returns the value of this constant expression. 53 /// Returns the value of this constant expression.
28 ConstantValue get value; 54 ConstantValue get value;
29 55
30 // TODO(johnniwinther): Unify precedence handled between constants, front-end 56 // TODO(johnniwinther): Unify precedence handled between constants, front-end
31 // and back-end. 57 // and back-end.
32 int get precedence => 16; 58 int get precedence => 16;
33 59
34 accept(ConstantExpressionVisitor visitor, [context]); 60 accept(ConstantExpressionVisitor visitor, [context]);
35 61
36 String getText() { 62 String getText() {
37 ConstExpPrinter printer = new ConstExpPrinter(); 63 ConstExpPrinter printer = new ConstExpPrinter();
38 accept(printer); 64 accept(printer);
39 return printer.toString(); 65 return printer.toString();
40 } 66 }
41 67
68 int _computeHashCode();
69
70 int get hashCode {
71 if (_hashCode == null) {
72 _hashCode = _computeHashCode();
73 }
74 return _hashCode;
75 }
76
77 bool _equals(ConstantExpression other);
78
79 bool operator ==(other) {
80 if (identical(this, other)) return true;
81 if (other is! ConstantExpression) return false;
82 if (kind != other.kind) return false;
83 if (hashCode != other.hashCode) return false;
84 return _equals(other);
85 }
86
42 String toString() { 87 String toString() {
43 assertDebugMode('Use ConstantExpression.getText() instead of ' 88 assertDebugMode('Use ConstantExpression.getText() instead of '
44 'ConstantExpression.toString()'); 89 'ConstantExpression.toString()');
45 return getText(); 90 return getText();
46 } 91 }
47 } 92 }
48 93
49 /// A synthetic constant used to recover from errors. 94 /// A synthetic constant used to recover from errors.
50 class ErroneousConstantExpression extends ConstantExpression { 95 class ErroneousConstantExpression extends ConstantExpression {
51 final PrimitiveConstantValue value = new NullConstantValue(); 96 final PrimitiveConstantValue value = new NullConstantValue();
52 97
53 ErroneousConstantExpression(); 98 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS;
54 99
55 accept(ConstantExpressionVisitor visitor, [context]) { 100 accept(ConstantExpressionVisitor visitor, [context]) {
56 // Do nothing. This is an error. 101 // Do nothing. This is an error.
57 } 102 }
103
104 @override
105 int _computeHashCode() => 13;
106
107 @override
108 bool _equals(ErroneousConstantExpression other) => true;
58 } 109 }
59 110
60 /// Boolean, int, double, string, or null constant. 111 /// A boolean, int, double, string, or null constant.
61 class PrimitiveConstantExpression extends ConstantExpression { 112 abstract class PrimitiveConstantExpression extends ConstantExpression {
62 final PrimitiveConstantValue value; 113 final PrimitiveConstantValue value;
63 114
64 PrimitiveConstantExpression(this.value) { 115 PrimitiveConstantExpression(this.value);
65 assert(value != null); 116
66 } 117 /// The primitive value of this contant expression.
118 get primitiveValue;
67 119
68 accept(ConstantExpressionVisitor visitor, [context]) { 120 accept(ConstantExpressionVisitor visitor, [context]) {
69 return visitor.visitPrimitive(this, context); 121 return visitor.visitPrimitive(this, context);
70 } 122 }
71 } 123 }
72 124
125 /// Boolean literal constant.
126 class BoolConstantExpression extends PrimitiveConstantExpression {
127 final bool primitiveValue;
128
129 BoolConstantExpression(this.primitiveValue,
130 PrimitiveConstantValue value) : super(value);
131
132 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL;
133
134 @override
135 int _computeHashCode() => 13 * primitiveValue.hashCode;
136
137 @override
138 bool _equals(BoolConstantExpression other) {
139 return primitiveValue == other.primitiveValue;
140 }
141 }
142
143 /// Integer literal constant.
144 class IntConstantExpression extends PrimitiveConstantExpression {
145 final int primitiveValue;
146
147 IntConstantExpression(this.primitiveValue,
148 PrimitiveConstantValue value) : super(value);
149
150 ConstantExpressionKind get kind => ConstantExpressionKind.INT;
151
152 @override
153 int _computeHashCode() => 17 * primitiveValue.hashCode;
154
155 @override
156 bool _equals(IntConstantExpression other) {
157 return primitiveValue == other.primitiveValue;
158 }
159 }
160
161 /// Double literal constant.
162 class DoubleConstantExpression extends PrimitiveConstantExpression {
163 final double primitiveValue;
164
165 DoubleConstantExpression(this.primitiveValue,
166 PrimitiveConstantValue value) : super(value);
167
168 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE;
169
170 @override
171 int _computeHashCode() => 19 * primitiveValue.hashCode;
172
173 @override
174 bool _equals(DoubleConstantExpression other) {
175 return primitiveValue == other.primitiveValue;
176 }
177 }
178
179 /// String literal constant.
180 class StringConstantExpression extends PrimitiveConstantExpression {
181 final String primitiveValue;
182
183 StringConstantExpression(this.primitiveValue,
184 PrimitiveConstantValue value) : super(value);
185
186 ConstantExpressionKind get kind => ConstantExpressionKind.STRING;
187
188 @override
189 int _computeHashCode() => 23 * primitiveValue.hashCode;
190
191 @override
192 bool _equals(StringConstantExpression other) {
193 return primitiveValue == other.primitiveValue;
194 }
195 }
196
197 /// Null literal constant.
198 class NullConstantExpression extends PrimitiveConstantExpression {
199 NullConstantExpression(PrimitiveConstantValue value) : super(value);
200
201 ConstantExpressionKind get kind => ConstantExpressionKind.NULL;
202
203 get primitiveValue => null;
204
205 @override
206 int _computeHashCode() => 29;
207
208 @override
209 bool _equals(NullConstantExpression other) => true;
210 }
211
73 /// Literal list constant. 212 /// Literal list constant.
74 class ListConstantExpression extends ConstantExpression { 213 class ListConstantExpression extends ConstantExpression {
75 final ListConstantValue value; 214 final ListConstantValue value;
76 final InterfaceType type; 215 final InterfaceType type;
77 final List<ConstantExpression> values; 216 final List<ConstantExpression> values;
78 217
79 ListConstantExpression(this.value, this.type, this.values); 218 ListConstantExpression(this.value, this.type, this.values);
80 219
220 ConstantExpressionKind get kind => ConstantExpressionKind.LIST;
221
81 accept(ConstantExpressionVisitor visitor, [context]) { 222 accept(ConstantExpressionVisitor visitor, [context]) {
82 return visitor.visitList(this, context); 223 return visitor.visitList(this, context);
83 } 224 }
225
226 @override
227 int _computeHashCode() {
228 int hashCode = 13 * type.hashCode + 17 * values.length;
229 for (ConstantExpression value in values) {
230 hashCode ^= 19 * value.hashCode;
231 }
232 return hashCode;
233 }
234
235 @override
236 bool _equals(ListConstantExpression other) {
237 if (type != other.type) return false;
238 if (values.length != other.values.length) return false;
239 for (int i = 0; i < values.length; i++) {
240 if (values[i] != other.values[i]) return false;
241 }
242 return true;
243 }
84 } 244 }
85 245
86 /// Literal map constant. 246 /// Literal map constant.
87 class MapConstantExpression extends ConstantExpression { 247 class MapConstantExpression extends ConstantExpression {
88 final MapConstantValue value; 248 final MapConstantValue value;
89 final InterfaceType type; 249 final InterfaceType type;
90 final List<ConstantExpression> keys; 250 final List<ConstantExpression> keys;
91 final List<ConstantExpression> values; 251 final List<ConstantExpression> values;
92 252
93 MapConstantExpression(this.value, this.type, this.keys, this.values); 253 MapConstantExpression(this.value, this.type, this.keys, this.values);
94 254
255 ConstantExpressionKind get kind => ConstantExpressionKind.MAP;
256
95 accept(ConstantExpressionVisitor visitor, [context]) { 257 accept(ConstantExpressionVisitor visitor, [context]) {
96 return visitor.visitMap(this, context); 258 return visitor.visitMap(this, context);
97 } 259 }
260
261 @override
262 int _computeHashCode() {
263 int hashCode = 13 * type.hashCode + 17 * values.length;
264 for (ConstantExpression value in values) {
265 hashCode ^= 19 * value.hashCode;
266 }
267 return hashCode;
268 }
269
270 @override
271 bool _equals(MapConstantExpression other) {
272 if (type != other.type) return false;
273 if (values.length != other.values.length) return false;
274 for (int i = 0; i < values.length; i++) {
275 if (keys[i] != other.keys[i]) return false;
276 if (values[i] != other.values[i]) return false;
277 }
278 return true;
279 }
98 } 280 }
99 281
100 /// Invocation of a const constructor. 282 /// Invocation of a const constructor.
101 class ConstructedConstantExpression extends ConstantExpression { 283 class ConstructedConstantExpression extends ConstantExpression {
102 final ConstantValue value; 284 final ConstantValue value;
103 final InterfaceType type; 285 final InterfaceType type;
104 final FunctionElement target; 286 final ConstructorElement target;
105 final CallStructure callStructure; 287 final CallStructure callStructure;
106 final List<ConstantExpression> arguments; 288 final List<ConstantExpression> arguments;
107 289
108 ConstructedConstantExpression( 290 ConstructedConstantExpression(
109 this.value, 291 this.value,
110 this.type, 292 this.type,
111 this.target, 293 this.target,
112 this.callStructure, 294 this.callStructure,
113 this.arguments) { 295 this.arguments) {
114 assert(type.element == target.enclosingClass); 296 assert(type.element == target.enclosingClass);
115 } 297 }
116 298
299 ConstantExpressionKind get kind => ConstantExpressionKind.CONSTRUCTED;
300
117 accept(ConstantExpressionVisitor visitor, [context]) { 301 accept(ConstantExpressionVisitor visitor, [context]) {
118 return visitor.visitConstructed(this, context); 302 return visitor.visitConstructed(this, context);
119 } 303 }
304
305 @override
306 int _computeHashCode() {
307 int hashCode =
308 13 * type.hashCode +
309 17 * target.hashCode +
310 19 * callStructure.hashCode;
311 for (ConstantExpression value in arguments) {
312 hashCode ^= 23 * value.hashCode;
313 }
314 return hashCode;
315 }
316
317 @override
318 bool _equals(ConstructedConstantExpression other) {
319 if (type != other.type) return false;
320 if (target != other.target) return false;
321 if (callStructure != other.callStructure) return false;
322 for (int i = 0; i < arguments.length; i++) {
323 if (arguments[i] != other.arguments[i]) return false;
324 }
325 return true;
326 }
120 } 327 }
121 328
122 /// String literal with juxtaposition and/or interpolations. 329 /// String literal with juxtaposition and/or interpolations.
123 // TODO(johnniwinther): Do we need this?
124 class ConcatenateConstantExpression extends ConstantExpression { 330 class ConcatenateConstantExpression extends ConstantExpression {
125 final StringConstantValue value; 331 final StringConstantValue value;
126 final List<ConstantExpression> arguments; 332 final List<ConstantExpression> arguments;
127 333
128 ConcatenateConstantExpression(this.value, this.arguments); 334 ConcatenateConstantExpression(this.value, this.arguments);
129 335
336 ConstantExpressionKind get kind => ConstantExpressionKind.CONCATENATE;
337
130 accept(ConstantExpressionVisitor visitor, [context]) { 338 accept(ConstantExpressionVisitor visitor, [context]) {
131 return visitor.visitConcatenate(this, context); 339 return visitor.visitConcatenate(this, context);
132 } 340 }
341
342 @override
343 int _computeHashCode() {
344 int hashCode = 17 * arguments.length;
345 for (ConstantExpression value in arguments) {
346 hashCode ^= 19 * value.hashCode;
347 }
348 return hashCode;
349 }
350
351 @override
352 bool _equals(ConcatenateConstantExpression other) {
353 if (arguments.length != other.arguments.length) return false;
354 for (int i = 0; i < arguments.length; i++) {
355 if (arguments[i] != other.arguments[i]) return false;
356 }
357 return true;
358 }
133 } 359 }
134 360
135 /// Symbol literal. 361 /// Symbol literal.
136 class SymbolConstantExpression extends ConstantExpression { 362 class SymbolConstantExpression extends ConstantExpression {
137 final ConstructedConstantValue value; 363 final ConstructedConstantValue value;
138 final String name; 364 final String name;
139 365
140 SymbolConstantExpression(this.value, this.name); 366 SymbolConstantExpression(this.value, this.name);
141 367
368 ConstantExpressionKind get kind => ConstantExpressionKind.SYMBOL;
369
142 accept(ConstantExpressionVisitor visitor, [context]) { 370 accept(ConstantExpressionVisitor visitor, [context]) {
143 return visitor.visitSymbol(this, context); 371 return visitor.visitSymbol(this, context);
144 } 372 }
373
374 @override
375 int _computeHashCode() => 13 * name.hashCode;
376
377 @override
378 bool _equals(SymbolConstantExpression other) {
379 return name == other.name;
380 }
145 } 381 }
146 382
147 /// Type literal. 383 /// Type literal.
148 class TypeConstantExpression extends ConstantExpression { 384 class TypeConstantExpression extends ConstantExpression {
149 final TypeConstantValue value; 385 final TypeConstantValue value;
150 /// Either [DynamicType] or a raw [GenericType]. 386 /// Either [DynamicType] or a raw [GenericType].
151 final DartType type; 387 final DartType type;
152 388
153 TypeConstantExpression(this.value, this.type) { 389 TypeConstantExpression(this.value, this.type) {
154 assert(type is GenericType || type is DynamicType); 390 assert(type is GenericType || type is DynamicType);
155 } 391 }
156 392
393 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE;
394
157 accept(ConstantExpressionVisitor visitor, [context]) { 395 accept(ConstantExpressionVisitor visitor, [context]) {
158 return visitor.visitType(this, context); 396 return visitor.visitType(this, context);
159 } 397 }
398
399 @override
400 int _computeHashCode() => 13 * type.hashCode;
401
402 @override
403 bool _equals(TypeConstantExpression other) {
404 return type == other.type;
405 }
160 } 406 }
161 407
162 /// Reference to a constant local, top-level, or static variable. 408 /// Reference to a constant local, top-level, or static variable.
163 class VariableConstantExpression extends ConstantExpression { 409 class VariableConstantExpression extends ConstantExpression {
164 final ConstantValue value; 410 final ConstantValue value;
165 final VariableElement element; 411 final VariableElement element;
166 412
167 VariableConstantExpression(this.value, this.element); 413 VariableConstantExpression(this.value, this.element);
168 414
415 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE;
416
169 accept(ConstantExpressionVisitor visitor, [context]) { 417 accept(ConstantExpressionVisitor visitor, [context]) {
170 return visitor.visitVariable(this, context); 418 return visitor.visitVariable(this, context);
171 } 419 }
420
421 @override
422 int _computeHashCode() => 13 * element.hashCode;
423
424 @override
425 bool _equals(VariableConstantExpression other) {
426 return element == other.element;
427 }
172 } 428 }
173 429
174 /// Reference to a top-level or static function. 430 /// Reference to a top-level or static function.
175 class FunctionConstantExpression extends ConstantExpression { 431 class FunctionConstantExpression extends ConstantExpression {
176 final FunctionConstantValue value; 432 final FunctionConstantValue value;
177 final FunctionElement element; 433 final FunctionElement element;
178 434
179 FunctionConstantExpression(this.value, this.element); 435 FunctionConstantExpression(this.value, this.element);
180 436
437 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION;
438
181 accept(ConstantExpressionVisitor visitor, [context]) { 439 accept(ConstantExpressionVisitor visitor, [context]) {
182 return visitor.visitFunction(this, context); 440 return visitor.visitFunction(this, context);
183 } 441 }
442
443 @override
444 int _computeHashCode() => 13 * element.hashCode;
445
446 @override
447 bool _equals(FunctionConstantExpression other) {
448 return element == other.element;
449 }
184 } 450 }
185 451
186 /// A constant binary expression like `a * b`. 452 /// A constant binary expression like `a * b`.
187 class BinaryConstantExpression extends ConstantExpression { 453 class BinaryConstantExpression extends ConstantExpression {
188 final ConstantValue value; 454 final ConstantValue value;
189 final ConstantExpression left; 455 final ConstantExpression left;
190 final BinaryOperator operator; 456 final BinaryOperator operator;
191 final ConstantExpression right; 457 final ConstantExpression right;
192 458
193 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { 459 BinaryConstantExpression(this.value, this.left, this.operator, this.right) {
194 assert(PRECEDENCE_MAP[operator.kind] != null); 460 assert(PRECEDENCE_MAP[operator.kind] != null);
195 } 461 }
196 462
463 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY;
464
197 accept(ConstantExpressionVisitor visitor, [context]) { 465 accept(ConstantExpressionVisitor visitor, [context]) {
198 return visitor.visitBinary(this, context); 466 return visitor.visitBinary(this, context);
199 } 467 }
200 468
201 int get precedence => PRECEDENCE_MAP[operator.kind]; 469 int get precedence => PRECEDENCE_MAP[operator.kind];
202 470
471 @override
472 int _computeHashCode() {
473 return 13 * operator.hashCode +
474 17 * left.hashCode +
475 19 * right.hashCode;
476 }
477
478 @override
479 bool _equals(BinaryConstantExpression other) {
480 return operator == other.operator &&
481 left == other.left &&
482 right == other.right;
483 }
484
203 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const { 485 static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const {
204 BinaryOperatorKind.EQ: 6, 486 BinaryOperatorKind.EQ: 6,
205 BinaryOperatorKind.NOT_EQ: 6, 487 BinaryOperatorKind.NOT_EQ: 6,
206 BinaryOperatorKind.LOGICAL_AND: 5, 488 BinaryOperatorKind.LOGICAL_AND: 5,
207 BinaryOperatorKind.LOGICAL_OR: 4, 489 BinaryOperatorKind.LOGICAL_OR: 4,
208 BinaryOperatorKind.XOR: 9, 490 BinaryOperatorKind.XOR: 9,
209 BinaryOperatorKind.AND: 10, 491 BinaryOperatorKind.AND: 10,
210 BinaryOperatorKind.OR: 8, 492 BinaryOperatorKind.OR: 8,
211 BinaryOperatorKind.SHR: 11, 493 BinaryOperatorKind.SHR: 11,
212 BinaryOperatorKind.SHL: 11, 494 BinaryOperatorKind.SHL: 11,
(...skipping 11 matching lines...) Expand all
224 } 506 }
225 507
226 /// A constant identical invocation like `identical(a, b)`. 508 /// A constant identical invocation like `identical(a, b)`.
227 class IdenticalConstantExpression extends ConstantExpression { 509 class IdenticalConstantExpression extends ConstantExpression {
228 final ConstantValue value; 510 final ConstantValue value;
229 final ConstantExpression left; 511 final ConstantExpression left;
230 final ConstantExpression right; 512 final ConstantExpression right;
231 513
232 IdenticalConstantExpression(this.value, this.left, this.right); 514 IdenticalConstantExpression(this.value, this.left, this.right);
233 515
516 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL;
517
234 accept(ConstantExpressionVisitor visitor, [context]) { 518 accept(ConstantExpressionVisitor visitor, [context]) {
235 return visitor.visitIdentical(this, context); 519 return visitor.visitIdentical(this, context);
236 } 520 }
237 521
238 int get precedence => 15; 522 int get precedence => 15;
523
524 @override
525 int _computeHashCode() {
526 return 17 * left.hashCode +
527 19 * right.hashCode;
528 }
529
530 @override
531 bool _equals(IdenticalConstantExpression other) {
532 return left == other.left &&
533 right == other.right;
534 }
239 } 535 }
240 536
241 /// A unary constant expression like `-a`. 537 /// A unary constant expression like `-a`.
242 class UnaryConstantExpression extends ConstantExpression { 538 class UnaryConstantExpression extends ConstantExpression {
243 final ConstantValue value; 539 final ConstantValue value;
244 final UnaryOperator operator; 540 final UnaryOperator operator;
245 final ConstantExpression expression; 541 final ConstantExpression expression;
246 542
247 UnaryConstantExpression(this.value, this.operator, this.expression) { 543 UnaryConstantExpression(this.value, this.operator, this.expression) {
248 assert(PRECEDENCE_MAP[operator.kind] != null); 544 assert(PRECEDENCE_MAP[operator.kind] != null);
249 } 545 }
250 546
547 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY;
548
251 accept(ConstantExpressionVisitor visitor, [context]) { 549 accept(ConstantExpressionVisitor visitor, [context]) {
252 return visitor.visitUnary(this, context); 550 return visitor.visitUnary(this, context);
253 } 551 }
254 552
255 int get precedence => PRECEDENCE_MAP[operator.kind]; 553 int get precedence => PRECEDENCE_MAP[operator.kind];
256 554
555 @override
556 int _computeHashCode() {
557 return 13 * operator.hashCode +
558 17 * expression.hashCode;
559 }
560
561 @override
562 bool _equals(UnaryConstantExpression other) {
563 return operator == other.operator &&
564 expression == other.expression;
565 }
566
257 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const { 567 static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const {
258 UnaryOperatorKind.NOT: 14, 568 UnaryOperatorKind.NOT: 14,
259 UnaryOperatorKind.COMPLEMENT: 14, 569 UnaryOperatorKind.COMPLEMENT: 14,
260 UnaryOperatorKind.NEGATE: 14, 570 UnaryOperatorKind.NEGATE: 14,
261 }; 571 };
262 } 572 }
263 573
264 /// A constant conditional expression like `a ? b : c`. 574 /// A constant conditional expression like `a ? b : c`.
265 class ConditionalConstantExpression extends ConstantExpression { 575 class ConditionalConstantExpression extends ConstantExpression {
266 final ConstantValue value; 576 final ConstantValue value;
267 final ConstantExpression condition; 577 final ConstantExpression condition;
268 final ConstantExpression trueExp; 578 final ConstantExpression trueExp;
269 final ConstantExpression falseExp; 579 final ConstantExpression falseExp;
270 580
271 ConditionalConstantExpression(this.value, 581 ConditionalConstantExpression(this.value,
272 this.condition, 582 this.condition,
273 this.trueExp, 583 this.trueExp,
274 this.falseExp); 584 this.falseExp);
275 585
586 ConstantExpressionKind get kind => ConstantExpressionKind.CONDITIONAL;
587
276 accept(ConstantExpressionVisitor visitor, [context]) { 588 accept(ConstantExpressionVisitor visitor, [context]) {
277 return visitor.visitConditional(this, context); 589 return visitor.visitConditional(this, context);
278 } 590 }
279 591
280 int get precedence => 3; 592 int get precedence => 3;
593
594 @override
595 int _computeHashCode() {
596 return 13 * condition.hashCode +
597 17 * trueExp.hashCode +
598 19 * falseExp.hashCode;
599 }
600
601 @override
602 bool _equals(ConditionalConstantExpression other) {
603 return condition == other.condition &&
604 trueExp == other.trueExp &&
605 falseExp == other.falseExp;
606 }
281 } 607 }
282 608
283 abstract class ConstantExpressionVisitor<C, R> { 609 abstract class ConstantExpressionVisitor<C, R> {
284 const ConstantExpressionVisitor(); 610 const ConstantExpressionVisitor();
285 611
286 R visit(ConstantExpression constant, C context) { 612 R visit(ConstantExpression constant, C context) {
287 return constant.accept(this, context); 613 return constant.accept(this, context);
288 } 614 }
289 615
290 R visitPrimitive(PrimitiveConstantExpression exp, C context); 616 R visitPrimitive(PrimitiveConstantExpression exp, C context);
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 void visitConditional(ConditionalConstantExpression exp, [_]) { 803 void visitConditional(ConditionalConstantExpression exp, [_]) {
478 write(exp, exp.condition, leftAssociative: false); 804 write(exp, exp.condition, leftAssociative: false);
479 sb.write(' ? '); 805 sb.write(' ? ');
480 write(exp, exp.trueExp); 806 write(exp, exp.trueExp);
481 sb.write(' : '); 807 sb.write(' : ');
482 write(exp, exp.falseExp); 808 write(exp, exp.falseExp);
483 } 809 }
484 810
485 String toString() => sb.toString(); 811 String toString() => sb.toString();
486 } 812 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/compile_time_constants.dart ('k') | pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698