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

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

Issue 1121233002: Add ConstantExpression.evaluate. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 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 | 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 '../constants/constant_system.dart';
8 import '../dart2jslib.dart' show assertDebugMode, Compiler;
8 import '../dart_types.dart'; 9 import '../dart_types.dart';
9 import '../elements/elements.dart' show 10 import '../elements/elements.dart' show
10 ConstructorElement, 11 ConstructorElement,
11 Element, 12 Element,
12 FieldElement, 13 FieldElement,
13 FunctionElement, 14 FunctionElement,
14 VariableElement; 15 VariableElement;
15 import '../resolution/operators.dart'; 16 import '../resolution/operators.dart';
17 import '../tree/tree.dart' show DartString;
16 import '../universe/universe.dart' show CallStructure; 18 import '../universe/universe.dart' show CallStructure;
17 import 'values.dart'; 19 import 'values.dart';
18 20
19 enum ConstantExpressionKind { 21 enum ConstantExpressionKind {
20 BINARY, 22 BINARY,
21 BOOL, 23 BOOL,
22 BOOL_FROM_ENVIRONMENT, 24 BOOL_FROM_ENVIRONMENT,
23 CONCATENATE, 25 CONCATENATE,
24 CONDITIONAL, 26 CONDITIONAL,
25 CONSTRUCTED, 27 CONSTRUCTED,
(...skipping 10 matching lines...) Expand all
36 STRING_FROM_ENVIRONMENT, 38 STRING_FROM_ENVIRONMENT,
37 SYMBOL, 39 SYMBOL,
38 TYPE, 40 TYPE,
39 UNARY, 41 UNARY,
40 VARIABLE, 42 VARIABLE,
41 43
42 POSITIONAL_REFERENCE, 44 POSITIONAL_REFERENCE,
43 NAMED_REFERENCE, 45 NAMED_REFERENCE,
44 } 46 }
45 47
48 /// Environment used for evaluating constant expressions.
49 abstract class Environment {
50 // TODO(johnniwinther): Replace this with [CoreTypes] and maybe [Backend].
51 Compiler get compiler;
52
53 /// Read environments string passed in using the '-Dname=value' option.
54 String readFromEnvironment(String name);
55 }
56
46 /// The normalized arguments passed to a const constructor computed from the 57 /// The normalized arguments passed to a const constructor computed from the
47 /// actual [arguments] and the [defaultValues] of the called construrctor. 58 /// actual [arguments] and the [defaultValues] of the called construrctor.
48 class Arguments { 59 class Arguments {
49 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues; 60 final Map<dynamic/*int|String*/, ConstantExpression> defaultValues;
50 final CallStructure callStructure; 61 final CallStructure callStructure;
51 final List<ConstantExpression> arguments; 62 final List<ConstantExpression> arguments;
52 63
53 Arguments(this.defaultValues, this.callStructure, this.arguments); 64 Arguments(this.defaultValues, this.callStructure, this.arguments);
54 65
55 /// Returns the normalized named argument [name]. 66 /// Returns the normalized named argument [name].
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 254
244 // TODO(johnniwinther): Unify precedence handled between constants, front-end 255 // TODO(johnniwinther): Unify precedence handled between constants, front-end
245 // and back-end. 256 // and back-end.
246 int get precedence => 16; 257 int get precedence => 16;
247 258
248 accept(ConstantExpressionVisitor visitor, [context]); 259 accept(ConstantExpressionVisitor visitor, [context]);
249 260
250 /// Substitute free variables using arguments. 261 /// Substitute free variables using arguments.
251 ConstantExpression apply(Arguments arguments) => this; 262 ConstantExpression apply(Arguments arguments) => this;
252 263
264 /// Compute the [ConstantValue] for this expression using the [environment]
265 /// and the [constantSystem].
266 ConstantValue evaluate(Environment environment,
267 ConstantSystem constantSystem);
268
253 String getText() { 269 String getText() {
254 ConstExpPrinter printer = new ConstExpPrinter(); 270 ConstExpPrinter printer = new ConstExpPrinter();
255 accept(printer); 271 accept(printer);
256 return printer.toString(); 272 return printer.toString();
257 } 273 }
258 274
259 int _computeHashCode(); 275 int _computeHashCode();
260 276
261 int get hashCode { 277 int get hashCode {
262 if (_hashCode == null) { 278 if (_hashCode == null) {
(...skipping 23 matching lines...) Expand all
286 class ErroneousConstantExpression extends ConstantExpression { 302 class ErroneousConstantExpression extends ConstantExpression {
287 final PrimitiveConstantValue value = new NullConstantValue(); 303 final PrimitiveConstantValue value = new NullConstantValue();
288 304
289 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS; 305 ConstantExpressionKind get kind => ConstantExpressionKind.ERRONEOUS;
290 306
291 accept(ConstantExpressionVisitor visitor, [context]) { 307 accept(ConstantExpressionVisitor visitor, [context]) {
292 // Do nothing. This is an error. 308 // Do nothing. This is an error.
293 } 309 }
294 310
295 @override 311 @override
312 ConstantValue evaluate(Environment environment,
313 ConstantSystem constantSystem) {
314 // TODO(johnniwinther): Use non-constant values for errors.
315 return value;
316 }
317
318 @override
296 int _computeHashCode() => 13; 319 int _computeHashCode() => 13;
297 320
298 @override 321 @override
299 bool _equals(ErroneousConstantExpression other) => true; 322 bool _equals(ErroneousConstantExpression other) => true;
300 } 323 }
301 324
302 /// A boolean, int, double, string, or null constant. 325 /// A boolean, int, double, string, or null constant.
303 abstract class PrimitiveConstantExpression extends ConstantExpression { 326 abstract class PrimitiveConstantExpression extends ConstantExpression {
304 final PrimitiveConstantValue value; 327 final PrimitiveConstantValue value;
305 328
(...skipping 10 matching lines...) Expand all
316 BoolConstantExpression(this.primitiveValue, 339 BoolConstantExpression(this.primitiveValue,
317 PrimitiveConstantValue value) : super(value); 340 PrimitiveConstantValue value) : super(value);
318 341
319 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL; 342 ConstantExpressionKind get kind => ConstantExpressionKind.BOOL;
320 343
321 accept(ConstantExpressionVisitor visitor, [context]) { 344 accept(ConstantExpressionVisitor visitor, [context]) {
322 return visitor.visitBool(this, context); 345 return visitor.visitBool(this, context);
323 } 346 }
324 347
325 @override 348 @override
349 ConstantValue evaluate(Environment environment,
350 ConstantSystem constantSystem) {
351 return constantSystem.createBool(primitiveValue);
352 }
353
354 @override
326 int _computeHashCode() => 13 * primitiveValue.hashCode; 355 int _computeHashCode() => 13 * primitiveValue.hashCode;
327 356
328 @override 357 @override
329 bool _equals(BoolConstantExpression other) { 358 bool _equals(BoolConstantExpression other) {
330 return primitiveValue == other.primitiveValue; 359 return primitiveValue == other.primitiveValue;
331 } 360 }
332 } 361 }
333 362
334 /// Integer literal constant. 363 /// Integer literal constant.
335 class IntConstantExpression extends PrimitiveConstantExpression { 364 class IntConstantExpression extends PrimitiveConstantExpression {
336 final int primitiveValue; 365 final int primitiveValue;
337 366
338 IntConstantExpression(this.primitiveValue, 367 IntConstantExpression(this.primitiveValue,
339 PrimitiveConstantValue value) : super(value); 368 PrimitiveConstantValue value) : super(value);
340 369
341 ConstantExpressionKind get kind => ConstantExpressionKind.INT; 370 ConstantExpressionKind get kind => ConstantExpressionKind.INT;
342 371
343 accept(ConstantExpressionVisitor visitor, [context]) { 372 accept(ConstantExpressionVisitor visitor, [context]) {
344 return visitor.visitInt(this, context); 373 return visitor.visitInt(this, context);
345 } 374 }
346 375
347 @override 376 @override
377 ConstantValue evaluate(Environment environment,
378 ConstantSystem constantSystem) {
379 return constantSystem.createInt(primitiveValue);
380 }
381
382 @override
348 int _computeHashCode() => 17 * primitiveValue.hashCode; 383 int _computeHashCode() => 17 * primitiveValue.hashCode;
349 384
350 @override 385 @override
351 bool _equals(IntConstantExpression other) { 386 bool _equals(IntConstantExpression other) {
352 return primitiveValue == other.primitiveValue; 387 return primitiveValue == other.primitiveValue;
353 } 388 }
354 } 389 }
355 390
356 /// Double literal constant. 391 /// Double literal constant.
357 class DoubleConstantExpression extends PrimitiveConstantExpression { 392 class DoubleConstantExpression extends PrimitiveConstantExpression {
358 final double primitiveValue; 393 final double primitiveValue;
359 394
360 DoubleConstantExpression(this.primitiveValue, 395 DoubleConstantExpression(this.primitiveValue,
361 PrimitiveConstantValue value) : super(value); 396 PrimitiveConstantValue value) : super(value);
362 397
363 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE; 398 ConstantExpressionKind get kind => ConstantExpressionKind.DOUBLE;
364 399
365 accept(ConstantExpressionVisitor visitor, [context]) { 400 accept(ConstantExpressionVisitor visitor, [context]) {
366 return visitor.visitDouble(this, context); 401 return visitor.visitDouble(this, context);
367 } 402 }
368 403
369 @override 404 @override
405 ConstantValue evaluate(Environment environment,
406 ConstantSystem constantSystem) {
407 return constantSystem.createDouble(primitiveValue);
408 }
409
410 @override
370 int _computeHashCode() => 19 * primitiveValue.hashCode; 411 int _computeHashCode() => 19 * primitiveValue.hashCode;
371 412
372 @override 413 @override
373 bool _equals(DoubleConstantExpression other) { 414 bool _equals(DoubleConstantExpression other) {
374 return primitiveValue == other.primitiveValue; 415 return primitiveValue == other.primitiveValue;
375 } 416 }
376 } 417 }
377 418
378 /// String literal constant. 419 /// String literal constant.
379 class StringConstantExpression extends PrimitiveConstantExpression { 420 class StringConstantExpression extends PrimitiveConstantExpression {
380 final String primitiveValue; 421 final String primitiveValue;
381 422
382 StringConstantExpression(this.primitiveValue, 423 StringConstantExpression(this.primitiveValue,
383 PrimitiveConstantValue value) : super(value); 424 PrimitiveConstantValue value) : super(value);
384 425
385 ConstantExpressionKind get kind => ConstantExpressionKind.STRING; 426 ConstantExpressionKind get kind => ConstantExpressionKind.STRING;
386 427
387 accept(ConstantExpressionVisitor visitor, [context]) { 428 accept(ConstantExpressionVisitor visitor, [context]) {
388 return visitor.visitString(this, context); 429 return visitor.visitString(this, context);
389 } 430 }
390 431
391 @override 432 @override
433 ConstantValue evaluate(Environment environment,
434 ConstantSystem constantSystem) {
435 return constantSystem.createString(new DartString.literal(primitiveValue));
436 }
437
438 @override
392 int _computeHashCode() => 23 * primitiveValue.hashCode; 439 int _computeHashCode() => 23 * primitiveValue.hashCode;
393 440
394 @override 441 @override
395 bool _equals(StringConstantExpression other) { 442 bool _equals(StringConstantExpression other) {
396 return primitiveValue == other.primitiveValue; 443 return primitiveValue == other.primitiveValue;
397 } 444 }
398 } 445 }
399 446
400 /// Null literal constant. 447 /// Null literal constant.
401 class NullConstantExpression extends PrimitiveConstantExpression { 448 class NullConstantExpression extends PrimitiveConstantExpression {
402 NullConstantExpression(PrimitiveConstantValue value) : super(value); 449 NullConstantExpression(PrimitiveConstantValue value) : super(value);
403 450
404 ConstantExpressionKind get kind => ConstantExpressionKind.NULL; 451 ConstantExpressionKind get kind => ConstantExpressionKind.NULL;
405 452
406 accept(ConstantExpressionVisitor visitor, [context]) { 453 accept(ConstantExpressionVisitor visitor, [context]) {
407 return visitor.visitNull(this, context); 454 return visitor.visitNull(this, context);
408 } 455 }
409 456
457 @override
458 ConstantValue evaluate(Environment environment,
459 ConstantSystem constantSystem) {
460 return constantSystem.createNull();
461 }
462
410 get primitiveValue => null; 463 get primitiveValue => null;
411 464
412 @override 465 @override
413 int _computeHashCode() => 29; 466 int _computeHashCode() => 29;
414 467
415 @override 468 @override
416 bool _equals(NullConstantExpression other) => true; 469 bool _equals(NullConstantExpression other) => true;
417 } 470 }
418 471
419 /// Literal list constant. 472 /// Literal list constant.
420 class ListConstantExpression extends ConstantExpression { 473 class ListConstantExpression extends ConstantExpression {
421 final ListConstantValue value; 474 final ListConstantValue value;
422 final InterfaceType type; 475 final InterfaceType type;
423 final List<ConstantExpression> values; 476 final List<ConstantExpression> values;
424 477
425 ListConstantExpression(this.value, this.type, this.values); 478 ListConstantExpression(this.value, this.type, this.values);
426 479
427 ConstantExpressionKind get kind => ConstantExpressionKind.LIST; 480 ConstantExpressionKind get kind => ConstantExpressionKind.LIST;
428 481
429 accept(ConstantExpressionVisitor visitor, [context]) { 482 accept(ConstantExpressionVisitor visitor, [context]) {
430 return visitor.visitList(this, context); 483 return visitor.visitList(this, context);
431 } 484 }
432 485
433 @override 486 @override
487 ConstantValue evaluate(Environment environment,
488 ConstantSystem constantSystem) {
489 return constantSystem.createList(type,
490 values.map((v) => v.evaluate(environment, constantSystem)).toList());
491 }
492
434 ConstantExpression apply(Arguments arguments) { 493 ConstantExpression apply(Arguments arguments) {
435 return new ListConstantExpression(null, type, 494 return new ListConstantExpression(null, type,
436 values.map((v) => v.apply(arguments)).toList()); 495 values.map((v) => v.apply(arguments)).toList());
437 } 496 }
438 497
498 @override
439 int _computeHashCode() { 499 int _computeHashCode() {
440 int hashCode = 13 * type.hashCode + 17 * values.length; 500 int hashCode = 13 * type.hashCode + 17 * values.length;
441 for (ConstantExpression value in values) { 501 for (ConstantExpression value in values) {
442 hashCode ^= 19 * value.hashCode; 502 hashCode ^= 19 * value.hashCode;
443 } 503 }
444 return hashCode; 504 return hashCode;
445 } 505 }
446 506
447 @override 507 @override
448 bool _equals(ListConstantExpression other) { 508 bool _equals(ListConstantExpression other) {
(...skipping 15 matching lines...) Expand all
464 524
465 MapConstantExpression(this.value, this.type, this.keys, this.values); 525 MapConstantExpression(this.value, this.type, this.keys, this.values);
466 526
467 ConstantExpressionKind get kind => ConstantExpressionKind.MAP; 527 ConstantExpressionKind get kind => ConstantExpressionKind.MAP;
468 528
469 accept(ConstantExpressionVisitor visitor, [context]) { 529 accept(ConstantExpressionVisitor visitor, [context]) {
470 return visitor.visitMap(this, context); 530 return visitor.visitMap(this, context);
471 } 531 }
472 532
473 @override 533 @override
534 ConstantValue evaluate(Environment environment,
535 ConstantSystem constantSystem) {
536 return constantSystem.createMap(environment.compiler,
537 type,
538 keys.map((k) => k.evaluate(environment, constantSystem)).toList(),
539 values.map((v) => v.evaluate(environment, constantSystem)).toList());
540 }
541
474 ConstantExpression apply(Arguments arguments) { 542 ConstantExpression apply(Arguments arguments) {
475 return new MapConstantExpression(null, type, 543 return new MapConstantExpression(null, type,
476 keys.map((k) => k.apply(arguments)).toList(), 544 keys.map((k) => k.apply(arguments)).toList(),
477 values.map((v) => v.apply(arguments)).toList()); 545 values.map((v) => v.apply(arguments)).toList());
478 } 546 }
479 547
548 @override
480 int _computeHashCode() { 549 int _computeHashCode() {
481 int hashCode = 13 * type.hashCode + 17 * values.length; 550 int hashCode = 13 * type.hashCode + 17 * values.length;
482 for (ConstantExpression value in values) { 551 for (ConstantExpression value in values) {
483 hashCode ^= 19 * value.hashCode; 552 hashCode ^= 19 * value.hashCode;
484 } 553 }
485 return hashCode; 554 return hashCode;
486 } 555 }
487 556
488 @override 557 @override
489 bool _equals(MapConstantExpression other) { 558 bool _equals(MapConstantExpression other) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 InterfaceType computeInstanceType() { 598 InterfaceType computeInstanceType() {
530 return target.constantConstructor.computeInstanceType(type); 599 return target.constantConstructor.computeInstanceType(type);
531 } 600 }
532 601
533 ConstructedConstantExpression apply(Arguments arguments) { 602 ConstructedConstantExpression apply(Arguments arguments) {
534 return new ConstructedConstantExpression(null, 603 return new ConstructedConstantExpression(null,
535 type, target, callStructure, 604 type, target, callStructure,
536 this.arguments.map((a) => a.apply(arguments)).toList()); 605 this.arguments.map((a) => a.apply(arguments)).toList());
537 } 606 }
538 607
608 @override
609 ConstantValue evaluate(Environment environment,
610 ConstantSystem constantSystem) {
611 Map<FieldElement, ConstantValue> fieldValues =
612 <FieldElement, ConstantValue>{};
613 computeInstanceFields().forEach(
614 (FieldElement field, ConstantExpression constant) {
615 fieldValues[field] = constant.evaluate(environment, constantSystem);
616 });
617 return new ConstructedConstantValue(computeInstanceType(), fieldValues);
618 }
619
620 @override
539 int _computeHashCode() { 621 int _computeHashCode() {
540 int hashCode = 622 int hashCode =
541 13 * type.hashCode + 623 13 * type.hashCode +
542 17 * target.hashCode + 624 17 * target.hashCode +
543 19 * callStructure.hashCode; 625 19 * callStructure.hashCode;
544 for (ConstantExpression value in arguments) { 626 for (ConstantExpression value in arguments) {
545 hashCode ^= 23 * value.hashCode; 627 hashCode ^= 23 * value.hashCode;
546 } 628 }
547 return hashCode; 629 return hashCode;
548 } 630 }
(...skipping 22 matching lines...) Expand all
571 accept(ConstantExpressionVisitor visitor, [context]) { 653 accept(ConstantExpressionVisitor visitor, [context]) {
572 return visitor.visitConcatenate(this, context); 654 return visitor.visitConcatenate(this, context);
573 } 655 }
574 656
575 ConstantExpression apply(Arguments arguments) { 657 ConstantExpression apply(Arguments arguments) {
576 return new ConcatenateConstantExpression(null, 658 return new ConcatenateConstantExpression(null,
577 expressions.map((a) => a.apply(arguments)).toList()); 659 expressions.map((a) => a.apply(arguments)).toList());
578 } 660 }
579 661
580 @override 662 @override
663 ConstantValue evaluate(Environment environment,
664 ConstantSystem constantSystem) {
665 DartString accumulator;
666 for (ConstantExpression expression in expressions) {
667 ConstantValue value = expression.evaluate(environment, constantSystem);
668 DartString valueString;
669 if (value.isNum || value.isBool) {
670 PrimitiveConstantValue primitive = value;
671 valueString =
672 new DartString.literal(primitive.primitiveValue.toString());
673 } else if (value.isString) {
674 PrimitiveConstantValue primitive = value;
675 valueString = primitive.primitiveValue;
676 } else {
677 // TODO(johnniwinther): Specialize message to indicated that the problem
678 // is not constness but the types of the const expressions.
679 return new NonConstantValue();
680 }
681 if (accumulator == null) {
682 accumulator = valueString;
683 } else {
684 accumulator = new DartString.concat(accumulator, valueString);
685 }
686 }
687 return constantSystem.createString(accumulator);
688 }
689
690 @override
581 int _computeHashCode() { 691 int _computeHashCode() {
582 int hashCode = 17 * expressions.length; 692 int hashCode = 17 * expressions.length;
583 for (ConstantExpression value in expressions) { 693 for (ConstantExpression value in expressions) {
584 hashCode ^= 19 * value.hashCode; 694 hashCode ^= 19 * value.hashCode;
585 } 695 }
586 return hashCode; 696 return hashCode;
587 } 697 }
588 698
589 @override 699 @override
590 bool _equals(ConcatenateConstantExpression other) { 700 bool _equals(ConcatenateConstantExpression other) {
(...skipping 18 matching lines...) Expand all
609 return visitor.visitSymbol(this, context); 719 return visitor.visitSymbol(this, context);
610 } 720 }
611 721
612 @override 722 @override
613 int _computeHashCode() => 13 * name.hashCode; 723 int _computeHashCode() => 13 * name.hashCode;
614 724
615 @override 725 @override
616 bool _equals(SymbolConstantExpression other) { 726 bool _equals(SymbolConstantExpression other) {
617 return name == other.name; 727 return name == other.name;
618 } 728 }
729
730 @override
731 ConstantValue evaluate(Environment environment,
732 ConstantSystem constantSystem) {
733 // TODO(johnniwinther): Implement this.
734 throw new UnsupportedError('SymbolConstantExpression.evaluate');
735 }
619 } 736 }
620 737
621 /// Type literal. 738 /// Type literal.
622 class TypeConstantExpression extends ConstantExpression { 739 class TypeConstantExpression extends ConstantExpression {
623 final TypeConstantValue value; 740 final TypeConstantValue value;
624 /// Either [DynamicType] or a raw [GenericType]. 741 /// Either [DynamicType] or a raw [GenericType].
625 final DartType type; 742 final DartType type;
626 743
627 TypeConstantExpression(this.value, this.type) { 744 TypeConstantExpression(this.value, this.type) {
628 assert(type is GenericType || type is DynamicType); 745 assert(type is GenericType || type is DynamicType);
629 } 746 }
630 747
631 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE; 748 ConstantExpressionKind get kind => ConstantExpressionKind.TYPE;
632 749
633 accept(ConstantExpressionVisitor visitor, [context]) { 750 accept(ConstantExpressionVisitor visitor, [context]) {
634 return visitor.visitType(this, context); 751 return visitor.visitType(this, context);
635 } 752 }
636 753
637 @override 754 @override
755 ConstantValue evaluate(Environment environment,
756 ConstantSystem constantSystem) {
757 return constantSystem.createType(environment.compiler, type);
758 }
759
760 @override
638 int _computeHashCode() => 13 * type.hashCode; 761 int _computeHashCode() => 13 * type.hashCode;
639 762
640 @override 763 @override
641 bool _equals(TypeConstantExpression other) { 764 bool _equals(TypeConstantExpression other) {
642 return type == other.type; 765 return type == other.type;
643 } 766 }
644 } 767 }
645 768
646 /// Reference to a constant local, top-level, or static variable. 769 /// Reference to a constant local, top-level, or static variable.
647 class VariableConstantExpression extends ConstantExpression { 770 class VariableConstantExpression extends ConstantExpression {
648 final ConstantValue value; 771 final ConstantValue value;
649 final VariableElement element; 772 final VariableElement element;
650 773
651 VariableConstantExpression(this.value, this.element); 774 VariableConstantExpression(this.value, this.element);
652 775
653 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE; 776 ConstantExpressionKind get kind => ConstantExpressionKind.VARIABLE;
654 777
655 accept(ConstantExpressionVisitor visitor, [context]) { 778 accept(ConstantExpressionVisitor visitor, [context]) {
656 return visitor.visitVariable(this, context); 779 return visitor.visitVariable(this, context);
657 } 780 }
658 781
659 @override 782 @override
783 ConstantValue evaluate(Environment environment,
784 ConstantSystem constantSystem) {
785 return element.constant.evaluate(environment, constantSystem);
786 }
787
788 @override
660 int _computeHashCode() => 13 * element.hashCode; 789 int _computeHashCode() => 13 * element.hashCode;
661 790
662 @override 791 @override
663 bool _equals(VariableConstantExpression other) { 792 bool _equals(VariableConstantExpression other) {
664 return element == other.element; 793 return element == other.element;
665 } 794 }
666 } 795 }
667 796
668 /// Reference to a top-level or static function. 797 /// Reference to a top-level or static function.
669 class FunctionConstantExpression extends ConstantExpression { 798 class FunctionConstantExpression extends ConstantExpression {
670 final FunctionConstantValue value; 799 final FunctionConstantValue value;
671 final FunctionElement element; 800 final FunctionElement element;
672 801
673 FunctionConstantExpression(this.value, this.element); 802 FunctionConstantExpression(this.value, this.element);
674 803
675 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION; 804 ConstantExpressionKind get kind => ConstantExpressionKind.FUNCTION;
676 805
677 accept(ConstantExpressionVisitor visitor, [context]) { 806 accept(ConstantExpressionVisitor visitor, [context]) {
678 return visitor.visitFunction(this, context); 807 return visitor.visitFunction(this, context);
679 } 808 }
680 809
681 @override 810 @override
811 ConstantValue evaluate(Environment environment,
812 ConstantSystem constantSystem) {
813 return new FunctionConstantValue(element);
814 }
815
816 @override
682 int _computeHashCode() => 13 * element.hashCode; 817 int _computeHashCode() => 13 * element.hashCode;
683 818
684 @override 819 @override
685 bool _equals(FunctionConstantExpression other) { 820 bool _equals(FunctionConstantExpression other) {
686 return element == other.element; 821 return element == other.element;
687 } 822 }
688 } 823 }
689 824
690 /// A constant binary expression like `a * b`. 825 /// A constant binary expression like `a * b`.
691 class BinaryConstantExpression extends ConstantExpression { 826 class BinaryConstantExpression extends ConstantExpression {
692 final ConstantValue value; 827 final ConstantValue value;
693 final ConstantExpression left; 828 final ConstantExpression left;
694 final BinaryOperator operator; 829 final BinaryOperator operator;
695 final ConstantExpression right; 830 final ConstantExpression right;
696 831
697 BinaryConstantExpression(this.value, this.left, this.operator, this.right) { 832 BinaryConstantExpression(this.value, this.left, this.operator, this.right) {
698 assert(PRECEDENCE_MAP[operator.kind] != null); 833 assert(PRECEDENCE_MAP[operator.kind] != null);
699 } 834 }
700 835
701 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY; 836 ConstantExpressionKind get kind => ConstantExpressionKind.BINARY;
702 837
703 accept(ConstantExpressionVisitor visitor, [context]) { 838 accept(ConstantExpressionVisitor visitor, [context]) {
704 return visitor.visitBinary(this, context); 839 return visitor.visitBinary(this, context);
705 } 840 }
706 841
842 @override
843 ConstantValue evaluate(Environment environment,
844 ConstantSystem constantSystem) {
845 return constantSystem.lookupBinary(operator).fold(
846 left.evaluate(environment, constantSystem),
847 right.evaluate(environment, constantSystem));
848 }
849
707 ConstantExpression apply(Arguments arguments) { 850 ConstantExpression apply(Arguments arguments) {
708 return new BinaryConstantExpression( 851 return new BinaryConstantExpression(
709 value, 852 value,
710 left.apply(arguments), 853 left.apply(arguments),
711 operator, 854 operator,
712 right.apply(arguments)); 855 right.apply(arguments));
713 } 856 }
714 857
715 int get precedence => PRECEDENCE_MAP[operator.kind]; 858 int get precedence => PRECEDENCE_MAP[operator.kind];
716 859
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 final ConstantExpression right; 901 final ConstantExpression right;
759 902
760 IdenticalConstantExpression(this.value, this.left, this.right); 903 IdenticalConstantExpression(this.value, this.left, this.right);
761 904
762 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL; 905 ConstantExpressionKind get kind => ConstantExpressionKind.IDENTICAL;
763 906
764 accept(ConstantExpressionVisitor visitor, [context]) { 907 accept(ConstantExpressionVisitor visitor, [context]) {
765 return visitor.visitIdentical(this, context); 908 return visitor.visitIdentical(this, context);
766 } 909 }
767 910
911 @override
912 ConstantValue evaluate(Environment environment,
913 ConstantSystem constantSystem) {
914 return constantSystem.identity.fold(
915 left.evaluate(environment, constantSystem),
916 right.evaluate(environment, constantSystem));
917 }
918
768 ConstantExpression apply(Arguments arguments) { 919 ConstantExpression apply(Arguments arguments) {
769 return new IdenticalConstantExpression( 920 return new IdenticalConstantExpression(
770 value, 921 value,
771 left.apply(arguments), 922 left.apply(arguments),
772 right.apply(arguments)); 923 right.apply(arguments));
773 } 924 }
774 925
775 int get precedence => 15; 926 int get precedence => 15;
776 927
777 @override 928 @override
(...skipping 18 matching lines...) Expand all
796 UnaryConstantExpression(this.value, this.operator, this.expression) { 947 UnaryConstantExpression(this.value, this.operator, this.expression) {
797 assert(PRECEDENCE_MAP[operator.kind] != null); 948 assert(PRECEDENCE_MAP[operator.kind] != null);
798 } 949 }
799 950
800 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY; 951 ConstantExpressionKind get kind => ConstantExpressionKind.UNARY;
801 952
802 accept(ConstantExpressionVisitor visitor, [context]) { 953 accept(ConstantExpressionVisitor visitor, [context]) {
803 return visitor.visitUnary(this, context); 954 return visitor.visitUnary(this, context);
804 } 955 }
805 956
957 @override
958 ConstantValue evaluate(Environment environment,
959 ConstantSystem constantSystem) {
960 return constantSystem.lookupUnary(operator).fold(
961 expression.evaluate(environment, constantSystem));
962 }
963
806 ConstantExpression apply(Arguments arguments) { 964 ConstantExpression apply(Arguments arguments) {
807 return new UnaryConstantExpression( 965 return new UnaryConstantExpression(
808 value, 966 value,
809 operator, 967 operator,
810 expression.apply(arguments)); 968 expression.apply(arguments));
811 } 969 }
812 970
813 int get precedence => PRECEDENCE_MAP[operator.kind]; 971 int get precedence => PRECEDENCE_MAP[operator.kind];
814 972
815 @override 973 @override
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 17 * trueExp.hashCode + 1023 17 * trueExp.hashCode +
866 19 * falseExp.hashCode; 1024 19 * falseExp.hashCode;
867 } 1025 }
868 1026
869 @override 1027 @override
870 bool _equals(ConditionalConstantExpression other) { 1028 bool _equals(ConditionalConstantExpression other) {
871 return condition == other.condition && 1029 return condition == other.condition &&
872 trueExp == other.trueExp && 1030 trueExp == other.trueExp &&
873 falseExp == other.falseExp; 1031 falseExp == other.falseExp;
874 } 1032 }
1033
1034 @override
1035 ConstantValue evaluate(Environment environment,
1036 ConstantSystem constantSystem) {
1037 ConstantValue conditionValue =
1038 condition.evaluate(environment, constantSystem);
1039 ConstantValue trueValue =
1040 trueExp.evaluate(environment, constantSystem);
1041 ConstantValue falseValue =
1042 falseExp.evaluate(environment, constantSystem);
1043 if (conditionValue.isTrue) {
1044 return trueValue;
1045 } else if (conditionValue.isFalse) {
1046 return falseValue;
1047 } else {
1048 return new NonConstantValue();
1049 }
1050 }
875 } 1051 }
876 1052
877 /// A reference to a position parameter. 1053 /// A reference to a position parameter.
878 class PositionalArgumentReference extends ConstantExpression { 1054 class PositionalArgumentReference extends ConstantExpression {
879 final int index; 1055 final int index;
880 1056
881 PositionalArgumentReference(this.index); 1057 PositionalArgumentReference(this.index);
882 1058
883 ConstantExpressionKind get kind { 1059 ConstantExpressionKind get kind {
884 return ConstantExpressionKind.POSITIONAL_REFERENCE; 1060 return ConstantExpressionKind.POSITIONAL_REFERENCE;
885 } 1061 }
886 1062
887 accept(ConstantExpressionVisitor visitor, [context]) { 1063 accept(ConstantExpressionVisitor visitor, [context]) {
888 return visitor.visitPositional(this, context); 1064 return visitor.visitPositional(this, context);
889 } 1065 }
890 1066
891 ConstantValue get value { 1067 ConstantValue get value {
892 throw new UnsupportedError('PositionalArgumentReference.value'); 1068 throw new UnsupportedError('PositionalArgumentReference.value');
893 } 1069 }
894 1070
895 ConstantExpression apply(Arguments arguments) { 1071 ConstantExpression apply(Arguments arguments) {
896 return arguments.getPositionalArgument(index); 1072 return arguments.getPositionalArgument(index);
897 } 1073 }
898 1074
899 @override 1075 @override
900 int _computeHashCode() => 13 * index.hashCode; 1076 int _computeHashCode() => 13 * index.hashCode;
901 1077
902 @override 1078 @override
903 bool _equals(PositionalArgumentReference other) => index == other.index; 1079 bool _equals(PositionalArgumentReference other) => index == other.index;
1080
1081 @override
1082 ConstantValue evaluate(Environment environment,
1083 ConstantSystem constantSystem) {
1084 throw new UnsupportedError('PositionalArgumentReference.evaluate');
1085 }
904 } 1086 }
905 1087
906 /// A reference to a named parameter. 1088 /// A reference to a named parameter.
907 class NamedArgumentReference extends ConstantExpression { 1089 class NamedArgumentReference extends ConstantExpression {
908 final String name; 1090 final String name;
909 1091
910 NamedArgumentReference(this.name); 1092 NamedArgumentReference(this.name);
911 1093
912 ConstantExpressionKind get kind { 1094 ConstantExpressionKind get kind {
913 return ConstantExpressionKind.NAMED_REFERENCE; 1095 return ConstantExpressionKind.NAMED_REFERENCE;
914 } 1096 }
915 1097
916 accept(ConstantExpressionVisitor visitor, [context]) { 1098 accept(ConstantExpressionVisitor visitor, [context]) {
917 return visitor.visitNamed(this, context); 1099 return visitor.visitNamed(this, context);
918 } 1100 }
919 1101
920 ConstantValue get value { 1102 ConstantValue get value {
921 throw new UnsupportedError('NamedArgumentReference.value'); 1103 throw new UnsupportedError('NamedArgumentReference.value');
922 } 1104 }
923 1105
924 ConstantExpression apply(Arguments arguments) { 1106 ConstantExpression apply(Arguments arguments) {
925 return arguments.getNamedArgument(name); 1107 return arguments.getNamedArgument(name);
926 } 1108 }
927 1109
928 @override 1110 @override
929 int _computeHashCode() => 13 * name.hashCode; 1111 int _computeHashCode() => 13 * name.hashCode;
930 1112
931 @override 1113 @override
932 bool _equals(NamedArgumentReference other) => name == other.name; 1114 bool _equals(NamedArgumentReference other) => name == other.name;
1115
1116 @override
1117 ConstantValue evaluate(Environment environment,
1118 ConstantSystem constantSystem) {
1119 throw new UnsupportedError('NamedArgumentReference.evaluate');
1120 }
933 } 1121 }
934 1122
935 abstract class FromEnvironmentConstantExpression extends ConstantExpression { 1123 abstract class FromEnvironmentConstantExpression extends ConstantExpression {
936 final ConstantValue value; 1124 final ConstantValue value;
937 final String name; 1125 final String name;
938 final ConstantExpression defaultValue; 1126 final ConstantExpression defaultValue;
939 1127
940 FromEnvironmentConstantExpression(this.value, this.name, this.defaultValue); 1128 FromEnvironmentConstantExpression(this.value, this.name, this.defaultValue);
941 1129
942 @override 1130 @override
(...skipping 20 matching lines...) Expand all
963 : super(value, name, defaultValue); 1151 : super(value, name, defaultValue);
964 1152
965 ConstantExpressionKind get kind { 1153 ConstantExpressionKind get kind {
966 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT; 1154 return ConstantExpressionKind.BOOL_FROM_ENVIRONMENT;
967 } 1155 }
968 1156
969 accept(ConstantExpressionVisitor visitor, [context]) { 1157 accept(ConstantExpressionVisitor visitor, [context]) {
970 return visitor.visitBoolFromEnvironment(this, context); 1158 return visitor.visitBoolFromEnvironment(this, context);
971 } 1159 }
972 1160
1161 @override
1162 ConstantValue evaluate(Environment environment,
1163 ConstantSystem constantSystem) {
1164 String text = environment.readFromEnvironment(name);
1165 if (text == 'true') {
1166 return constantSystem.createBool(true);
1167 } else if (text == 'false') {
1168 return constantSystem.createBool(false);
1169 } else {
1170 return defaultValue.evaluate(environment, constantSystem);
1171 }
1172 }
1173
973 ConstantExpression apply(Arguments arguments) { 1174 ConstantExpression apply(Arguments arguments) {
974 return new BoolFromEnvironmentConstantExpression( 1175 return new BoolFromEnvironmentConstantExpression(
975 null, name, defaultValue.apply(arguments)); 1176 null, name, defaultValue.apply(arguments));
976 } 1177 }
977 } 1178 }
978 1179
979 /// A `const int.fromEnvironment` constant. 1180 /// A `const int.fromEnvironment` constant.
980 class IntFromEnvironmentConstantExpression 1181 class IntFromEnvironmentConstantExpression
981 extends FromEnvironmentConstantExpression { 1182 extends FromEnvironmentConstantExpression {
982 1183
983 IntFromEnvironmentConstantExpression( 1184 IntFromEnvironmentConstantExpression(
984 ConstantValue value, 1185 ConstantValue value,
985 String name, 1186 String name,
986 ConstantExpression defaultValue) 1187 ConstantExpression defaultValue)
987 : super(value, name, defaultValue); 1188 : super(value, name, defaultValue);
988 1189
989 ConstantExpressionKind get kind { 1190 ConstantExpressionKind get kind {
990 return ConstantExpressionKind.INT_FROM_ENVIRONMENT; 1191 return ConstantExpressionKind.INT_FROM_ENVIRONMENT;
991 } 1192 }
992 1193
993 accept(ConstantExpressionVisitor visitor, [context]) { 1194 accept(ConstantExpressionVisitor visitor, [context]) {
994 return visitor.visitIntFromEnvironment(this, context); 1195 return visitor.visitIntFromEnvironment(this, context);
995 } 1196 }
996 1197
1198 @override
1199 ConstantValue evaluate(Environment environment,
1200 ConstantSystem constantSystem) {
1201 int value;
1202 String text = environment.readFromEnvironment(name);
1203 if (text != null) {
1204 value = int.parse(text, onError: (_) => null);
1205 }
1206 if (value == null) {
1207 return defaultValue.evaluate(environment, constantSystem);
1208 } else {
1209 return constantSystem.createInt(value);
1210 }
1211 }
1212
997 ConstantExpression apply(Arguments arguments) { 1213 ConstantExpression apply(Arguments arguments) {
998 return new IntFromEnvironmentConstantExpression( 1214 return new IntFromEnvironmentConstantExpression(
999 null, name, defaultValue.apply(arguments)); 1215 null, name, defaultValue.apply(arguments));
1000 } 1216 }
1001 } 1217 }
1002 1218
1003 /// A `const String.fromEnvironment` constant. 1219 /// A `const String.fromEnvironment` constant.
1004 class StringFromEnvironmentConstantExpression 1220 class StringFromEnvironmentConstantExpression
1005 extends FromEnvironmentConstantExpression { 1221 extends FromEnvironmentConstantExpression {
1006 1222
1007 StringFromEnvironmentConstantExpression( 1223 StringFromEnvironmentConstantExpression(
1008 ConstantValue value, 1224 ConstantValue value,
1009 String name, 1225 String name,
1010 ConstantExpression defaultValue) 1226 ConstantExpression defaultValue)
1011 : super(value, name, defaultValue); 1227 : super(value, name, defaultValue);
1012 1228
1013 ConstantExpressionKind get kind { 1229 ConstantExpressionKind get kind {
1014 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT; 1230 return ConstantExpressionKind.STRING_FROM_ENVIRONMENT;
1015 } 1231 }
1016 1232
1017 accept(ConstantExpressionVisitor visitor, [context]) { 1233 accept(ConstantExpressionVisitor visitor, [context]) {
1018 return visitor.visitStringFromEnvironment(this, context); 1234 return visitor.visitStringFromEnvironment(this, context);
1019 } 1235 }
1020 1236
1237 @override
1238 ConstantValue evaluate(Environment environment,
1239 ConstantSystem constantSystem) {
1240 String text = environment.readFromEnvironment(name);
1241 if (text == null) {
1242 return defaultValue.evaluate(environment, constantSystem);
1243 } else {
1244 return constantSystem.createString(new DartString.literal(text));
1245 }
1246 }
1021 1247
1022 ConstantExpression apply(Arguments arguments) { 1248 ConstantExpression apply(Arguments arguments) {
1023 return new StringFromEnvironmentConstantExpression( 1249 return new StringFromEnvironmentConstantExpression(
1024 null, name, defaultValue.apply(arguments)); 1250 null, name, defaultValue.apply(arguments));
1025 } 1251 }
1026 } 1252 }
1027 1253
1028 abstract class ConstantExpressionVisitor<R, A> { 1254 abstract class ConstantExpressionVisitor<R, A> {
1029 const ConstantExpressionVisitor(); 1255 const ConstantExpressionVisitor();
1030 1256
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
1293 sb.write(')'); 1519 sb.write(')');
1294 } 1520 }
1295 1521
1296 @override 1522 @override
1297 visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, [_]) { 1523 visitStringFromEnvironment(StringFromEnvironmentConstantExpression exp, [_]) {
1298 sb.write('const String.fromEnvironment("${exp.name}", defaultValue: '); 1524 sb.write('const String.fromEnvironment("${exp.name}", defaultValue: ');
1299 visit(exp.defaultValue); 1525 visit(exp.defaultValue);
1300 sb.write(')'); 1526 sb.write(')');
1301 } 1527 }
1302 } 1528 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698