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

Side by Side Diff: packages/analyzer/lib/src/dart/constant/value.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 /**
6 * The implementation of the class [DartObject].
7 */
8 library analyzer.src.dart.constant.value;
9
10 import 'dart:collection';
11
12 import 'package:analyzer/dart/constant/value.dart';
13 import 'package:analyzer/dart/element/element.dart';
14 import 'package:analyzer/dart/element/type.dart';
15 import 'package:analyzer/error/error.dart';
16 import 'package:analyzer/src/error/codes.dart';
17 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
18 import 'package:analyzer/src/generated/utilities_general.dart';
19
20 /**
21 * The state of an object representing a boolean value.
22 */
23 class BoolState extends InstanceState {
24 /**
25 * An instance representing the boolean value 'false'.
26 */
27 static BoolState FALSE_STATE = new BoolState(false);
28
29 /**
30 * An instance representing the boolean value 'true'.
31 */
32 static BoolState TRUE_STATE = new BoolState(true);
33
34 /**
35 * A state that can be used to represent a boolean whose value is not known.
36 */
37 static BoolState UNKNOWN_VALUE = new BoolState(null);
38
39 /**
40 * The value of this instance.
41 */
42 final bool value;
43
44 /**
45 * Initialize a newly created state to represent the given [value].
46 */
47 BoolState(this.value);
48
49 @override
50 int get hashCode => value == null ? 0 : (value ? 2 : 3);
51
52 @override
53 bool get isBool => true;
54
55 @override
56 bool get isBoolNumStringOrNull => true;
57
58 @override
59 bool get isUnknown => value == null;
60
61 @override
62 String get typeName => "bool";
63
64 @override
65 bool operator ==(Object object) =>
66 object is BoolState && identical(value, object.value);
67
68 @override
69 BoolState convertToBool() => this;
70
71 @override
72 StringState convertToString() {
73 if (value == null) {
74 return StringState.UNKNOWN_VALUE;
75 }
76 return new StringState(value ? "true" : "false");
77 }
78
79 @override
80 BoolState equalEqual(InstanceState rightOperand) {
81 assertBoolNumStringOrNull(rightOperand);
82 return isIdentical(rightOperand);
83 }
84
85 @override
86 BoolState isIdentical(InstanceState rightOperand) {
87 if (value == null) {
88 return UNKNOWN_VALUE;
89 }
90 if (rightOperand is BoolState) {
91 bool rightValue = rightOperand.value;
92 if (rightValue == null) {
93 return UNKNOWN_VALUE;
94 }
95 return BoolState.from(identical(value, rightValue));
96 } else if (rightOperand is DynamicState) {
97 return UNKNOWN_VALUE;
98 }
99 return FALSE_STATE;
100 }
101
102 @override
103 BoolState logicalAnd(InstanceState rightOperand) {
104 assertBool(rightOperand);
105 if (value == null) {
106 return UNKNOWN_VALUE;
107 }
108 return value ? rightOperand.convertToBool() : FALSE_STATE;
109 }
110
111 @override
112 BoolState logicalNot() {
113 if (value == null) {
114 return UNKNOWN_VALUE;
115 }
116 return value ? FALSE_STATE : TRUE_STATE;
117 }
118
119 @override
120 BoolState logicalOr(InstanceState rightOperand) {
121 assertBool(rightOperand);
122 if (value == null) {
123 return UNKNOWN_VALUE;
124 }
125 return value ? TRUE_STATE : rightOperand.convertToBool();
126 }
127
128 @override
129 String toString() => value == null ? "-unknown-" : (value ? "true" : "false");
130
131 /**
132 * Return the boolean state representing the given boolean [value].
133 */
134 static BoolState from(bool value) =>
135 value ? BoolState.TRUE_STATE : BoolState.FALSE_STATE;
136 }
137
138 /**
139 * A representation of an instance of a Dart class.
140 */
141 class DartObjectImpl implements DartObject {
142 /**
143 * An empty list of objects.
144 */
145 static const List<DartObjectImpl> EMPTY_LIST = const <DartObjectImpl>[];
146
147 /**
148 * The run-time type of this object.
149 */
150 @override
151 final ParameterizedType type;
152
153 /**
154 * The state of the object.
155 */
156 final InstanceState _state;
157
158 /**
159 * Initialize a newly created object to have the given [type] and [_state].
160 */
161 DartObjectImpl(this.type, this._state);
162
163 /**
164 * Create an object to represent an unknown value.
165 */
166 factory DartObjectImpl.validWithUnknownValue(InterfaceType type) {
167 if (type.element.library.isDartCore) {
168 String typeName = type.name;
169 if (typeName == "bool") {
170 return new DartObjectImpl(type, BoolState.UNKNOWN_VALUE);
171 } else if (typeName == "double") {
172 return new DartObjectImpl(type, DoubleState.UNKNOWN_VALUE);
173 } else if (typeName == "int") {
174 return new DartObjectImpl(type, IntState.UNKNOWN_VALUE);
175 } else if (typeName == "String") {
176 return new DartObjectImpl(type, StringState.UNKNOWN_VALUE);
177 }
178 }
179 return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
180 }
181
182 HashMap<String, DartObjectImpl> get fields => _state.fields;
183
184 @override
185 int get hashCode => JenkinsSmiHash.hash2(type.hashCode, _state.hashCode);
186
187 @override
188 bool get hasKnownValue => !_state.isUnknown;
189
190 /**
191 * Return `true` if this object represents an object whose type is 'bool'.
192 */
193 bool get isBool => _state.isBool;
194
195 /**
196 * Return `true` if this object represents an object whose type is either
197 * 'bool', 'num', 'String', or 'Null'.
198 */
199 bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
200
201 @override
202 bool get isNull => _state is NullState;
203
204 /**
205 * Return `true` if this object represents an unknown value.
206 */
207 bool get isUnknown => _state.isUnknown;
208
209 /**
210 * Return `true` if this object represents an instance of a user-defined
211 * class.
212 */
213 bool get isUserDefinedObject => _state is GenericState;
214
215 @override
216 bool operator ==(Object object) {
217 if (object is DartObjectImpl) {
218 return type == object.type && _state == object._state;
219 }
220 return false;
221 }
222
223 /**
224 * Return the result of invoking the '+' operator on this object with the
225 * given [rightOperand]. The [typeProvider] is the type provider used to find
226 * known types.
227 *
228 * Throws an [EvaluationException] if the operator is not appropriate for an
229 * object of this kind.
230 */
231 DartObjectImpl add(TypeProvider typeProvider, DartObjectImpl rightOperand) {
232 InstanceState result = _state.add(rightOperand._state);
233 if (result is IntState) {
234 return new DartObjectImpl(typeProvider.intType, result);
235 } else if (result is DoubleState) {
236 return new DartObjectImpl(typeProvider.doubleType, result);
237 } else if (result is NumState) {
238 return new DartObjectImpl(typeProvider.numType, result);
239 } else if (result is StringState) {
240 return new DartObjectImpl(typeProvider.stringType, result);
241 }
242 // We should never get here.
243 throw new StateError("add returned a ${result.runtimeType}");
244 }
245
246 /**
247 * Return the result of invoking the '&' operator on this object with the
248 * [rightOperand]. The [typeProvider] is the type provider used to find known
249 * types.
250 *
251 * Throws an [EvaluationException] if the operator is not appropriate for an
252 * object of this kind.
253 */
254 DartObjectImpl bitAnd(
255 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
256 new DartObjectImpl(
257 typeProvider.intType, _state.bitAnd(rightOperand._state));
258
259 /**
260 * Return the result of invoking the '~' operator on this object. The
261 * [typeProvider] is the type provider used to find known types.
262 *
263 * Throws an [EvaluationException] if the operator is not appropriate for an
264 * object of this kind.
265 */
266 DartObjectImpl bitNot(TypeProvider typeProvider) =>
267 new DartObjectImpl(typeProvider.intType, _state.bitNot());
268
269 /**
270 * Return the result of invoking the '|' operator on this object with the
271 * [rightOperand]. The [typeProvider] is the type provider used to find known
272 * types.
273 *
274 * Throws an [EvaluationException] if the operator is not appropriate for an
275 * object of this kind.
276 */
277 DartObjectImpl bitOr(
278 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
279 new DartObjectImpl(
280 typeProvider.intType, _state.bitOr(rightOperand._state));
281
282 /**
283 * Return the result of invoking the '^' operator on this object with the
284 * [rightOperand]. The [typeProvider] is the type provider used to find known
285 * types.
286 *
287 * Throws an [EvaluationException] if the operator is not appropriate for an
288 * object of this kind.
289 */
290 DartObjectImpl bitXor(
291 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
292 new DartObjectImpl(
293 typeProvider.intType, _state.bitXor(rightOperand._state));
294
295 /**
296 * Return the result of invoking the ' ' operator on this object with the
297 * [rightOperand]. The [typeProvider] is the type provider used to find known
298 * types.
299 *
300 * Throws an [EvaluationException] if the operator is not appropriate for an
301 * object of this kind.
302 */
303 DartObjectImpl concatenate(
304 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
305 new DartObjectImpl(
306 typeProvider.stringType, _state.concatenate(rightOperand._state));
307
308 /**
309 * Return the result of applying boolean conversion to this object. The
310 * [typeProvider] is the type provider used to find known types.
311 *
312 * Throws an [EvaluationException] if the operator is not appropriate for an
313 * object of this kind.
314 */
315 DartObjectImpl convertToBool(TypeProvider typeProvider) {
316 InterfaceType boolType = typeProvider.boolType;
317 if (identical(type, boolType)) {
318 return this;
319 }
320 return new DartObjectImpl(boolType, _state.convertToBool());
321 }
322
323 /**
324 * Return the result of invoking the '/' operator on this object with the
325 * [rightOperand]. The [typeProvider] is the type provider used to find known
326 * types.
327 *
328 * Throws an [EvaluationException] if the operator is not appropriate for
329 * an object of this kind.
330 */
331 DartObjectImpl divide(
332 TypeProvider typeProvider, DartObjectImpl rightOperand) {
333 InstanceState result = _state.divide(rightOperand._state);
334 if (result is IntState) {
335 return new DartObjectImpl(typeProvider.intType, result);
336 } else if (result is DoubleState) {
337 return new DartObjectImpl(typeProvider.doubleType, result);
338 } else if (result is NumState) {
339 return new DartObjectImpl(typeProvider.numType, result);
340 }
341 // We should never get here.
342 throw new StateError("divide returned a ${result.runtimeType}");
343 }
344
345 /**
346 * Return the result of invoking the '==' operator on this object with the
347 * [rightOperand]. The [typeProvider] is the type provider used to find known
348 * types.
349 *
350 * Throws an [EvaluationException] if the operator is not appropriate for an
351 * object of this kind.
352 */
353 DartObjectImpl equalEqual(
354 TypeProvider typeProvider, DartObjectImpl rightOperand) {
355 if (type != rightOperand.type) {
356 String typeName = type.name;
357 if (!(typeName == "bool" ||
358 typeName == "double" ||
359 typeName == "int" ||
360 typeName == "num" ||
361 typeName == "String" ||
362 typeName == "Null" ||
363 type.isDynamic)) {
364 throw new EvaluationException(
365 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
366 }
367 }
368 return new DartObjectImpl(
369 typeProvider.boolType, _state.equalEqual(rightOperand._state));
370 }
371
372 @override
373 DartObject getField(String name) {
374 InstanceState state = _state;
375 if (state is GenericState) {
376 return state.fields[name];
377 }
378 return null;
379 }
380
381 /**
382 * Return the result of invoking the '&gt;' operator on this object with the
383 * [rightOperand]. The [typeProvider] is the type provider used to find known
384 * types.
385 *
386 * Throws an [EvaluationException] if the operator is not appropriate for an
387 * object of this kind.
388 */
389 DartObjectImpl greaterThan(
390 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
391 new DartObjectImpl(
392 typeProvider.boolType, _state.greaterThan(rightOperand._state));
393
394 /**
395 * Return the result of invoking the '&gt;=' operator on this object with the
396 * [rightOperand]. The [typeProvider] is the type provider used to find known
397 * types.
398 *
399 * Throws an [EvaluationException] if the operator is not appropriate for an
400 * object of this kind.
401 */
402 DartObjectImpl greaterThanOrEqual(
403 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
404 new DartObjectImpl(typeProvider.boolType,
405 _state.greaterThanOrEqual(rightOperand._state));
406
407 /**
408 * Return the result of invoking the '~/' operator on this object with the
409 * [rightOperand]. The [typeProvider] is the type provider used to find known
410 * types.
411 *
412 * Throws an [EvaluationException] if the operator is not appropriate for an
413 * object of this kind.
414 */
415 DartObjectImpl integerDivide(
416 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
417 new DartObjectImpl(
418 typeProvider.intType, _state.integerDivide(rightOperand._state));
419
420 /**
421 * Return the result of invoking the identical function on this object with
422 * the [rightOperand]. The [typeProvider] is the type provider used to find
423 * known types.
424 */
425 DartObjectImpl isIdentical(
426 TypeProvider typeProvider, DartObjectImpl rightOperand) {
427 return new DartObjectImpl(
428 typeProvider.boolType, _state.isIdentical(rightOperand._state));
429 }
430
431 /**
432 * Return the result of invoking the '&lt;' operator on this object with the
433 * [rightOperand]. The [typeProvider] is the type provider used to find known
434 * types.
435 *
436 * Throws an [EvaluationException] if the operator is not appropriate for an
437 * object of this kind.
438 */
439 DartObjectImpl lessThan(
440 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
441 new DartObjectImpl(
442 typeProvider.boolType, _state.lessThan(rightOperand._state));
443
444 /**
445 * Return the result of invoking the '&lt;=' operator on this object with the
446 * [rightOperand]. The [typeProvider] is the type provider used to find known
447 * types.
448 *
449 * Throws an [EvaluationException] if the operator is not appropriate for an
450 * object of this kind.
451 */
452 DartObjectImpl lessThanOrEqual(
453 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
454 new DartObjectImpl(
455 typeProvider.boolType, _state.lessThanOrEqual(rightOperand._state));
456
457 /**
458 * Return the result of invoking the '&&' operator on this object with the
459 * [rightOperand]. The [typeProvider] is the type provider used to find known
460 * types.
461 *
462 * Throws an [EvaluationException] if the operator is not appropriate for an
463 * object of this kind.
464 */
465 DartObjectImpl logicalAnd(
466 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
467 new DartObjectImpl(
468 typeProvider.boolType, _state.logicalAnd(rightOperand._state));
469
470 /**
471 * Return the result of invoking the '!' operator on this object. The
472 * [typeProvider] is the type provider used to find known types.
473 *
474 * Throws an [EvaluationException] if the operator is not appropriate for an
475 * object of this kind.
476 */
477 DartObjectImpl logicalNot(TypeProvider typeProvider) =>
478 new DartObjectImpl(typeProvider.boolType, _state.logicalNot());
479
480 /**
481 * Return the result of invoking the '||' operator on this object with the
482 * [rightOperand]. The [typeProvider] is the type provider used to find known
483 * types.
484 *
485 * Throws an [EvaluationException] if the operator is not appropriate for an
486 * object of this kind.
487 */
488 DartObjectImpl logicalOr(
489 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
490 new DartObjectImpl(
491 typeProvider.boolType, _state.logicalOr(rightOperand._state));
492
493 /**
494 * Return the result of invoking the '-' operator on this object with the
495 * [rightOperand]. The [typeProvider] is the type provider used to find known
496 * types.
497 *
498 * Throws an [EvaluationException] if the operator is not appropriate for an
499 * object of this kind.
500 */
501 DartObjectImpl minus(TypeProvider typeProvider, DartObjectImpl rightOperand) {
502 InstanceState result = _state.minus(rightOperand._state);
503 if (result is IntState) {
504 return new DartObjectImpl(typeProvider.intType, result);
505 } else if (result is DoubleState) {
506 return new DartObjectImpl(typeProvider.doubleType, result);
507 } else if (result is NumState) {
508 return new DartObjectImpl(typeProvider.numType, result);
509 }
510 // We should never get here.
511 throw new StateError("minus returned a ${result.runtimeType}");
512 }
513
514 /**
515 * Return the result of invoking the '-' operator on this object. The
516 * [typeProvider] is the type provider used to find known types.
517 *
518 * Throws an [EvaluationException] if the operator is not appropriate for an
519 * object of this kind.
520 */
521 DartObjectImpl negated(TypeProvider typeProvider) {
522 InstanceState result = _state.negated();
523 if (result is IntState) {
524 return new DartObjectImpl(typeProvider.intType, result);
525 } else if (result is DoubleState) {
526 return new DartObjectImpl(typeProvider.doubleType, result);
527 } else if (result is NumState) {
528 return new DartObjectImpl(typeProvider.numType, result);
529 }
530 // We should never get here.
531 throw new StateError("negated returned a ${result.runtimeType}");
532 }
533
534 /**
535 * Return the result of invoking the '!=' operator on this object with the
536 * [rightOperand]. The [typeProvider] is the type provider used to find known
537 * types.
538 *
539 * Throws an [EvaluationException] if the operator is not appropriate for an
540 * object of this kind.
541 */
542 DartObjectImpl notEqual(
543 TypeProvider typeProvider, DartObjectImpl rightOperand) {
544 if (type != rightOperand.type) {
545 String typeName = type.name;
546 if (typeName != "bool" &&
547 typeName != "double" &&
548 typeName != "int" &&
549 typeName != "num" &&
550 typeName != "String") {
551 return new DartObjectImpl(typeProvider.boolType, BoolState.TRUE_STATE);
552 }
553 }
554 return new DartObjectImpl(typeProvider.boolType,
555 _state.equalEqual(rightOperand._state).logicalNot());
556 }
557
558 /**
559 * Return the result of converting this object to a 'String'. The
560 * [typeProvider] is the type provider used to find known types.
561 *
562 * Throws an [EvaluationException] if the object cannot be converted to a
563 * 'String'.
564 */
565 DartObjectImpl performToString(TypeProvider typeProvider) {
566 InterfaceType stringType = typeProvider.stringType;
567 if (identical(type, stringType)) {
568 return this;
569 }
570 return new DartObjectImpl(stringType, _state.convertToString());
571 }
572
573 /**
574 * Return the result of invoking the '%' operator on this object with the
575 * [rightOperand]. The [typeProvider] is the type provider used to find known
576 * types.
577 *
578 * Throws an [EvaluationException] if the operator is not appropriate for an
579 * object of this kind.
580 */
581 DartObjectImpl remainder(
582 TypeProvider typeProvider, DartObjectImpl rightOperand) {
583 InstanceState result = _state.remainder(rightOperand._state);
584 if (result is IntState) {
585 return new DartObjectImpl(typeProvider.intType, result);
586 } else if (result is DoubleState) {
587 return new DartObjectImpl(typeProvider.doubleType, result);
588 } else if (result is NumState) {
589 return new DartObjectImpl(typeProvider.numType, result);
590 }
591 // We should never get here.
592 throw new StateError("remainder returned a ${result.runtimeType}");
593 }
594
595 /**
596 * Return the result of invoking the '&lt;&lt;' operator on this object with
597 * the [rightOperand]. The [typeProvider] is the type provider used to find
598 * known types.
599 *
600 * Throws an [EvaluationException] if the operator is not appropriate for an
601 * object of this kind.
602 */
603 DartObjectImpl shiftLeft(
604 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
605 new DartObjectImpl(
606 typeProvider.intType, _state.shiftLeft(rightOperand._state));
607
608 /**
609 * Return the result of invoking the '&gt;&gt;' operator on this object with
610 * the [rightOperand]. The [typeProvider] is the type provider used to find
611 * known types.
612 *
613 * Throws an [EvaluationException] if the operator is not appropriate for an
614 * object of this kind.
615 */
616 DartObjectImpl shiftRight(
617 TypeProvider typeProvider, DartObjectImpl rightOperand) =>
618 new DartObjectImpl(
619 typeProvider.intType, _state.shiftRight(rightOperand._state));
620
621 /**
622 * Return the result of invoking the 'length' getter on this object. The
623 * [typeProvider] is the type provider used to find known types.
624 *
625 * Throws an [EvaluationException] if the operator is not appropriate for an
626 * object of this kind.
627 */
628 DartObjectImpl stringLength(TypeProvider typeProvider) =>
629 new DartObjectImpl(typeProvider.intType, _state.stringLength());
630
631 /**
632 * Return the result of invoking the '*' operator on this object with the
633 * [rightOperand]. The [typeProvider] is the type provider used to find known
634 * types.
635 *
636 * Throws an [EvaluationException] if the operator is not appropriate for an
637 * object of this kind.
638 */
639 DartObjectImpl times(TypeProvider typeProvider, DartObjectImpl rightOperand) {
640 InstanceState result = _state.times(rightOperand._state);
641 if (result is IntState) {
642 return new DartObjectImpl(typeProvider.intType, result);
643 } else if (result is DoubleState) {
644 return new DartObjectImpl(typeProvider.doubleType, result);
645 } else if (result is NumState) {
646 return new DartObjectImpl(typeProvider.numType, result);
647 }
648 // We should never get here.
649 throw new StateError("times returned a ${result.runtimeType}");
650 }
651
652 @override
653 bool toBoolValue() {
654 InstanceState state = _state;
655 if (state is BoolState) {
656 return state.value;
657 }
658 return null;
659 }
660
661 @override
662 double toDoubleValue() {
663 InstanceState state = _state;
664 if (state is DoubleState) {
665 return state.value;
666 }
667 return null;
668 }
669
670 @override
671 int toIntValue() {
672 InstanceState state = _state;
673 if (state is IntState) {
674 return state.value;
675 }
676 return null;
677 }
678
679 @override
680 List<DartObject> toListValue() {
681 InstanceState state = _state;
682 if (state is ListState) {
683 return state._elements;
684 }
685 return null;
686 }
687
688 @override
689 Map<DartObject, DartObject> toMapValue() {
690 InstanceState state = _state;
691 if (state is MapState) {
692 return state._entries;
693 }
694 return null;
695 }
696
697 @override
698 String toString() => "${type.displayName} ($_state)";
699
700 @override
701 String toStringValue() {
702 InstanceState state = _state;
703 if (state is StringState) {
704 return state.value;
705 }
706 return null;
707 }
708
709 @override
710 String toSymbolValue() {
711 InstanceState state = _state;
712 if (state is SymbolState) {
713 return state.value;
714 }
715 return null;
716 }
717
718 @override
719 DartType toTypeValue() {
720 InstanceState state = _state;
721 if (state is TypeState) {
722 return state._type;
723 }
724 return null;
725 }
726 }
727
728 /**
729 * The state of an object representing a double.
730 */
731 class DoubleState extends NumState {
732 /**
733 * A state that can be used to represent a double whose value is not known.
734 */
735 static DoubleState UNKNOWN_VALUE = new DoubleState(null);
736
737 /**
738 * The value of this instance.
739 */
740 final double value;
741
742 /**
743 * Initialize a newly created state to represent a double with the given
744 * [value].
745 */
746 DoubleState(this.value);
747
748 @override
749 int get hashCode => value == null ? 0 : value.hashCode;
750
751 @override
752 bool get isBoolNumStringOrNull => true;
753
754 @override
755 bool get isUnknown => value == null;
756
757 @override
758 String get typeName => "double";
759
760 @override
761 bool operator ==(Object object) =>
762 object is DoubleState && (value == object.value);
763
764 @override
765 NumState add(InstanceState rightOperand) {
766 assertNumOrNull(rightOperand);
767 if (value == null) {
768 return UNKNOWN_VALUE;
769 }
770 if (rightOperand is IntState) {
771 int rightValue = rightOperand.value;
772 if (rightValue == null) {
773 return UNKNOWN_VALUE;
774 }
775 return new DoubleState(value + rightValue.toDouble());
776 } else if (rightOperand is DoubleState) {
777 double rightValue = rightOperand.value;
778 if (rightValue == null) {
779 return UNKNOWN_VALUE;
780 }
781 return new DoubleState(value + rightValue);
782 } else if (rightOperand is DynamicState || rightOperand is NumState) {
783 return UNKNOWN_VALUE;
784 }
785 throw new EvaluationException(
786 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
787 }
788
789 @override
790 StringState convertToString() {
791 if (value == null) {
792 return StringState.UNKNOWN_VALUE;
793 }
794 return new StringState(value.toString());
795 }
796
797 @override
798 NumState divide(InstanceState rightOperand) {
799 assertNumOrNull(rightOperand);
800 if (value == null) {
801 return UNKNOWN_VALUE;
802 }
803 if (rightOperand is IntState) {
804 int rightValue = rightOperand.value;
805 if (rightValue == null) {
806 return UNKNOWN_VALUE;
807 }
808 return new DoubleState(value / rightValue.toDouble());
809 } else if (rightOperand is DoubleState) {
810 double rightValue = rightOperand.value;
811 if (rightValue == null) {
812 return UNKNOWN_VALUE;
813 }
814 return new DoubleState(value / rightValue);
815 } else if (rightOperand is DynamicState || rightOperand is NumState) {
816 return UNKNOWN_VALUE;
817 }
818 throw new EvaluationException(
819 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
820 }
821
822 @override
823 BoolState equalEqual(InstanceState rightOperand) {
824 assertBoolNumStringOrNull(rightOperand);
825 return isIdentical(rightOperand);
826 }
827
828 @override
829 BoolState greaterThan(InstanceState rightOperand) {
830 assertNumOrNull(rightOperand);
831 if (value == null) {
832 return BoolState.UNKNOWN_VALUE;
833 }
834 if (rightOperand is IntState) {
835 int rightValue = rightOperand.value;
836 if (rightValue == null) {
837 return BoolState.UNKNOWN_VALUE;
838 }
839 return BoolState.from(value > rightValue.toDouble());
840 } else if (rightOperand is DoubleState) {
841 double rightValue = rightOperand.value;
842 if (rightValue == null) {
843 return BoolState.UNKNOWN_VALUE;
844 }
845 return BoolState.from(value > rightValue);
846 } else if (rightOperand is DynamicState || rightOperand is NumState) {
847 return BoolState.UNKNOWN_VALUE;
848 }
849 throw new EvaluationException(
850 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
851 }
852
853 @override
854 BoolState greaterThanOrEqual(InstanceState rightOperand) {
855 assertNumOrNull(rightOperand);
856 if (value == null) {
857 return BoolState.UNKNOWN_VALUE;
858 }
859 if (rightOperand is IntState) {
860 int rightValue = rightOperand.value;
861 if (rightValue == null) {
862 return BoolState.UNKNOWN_VALUE;
863 }
864 return BoolState.from(value >= rightValue.toDouble());
865 } else if (rightOperand is DoubleState) {
866 double rightValue = rightOperand.value;
867 if (rightValue == null) {
868 return BoolState.UNKNOWN_VALUE;
869 }
870 return BoolState.from(value >= rightValue);
871 } else if (rightOperand is DynamicState || rightOperand is NumState) {
872 return BoolState.UNKNOWN_VALUE;
873 }
874 throw new EvaluationException(
875 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
876 }
877
878 @override
879 IntState integerDivide(InstanceState rightOperand) {
880 assertNumOrNull(rightOperand);
881 if (value == null) {
882 return IntState.UNKNOWN_VALUE;
883 }
884 if (rightOperand is IntState) {
885 int rightValue = rightOperand.value;
886 if (rightValue == null) {
887 return IntState.UNKNOWN_VALUE;
888 }
889 double result = value / rightValue.toDouble();
890 return new IntState(result.toInt());
891 } else if (rightOperand is DoubleState) {
892 double rightValue = rightOperand.value;
893 if (rightValue == null) {
894 return IntState.UNKNOWN_VALUE;
895 }
896 double result = value / rightValue;
897 return new IntState(result.toInt());
898 } else if (rightOperand is DynamicState || rightOperand is NumState) {
899 return IntState.UNKNOWN_VALUE;
900 }
901 throw new EvaluationException(
902 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
903 }
904
905 @override
906 BoolState isIdentical(InstanceState rightOperand) {
907 if (value == null) {
908 return BoolState.UNKNOWN_VALUE;
909 }
910 if (rightOperand is DoubleState) {
911 double rightValue = rightOperand.value;
912 if (rightValue == null) {
913 return BoolState.UNKNOWN_VALUE;
914 }
915 return BoolState.from(value == rightValue);
916 } else if (rightOperand is IntState) {
917 int rightValue = rightOperand.value;
918 if (rightValue == null) {
919 return BoolState.UNKNOWN_VALUE;
920 }
921 return BoolState.from(value == rightValue.toDouble());
922 } else if (rightOperand is DynamicState || rightOperand is NumState) {
923 return BoolState.UNKNOWN_VALUE;
924 }
925 return BoolState.FALSE_STATE;
926 }
927
928 @override
929 BoolState lessThan(InstanceState rightOperand) {
930 assertNumOrNull(rightOperand);
931 if (value == null) {
932 return BoolState.UNKNOWN_VALUE;
933 }
934 if (rightOperand is IntState) {
935 int rightValue = rightOperand.value;
936 if (rightValue == null) {
937 return BoolState.UNKNOWN_VALUE;
938 }
939 return BoolState.from(value < rightValue.toDouble());
940 } else if (rightOperand is DoubleState) {
941 double rightValue = rightOperand.value;
942 if (rightValue == null) {
943 return BoolState.UNKNOWN_VALUE;
944 }
945 return BoolState.from(value < rightValue);
946 } else if (rightOperand is DynamicState || rightOperand is NumState) {
947 return BoolState.UNKNOWN_VALUE;
948 }
949 throw new EvaluationException(
950 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
951 }
952
953 @override
954 BoolState lessThanOrEqual(InstanceState rightOperand) {
955 assertNumOrNull(rightOperand);
956 if (value == null) {
957 return BoolState.UNKNOWN_VALUE;
958 }
959 if (rightOperand is IntState) {
960 int rightValue = rightOperand.value;
961 if (rightValue == null) {
962 return BoolState.UNKNOWN_VALUE;
963 }
964 return BoolState.from(value <= rightValue.toDouble());
965 } else if (rightOperand is DoubleState) {
966 double rightValue = rightOperand.value;
967 if (rightValue == null) {
968 return BoolState.UNKNOWN_VALUE;
969 }
970 return BoolState.from(value <= rightValue);
971 } else if (rightOperand is DynamicState || rightOperand is NumState) {
972 return BoolState.UNKNOWN_VALUE;
973 }
974 throw new EvaluationException(
975 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
976 }
977
978 @override
979 NumState minus(InstanceState rightOperand) {
980 assertNumOrNull(rightOperand);
981 if (value == null) {
982 return UNKNOWN_VALUE;
983 }
984 if (rightOperand is IntState) {
985 int rightValue = rightOperand.value;
986 if (rightValue == null) {
987 return UNKNOWN_VALUE;
988 }
989 return new DoubleState(value - rightValue.toDouble());
990 } else if (rightOperand is DoubleState) {
991 double rightValue = rightOperand.value;
992 if (rightValue == null) {
993 return UNKNOWN_VALUE;
994 }
995 return new DoubleState(value - rightValue);
996 } else if (rightOperand is DynamicState || rightOperand is NumState) {
997 return UNKNOWN_VALUE;
998 }
999 throw new EvaluationException(
1000 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1001 }
1002
1003 @override
1004 NumState negated() {
1005 if (value == null) {
1006 return UNKNOWN_VALUE;
1007 }
1008 return new DoubleState(-(value));
1009 }
1010
1011 @override
1012 NumState remainder(InstanceState rightOperand) {
1013 assertNumOrNull(rightOperand);
1014 if (value == null) {
1015 return UNKNOWN_VALUE;
1016 }
1017 if (rightOperand is IntState) {
1018 int rightValue = rightOperand.value;
1019 if (rightValue == null) {
1020 return UNKNOWN_VALUE;
1021 }
1022 return new DoubleState(value % rightValue.toDouble());
1023 } else if (rightOperand is DoubleState) {
1024 double rightValue = rightOperand.value;
1025 if (rightValue == null) {
1026 return UNKNOWN_VALUE;
1027 }
1028 return new DoubleState(value % rightValue);
1029 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1030 return UNKNOWN_VALUE;
1031 }
1032 throw new EvaluationException(
1033 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1034 }
1035
1036 @override
1037 NumState times(InstanceState rightOperand) {
1038 assertNumOrNull(rightOperand);
1039 if (value == null) {
1040 return UNKNOWN_VALUE;
1041 }
1042 if (rightOperand is IntState) {
1043 int rightValue = rightOperand.value;
1044 if (rightValue == null) {
1045 return UNKNOWN_VALUE;
1046 }
1047 return new DoubleState(value * rightValue.toDouble());
1048 } else if (rightOperand is DoubleState) {
1049 double rightValue = rightOperand.value;
1050 if (rightValue == null) {
1051 return UNKNOWN_VALUE;
1052 }
1053 return new DoubleState(value * rightValue);
1054 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1055 return UNKNOWN_VALUE;
1056 }
1057 throw new EvaluationException(
1058 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1059 }
1060
1061 @override
1062 String toString() => value == null ? "-unknown-" : value.toString();
1063 }
1064
1065 /**
1066 * The state of an object representing a Dart object for which there is no type
1067 * information.
1068 */
1069 class DynamicState extends InstanceState {
1070 /**
1071 * The unique instance of this class.
1072 */
1073 static DynamicState DYNAMIC_STATE = new DynamicState();
1074
1075 @override
1076 bool get isBool => true;
1077
1078 @override
1079 bool get isBoolNumStringOrNull => true;
1080
1081 @override
1082 String get typeName => "dynamic";
1083
1084 @override
1085 NumState add(InstanceState rightOperand) {
1086 assertNumOrNull(rightOperand);
1087 return _unknownNum(rightOperand);
1088 }
1089
1090 @override
1091 IntState bitAnd(InstanceState rightOperand) {
1092 assertIntOrNull(rightOperand);
1093 return IntState.UNKNOWN_VALUE;
1094 }
1095
1096 @override
1097 IntState bitNot() => IntState.UNKNOWN_VALUE;
1098
1099 @override
1100 IntState bitOr(InstanceState rightOperand) {
1101 assertIntOrNull(rightOperand);
1102 return IntState.UNKNOWN_VALUE;
1103 }
1104
1105 @override
1106 IntState bitXor(InstanceState rightOperand) {
1107 assertIntOrNull(rightOperand);
1108 return IntState.UNKNOWN_VALUE;
1109 }
1110
1111 @override
1112 StringState concatenate(InstanceState rightOperand) {
1113 assertString(rightOperand);
1114 return StringState.UNKNOWN_VALUE;
1115 }
1116
1117 @override
1118 BoolState convertToBool() => BoolState.UNKNOWN_VALUE;
1119
1120 @override
1121 StringState convertToString() => StringState.UNKNOWN_VALUE;
1122
1123 @override
1124 NumState divide(InstanceState rightOperand) {
1125 assertNumOrNull(rightOperand);
1126 return _unknownNum(rightOperand);
1127 }
1128
1129 @override
1130 BoolState equalEqual(InstanceState rightOperand) {
1131 assertBoolNumStringOrNull(rightOperand);
1132 return BoolState.UNKNOWN_VALUE;
1133 }
1134
1135 @override
1136 BoolState greaterThan(InstanceState rightOperand) {
1137 assertNumOrNull(rightOperand);
1138 return BoolState.UNKNOWN_VALUE;
1139 }
1140
1141 @override
1142 BoolState greaterThanOrEqual(InstanceState rightOperand) {
1143 assertNumOrNull(rightOperand);
1144 return BoolState.UNKNOWN_VALUE;
1145 }
1146
1147 @override
1148 IntState integerDivide(InstanceState rightOperand) {
1149 assertNumOrNull(rightOperand);
1150 return IntState.UNKNOWN_VALUE;
1151 }
1152
1153 @override
1154 BoolState isIdentical(InstanceState rightOperand) {
1155 return BoolState.UNKNOWN_VALUE;
1156 }
1157
1158 @override
1159 BoolState lessThan(InstanceState rightOperand) {
1160 assertNumOrNull(rightOperand);
1161 return BoolState.UNKNOWN_VALUE;
1162 }
1163
1164 @override
1165 BoolState lessThanOrEqual(InstanceState rightOperand) {
1166 assertNumOrNull(rightOperand);
1167 return BoolState.UNKNOWN_VALUE;
1168 }
1169
1170 @override
1171 BoolState logicalAnd(InstanceState rightOperand) {
1172 assertBool(rightOperand);
1173 return BoolState.UNKNOWN_VALUE;
1174 }
1175
1176 @override
1177 BoolState logicalNot() => BoolState.UNKNOWN_VALUE;
1178
1179 @override
1180 BoolState logicalOr(InstanceState rightOperand) {
1181 assertBool(rightOperand);
1182 return rightOperand.convertToBool();
1183 }
1184
1185 @override
1186 NumState minus(InstanceState rightOperand) {
1187 assertNumOrNull(rightOperand);
1188 return _unknownNum(rightOperand);
1189 }
1190
1191 @override
1192 NumState negated() => NumState.UNKNOWN_VALUE;
1193
1194 @override
1195 NumState remainder(InstanceState rightOperand) {
1196 assertNumOrNull(rightOperand);
1197 return _unknownNum(rightOperand);
1198 }
1199
1200 @override
1201 IntState shiftLeft(InstanceState rightOperand) {
1202 assertIntOrNull(rightOperand);
1203 return IntState.UNKNOWN_VALUE;
1204 }
1205
1206 @override
1207 IntState shiftRight(InstanceState rightOperand) {
1208 assertIntOrNull(rightOperand);
1209 return IntState.UNKNOWN_VALUE;
1210 }
1211
1212 @override
1213 NumState times(InstanceState rightOperand) {
1214 assertNumOrNull(rightOperand);
1215 return _unknownNum(rightOperand);
1216 }
1217
1218 /**
1219 * Return an object representing an unknown numeric value whose type is based
1220 * on the type of the [rightOperand].
1221 */
1222 NumState _unknownNum(InstanceState rightOperand) {
1223 if (rightOperand is IntState) {
1224 return IntState.UNKNOWN_VALUE;
1225 } else if (rightOperand is DoubleState) {
1226 return DoubleState.UNKNOWN_VALUE;
1227 }
1228 return NumState.UNKNOWN_VALUE;
1229 }
1230 }
1231
1232 /**
1233 * Exception that would be thrown during the evaluation of Dart code.
1234 */
1235 class EvaluationException {
1236 /**
1237 * The error code associated with the exception.
1238 */
1239 final ErrorCode errorCode;
1240
1241 /**
1242 * Initialize a newly created exception to have the given [errorCode].
1243 */
1244 EvaluationException(this.errorCode);
1245 }
1246
1247 /**
1248 * The state of an object representing a function.
1249 */
1250 class FunctionState extends InstanceState {
1251 /**
1252 * The element representing the function being modeled.
1253 */
1254 final ExecutableElement _element;
1255
1256 /**
1257 * Initialize a newly created state to represent the function with the given
1258 * [element].
1259 */
1260 FunctionState(this._element);
1261
1262 @override
1263 int get hashCode => _element == null ? 0 : _element.hashCode;
1264
1265 @override
1266 String get typeName => "Function";
1267
1268 @override
1269 bool operator ==(Object object) =>
1270 object is FunctionState && (_element == object._element);
1271
1272 @override
1273 StringState convertToString() {
1274 if (_element == null) {
1275 return StringState.UNKNOWN_VALUE;
1276 }
1277 return new StringState(_element.name);
1278 }
1279
1280 @override
1281 BoolState equalEqual(InstanceState rightOperand) {
1282 return isIdentical(rightOperand);
1283 }
1284
1285 @override
1286 BoolState isIdentical(InstanceState rightOperand) {
1287 if (_element == null) {
1288 return BoolState.UNKNOWN_VALUE;
1289 }
1290 if (rightOperand is FunctionState) {
1291 ExecutableElement rightElement = rightOperand._element;
1292 if (rightElement == null) {
1293 return BoolState.UNKNOWN_VALUE;
1294 }
1295 return BoolState.from(_element == rightElement);
1296 } else if (rightOperand is DynamicState) {
1297 return BoolState.UNKNOWN_VALUE;
1298 }
1299 return BoolState.FALSE_STATE;
1300 }
1301
1302 @override
1303 String toString() => _element == null ? "-unknown-" : _element.name;
1304 }
1305
1306 /**
1307 * The state of an object representing a Dart object for which there is no more
1308 * specific state.
1309 */
1310 class GenericState extends InstanceState {
1311 /**
1312 * Pseudo-field that we use to represent fields in the superclass.
1313 */
1314 static String SUPERCLASS_FIELD = "(super)";
1315
1316 /**
1317 * A state that can be used to represent an object whose state is not known.
1318 */
1319 static GenericState UNKNOWN_VALUE =
1320 new GenericState(new HashMap<String, DartObjectImpl>());
1321
1322 /**
1323 * The values of the fields of this instance.
1324 */
1325 final HashMap<String, DartObjectImpl> _fieldMap;
1326
1327 /**
1328 * Initialize a newly created state to represent a newly created object. The
1329 * [fieldMap] contains the values of the fields of the instance.
1330 */
1331 GenericState(this._fieldMap);
1332
1333 @override
1334 HashMap<String, DartObjectImpl> get fields => _fieldMap;
1335
1336 @override
1337 int get hashCode {
1338 int hashCode = 0;
1339 for (DartObjectImpl value in _fieldMap.values) {
1340 hashCode += value.hashCode;
1341 }
1342 return hashCode;
1343 }
1344
1345 @override
1346 bool get isUnknown => identical(this, UNKNOWN_VALUE);
1347
1348 @override
1349 String get typeName => "user defined type";
1350
1351 @override
1352 bool operator ==(Object object) {
1353 if (object is GenericState) {
1354 HashSet<String> otherFields =
1355 new HashSet<String>.from(object._fieldMap.keys.toSet());
1356 for (String fieldName in _fieldMap.keys.toSet()) {
1357 if (_fieldMap[fieldName] != object._fieldMap[fieldName]) {
1358 return false;
1359 }
1360 otherFields.remove(fieldName);
1361 }
1362 for (String fieldName in otherFields) {
1363 if (object._fieldMap[fieldName] != _fieldMap[fieldName]) {
1364 return false;
1365 }
1366 }
1367 return true;
1368 }
1369 return false;
1370 }
1371
1372 @override
1373 StringState convertToString() => StringState.UNKNOWN_VALUE;
1374
1375 @override
1376 BoolState equalEqual(InstanceState rightOperand) {
1377 assertBoolNumStringOrNull(rightOperand);
1378 return isIdentical(rightOperand);
1379 }
1380
1381 @override
1382 BoolState isIdentical(InstanceState rightOperand) {
1383 if (rightOperand is DynamicState) {
1384 return BoolState.UNKNOWN_VALUE;
1385 }
1386 return BoolState.from(this == rightOperand);
1387 }
1388
1389 @override
1390 String toString() {
1391 StringBuffer buffer = new StringBuffer();
1392 List<String> fieldNames = _fieldMap.keys.toList();
1393 fieldNames.sort();
1394 bool first = true;
1395 for (String fieldName in fieldNames) {
1396 if (first) {
1397 first = false;
1398 } else {
1399 buffer.write('; ');
1400 }
1401 buffer.write(fieldName);
1402 buffer.write(' = ');
1403 buffer.write(_fieldMap[fieldName]);
1404 }
1405 return buffer.toString();
1406 }
1407 }
1408
1409 /**
1410 * The state of an object representing a Dart object.
1411 */
1412 abstract class InstanceState {
1413 /**
1414 * If this represents a generic dart object, return a map from its field names
1415 * to their values. Otherwise return null.
1416 */
1417 HashMap<String, DartObjectImpl> get fields => null;
1418
1419 /**
1420 * Return `true` if this object represents an object whose type is 'bool'.
1421 */
1422 bool get isBool => false;
1423
1424 /**
1425 * Return `true` if this object represents an object whose type is either
1426 * 'bool', 'num', 'String', or 'Null'.
1427 */
1428 bool get isBoolNumStringOrNull => false;
1429
1430 /**
1431 * Return `true` if this object represents an unknown value.
1432 */
1433 bool get isUnknown => false;
1434
1435 /**
1436 * Return the name of the type of this value.
1437 */
1438 String get typeName;
1439
1440 /**
1441 * Return the result of invoking the '+' operator on this object with the
1442 * [rightOperand].
1443 *
1444 * Throws an [EvaluationException] if the operator is not appropriate for an
1445 * object of this kind.
1446 */
1447 InstanceState add(InstanceState rightOperand) {
1448 if (this is StringState && rightOperand is StringState) {
1449 return concatenate(rightOperand);
1450 }
1451 assertNumOrNull(this);
1452 assertNumOrNull(rightOperand);
1453 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1454 }
1455
1456 /**
1457 * Throw an exception if the given [state] does not represent a boolean value.
1458 */
1459 void assertBool(InstanceState state) {
1460 if (!(state is BoolState || state is DynamicState)) {
1461 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
1462 }
1463 }
1464
1465 /**
1466 * Throw an exception if the given [state] does not represent a boolean,
1467 * numeric, string or null value.
1468 */
1469 void assertBoolNumStringOrNull(InstanceState state) {
1470 if (!(state is BoolState ||
1471 state is DoubleState ||
1472 state is IntState ||
1473 state is NumState ||
1474 state is StringState ||
1475 state is NullState ||
1476 state is DynamicState)) {
1477 throw new EvaluationException(
1478 CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
1479 }
1480 }
1481
1482 /**
1483 * Throw an exception if the given [state] does not represent an integer or
1484 * null value.
1485 */
1486 void assertIntOrNull(InstanceState state) {
1487 if (!(state is IntState ||
1488 state is NumState ||
1489 state is NullState ||
1490 state is DynamicState)) {
1491 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_INT);
1492 }
1493 }
1494
1495 /**
1496 * Throw an exception if the given [state] does not represent a boolean,
1497 * numeric, string or null value.
1498 */
1499 void assertNumOrNull(InstanceState state) {
1500 if (!(state is DoubleState ||
1501 state is IntState ||
1502 state is NumState ||
1503 state is NullState ||
1504 state is DynamicState)) {
1505 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_NUM);
1506 }
1507 }
1508
1509 /**
1510 * Throw an exception if the given [state] does not represent a String value.
1511 */
1512 void assertString(InstanceState state) {
1513 if (!(state is StringState || state is DynamicState)) {
1514 throw new EvaluationException(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL);
1515 }
1516 }
1517
1518 /**
1519 * Return the result of invoking the '&' operator on this object with the
1520 * [rightOperand].
1521 *
1522 * Throws an [EvaluationException] if the operator is not appropriate for an
1523 * object of this kind.
1524 */
1525 IntState bitAnd(InstanceState rightOperand) {
1526 assertIntOrNull(this);
1527 assertIntOrNull(rightOperand);
1528 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1529 }
1530
1531 /**
1532 * Return the result of invoking the '~' operator on this object.
1533 *
1534 * Throws an [EvaluationException] if the operator is not appropriate for an
1535 * object of this kind.
1536 */
1537 IntState bitNot() {
1538 assertIntOrNull(this);
1539 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1540 }
1541
1542 /**
1543 * Return the result of invoking the '|' operator on this object with the
1544 * [rightOperand].
1545 *
1546 * Throws an [EvaluationException] if the operator is not appropriate for an
1547 * object of this kind.
1548 */
1549 IntState bitOr(InstanceState rightOperand) {
1550 assertIntOrNull(this);
1551 assertIntOrNull(rightOperand);
1552 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1553 }
1554
1555 /**
1556 * Return the result of invoking the '^' operator on this object with the
1557 * [rightOperand].
1558 *
1559 * Throws an [EvaluationException] if the operator is not appropriate for an
1560 * object of this kind.
1561 */
1562 IntState bitXor(InstanceState rightOperand) {
1563 assertIntOrNull(this);
1564 assertIntOrNull(rightOperand);
1565 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1566 }
1567
1568 /**
1569 * Return the result of invoking the ' ' operator on this object with the
1570 * [rightOperand].
1571 *
1572 * Throws an [EvaluationException] if the operator is not appropriate for an
1573 * object of this kind.
1574 */
1575 StringState concatenate(InstanceState rightOperand) {
1576 assertString(rightOperand);
1577 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1578 }
1579
1580 /**
1581 * Return the result of applying boolean conversion to this object.
1582 *
1583 * Throws an [EvaluationException] if the operator is not appropriate for an
1584 * object of this kind.
1585 */
1586 BoolState convertToBool() => BoolState.FALSE_STATE;
1587
1588 /**
1589 * Return the result of converting this object to a String.
1590 *
1591 * Throws an [EvaluationException] if the operator is not appropriate for an
1592 * object of this kind.
1593 */
1594 StringState convertToString();
1595
1596 /**
1597 * Return the result of invoking the '/' operator on this object with the
1598 * [rightOperand].
1599 *
1600 * Throws an [EvaluationException] if the operator is not appropriate for an
1601 * object of this kind.
1602 */
1603 NumState divide(InstanceState rightOperand) {
1604 assertNumOrNull(this);
1605 assertNumOrNull(rightOperand);
1606 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1607 }
1608
1609 /**
1610 * Return the result of invoking the '==' operator on this object with the
1611 * [rightOperand].
1612 *
1613 * Throws an [EvaluationException] if the operator is not appropriate for an
1614 * object of this kind.
1615 */
1616 BoolState equalEqual(InstanceState rightOperand);
1617
1618 /**
1619 * Return the result of invoking the '&gt;' operator on this object with the
1620 * [rightOperand].
1621 *
1622 * Throws an [EvaluationException] if the operator is not appropriate for an
1623 * object of this kind.
1624 */
1625 BoolState greaterThan(InstanceState rightOperand) {
1626 assertNumOrNull(this);
1627 assertNumOrNull(rightOperand);
1628 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1629 }
1630
1631 /**
1632 * Return the result of invoking the '&gt;=' operator on this object with the
1633 * [rightOperand].
1634 *
1635 * Throws an [EvaluationException] if the operator is not appropriate for an
1636 * object of this kind.
1637 */
1638 BoolState greaterThanOrEqual(InstanceState rightOperand) {
1639 assertNumOrNull(this);
1640 assertNumOrNull(rightOperand);
1641 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1642 }
1643
1644 /**
1645 * Return the result of invoking the '~/' operator on this object with the
1646 * [rightOperand].
1647 *
1648 * Throws an [EvaluationException] if the operator is not appropriate for an
1649 * object of this kind.
1650 */
1651 IntState integerDivide(InstanceState rightOperand) {
1652 assertNumOrNull(this);
1653 assertNumOrNull(rightOperand);
1654 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1655 }
1656
1657 /**
1658 * Return the result of invoking the identical function on this object with
1659 * the [rightOperand].
1660 */
1661 BoolState isIdentical(InstanceState rightOperand);
1662
1663 /**
1664 * Return the result of invoking the '&lt;' operator on this object with the
1665 * [rightOperand].
1666 *
1667 * Throws an [EvaluationException] if the operator is not appropriate for an
1668 * object of this kind.
1669 */
1670 BoolState lessThan(InstanceState rightOperand) {
1671 assertNumOrNull(this);
1672 assertNumOrNull(rightOperand);
1673 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1674 }
1675
1676 /**
1677 * Return the result of invoking the '&lt;=' operator on this object with the
1678 * [rightOperand].
1679 *
1680 * Throws an [EvaluationException] if the operator is not appropriate for an
1681 * object of this kind.
1682 */
1683 BoolState lessThanOrEqual(InstanceState rightOperand) {
1684 assertNumOrNull(this);
1685 assertNumOrNull(rightOperand);
1686 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1687 }
1688
1689 /**
1690 * Return the result of invoking the '&&' operator on this object with the
1691 * [rightOperand].
1692 *
1693 * Throws an [EvaluationException] if the operator is not appropriate for an
1694 * object of this kind.
1695 */
1696 BoolState logicalAnd(InstanceState rightOperand) {
1697 assertBool(this);
1698 assertBool(rightOperand);
1699 return BoolState.FALSE_STATE;
1700 }
1701
1702 /**
1703 * Return the result of invoking the '!' operator on this object.
1704 *
1705 * Throws an [EvaluationException] if the operator is not appropriate for an
1706 * object of this kind.
1707 */
1708 BoolState logicalNot() {
1709 assertBool(this);
1710 return BoolState.TRUE_STATE;
1711 }
1712
1713 /**
1714 * Return the result of invoking the '||' operator on this object with the
1715 * [rightOperand].
1716 *
1717 * Throws an [EvaluationException] if the operator is not appropriate for an
1718 * object of this kind.
1719 */
1720 BoolState logicalOr(InstanceState rightOperand) {
1721 assertBool(this);
1722 assertBool(rightOperand);
1723 return rightOperand.convertToBool();
1724 }
1725
1726 /**
1727 * Return the result of invoking the '-' operator on this object with the
1728 * [rightOperand].
1729 *
1730 * Throws an [EvaluationException] if the operator is not appropriate for an
1731 * object of this kind.
1732 */
1733 NumState minus(InstanceState rightOperand) {
1734 assertNumOrNull(this);
1735 assertNumOrNull(rightOperand);
1736 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1737 }
1738
1739 /**
1740 * Return the result of invoking the '-' operator on this object.
1741 *
1742 * Throws an [EvaluationException] if the operator is not appropriate for an
1743 * object of this kind.
1744 */
1745 NumState negated() {
1746 assertNumOrNull(this);
1747 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1748 }
1749
1750 /**
1751 * Return the result of invoking the '%' operator on this object with the
1752 * [rightOperand].
1753 *
1754 * Throws an [EvaluationException] if the operator is not appropriate for an
1755 * object of this kind.
1756 */
1757 NumState remainder(InstanceState rightOperand) {
1758 assertNumOrNull(this);
1759 assertNumOrNull(rightOperand);
1760 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1761 }
1762
1763 /**
1764 * Return the result of invoking the '&lt;&lt;' operator on this object with
1765 * the [rightOperand].
1766 *
1767 * Throws an [EvaluationException] if the operator is not appropriate for an
1768 * object of this kind.
1769 */
1770 IntState shiftLeft(InstanceState rightOperand) {
1771 assertIntOrNull(this);
1772 assertIntOrNull(rightOperand);
1773 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1774 }
1775
1776 /**
1777 * Return the result of invoking the '&gt;&gt;' operator on this object with
1778 * the [rightOperand].
1779 *
1780 * Throws an [EvaluationException] if the operator is not appropriate for an
1781 * object of this kind.
1782 */
1783 IntState shiftRight(InstanceState rightOperand) {
1784 assertIntOrNull(this);
1785 assertIntOrNull(rightOperand);
1786 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1787 }
1788
1789 /**
1790 * Return the result of invoking the 'length' getter on this object.
1791 *
1792 * Throws an [EvaluationException] if the operator is not appropriate for an
1793 * object of this kind.
1794 */
1795 IntState stringLength() {
1796 assertString(this);
1797 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1798 }
1799
1800 /**
1801 * Return the result of invoking the '*' operator on this object with the
1802 * [rightOperand].
1803 *
1804 * Throws an [EvaluationException] if the operator is not appropriate for an
1805 * object of this kind.
1806 */
1807 NumState times(InstanceState rightOperand) {
1808 assertNumOrNull(this);
1809 assertNumOrNull(rightOperand);
1810 throw new EvaluationException(CompileTimeErrorCode.INVALID_CONSTANT);
1811 }
1812 }
1813
1814 /**
1815 * The state of an object representing an int.
1816 */
1817 class IntState extends NumState {
1818 /**
1819 * A state that can be used to represent an int whose value is not known.
1820 */
1821 static IntState UNKNOWN_VALUE = new IntState(null);
1822
1823 /**
1824 * The value of this instance.
1825 */
1826 final int value;
1827
1828 /**
1829 * Initialize a newly created state to represent an int with the given
1830 * [value].
1831 */
1832 IntState(this.value);
1833
1834 @override
1835 int get hashCode => value == null ? 0 : value.hashCode;
1836
1837 @override
1838 bool get isBoolNumStringOrNull => true;
1839
1840 @override
1841 bool get isUnknown => value == null;
1842
1843 @override
1844 String get typeName => "int";
1845
1846 @override
1847 bool operator ==(Object object) =>
1848 object is IntState && (value == object.value);
1849
1850 @override
1851 NumState add(InstanceState rightOperand) {
1852 assertNumOrNull(rightOperand);
1853 if (value == null) {
1854 if (rightOperand is DoubleState) {
1855 return DoubleState.UNKNOWN_VALUE;
1856 }
1857 return UNKNOWN_VALUE;
1858 }
1859 if (rightOperand is IntState) {
1860 int rightValue = rightOperand.value;
1861 if (rightValue == null) {
1862 return UNKNOWN_VALUE;
1863 }
1864 return new IntState(value + rightValue);
1865 } else if (rightOperand is DoubleState) {
1866 double rightValue = rightOperand.value;
1867 if (rightValue == null) {
1868 return DoubleState.UNKNOWN_VALUE;
1869 }
1870 return new DoubleState(value.toDouble() + rightValue);
1871 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1872 return UNKNOWN_VALUE;
1873 }
1874 throw new EvaluationException(
1875 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1876 }
1877
1878 @override
1879 IntState bitAnd(InstanceState rightOperand) {
1880 assertIntOrNull(rightOperand);
1881 if (value == null) {
1882 return UNKNOWN_VALUE;
1883 }
1884 if (rightOperand is IntState) {
1885 int rightValue = rightOperand.value;
1886 if (rightValue == null) {
1887 return UNKNOWN_VALUE;
1888 }
1889 return new IntState(value & rightValue);
1890 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1891 return UNKNOWN_VALUE;
1892 }
1893 throw new EvaluationException(
1894 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1895 }
1896
1897 @override
1898 IntState bitNot() {
1899 if (value == null) {
1900 return UNKNOWN_VALUE;
1901 }
1902 return new IntState(~value);
1903 }
1904
1905 @override
1906 IntState bitOr(InstanceState rightOperand) {
1907 assertIntOrNull(rightOperand);
1908 if (value == null) {
1909 return UNKNOWN_VALUE;
1910 }
1911 if (rightOperand is IntState) {
1912 int rightValue = rightOperand.value;
1913 if (rightValue == null) {
1914 return UNKNOWN_VALUE;
1915 }
1916 return new IntState(value | rightValue);
1917 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1918 return UNKNOWN_VALUE;
1919 }
1920 throw new EvaluationException(
1921 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1922 }
1923
1924 @override
1925 IntState bitXor(InstanceState rightOperand) {
1926 assertIntOrNull(rightOperand);
1927 if (value == null) {
1928 return UNKNOWN_VALUE;
1929 }
1930 if (rightOperand is IntState) {
1931 int rightValue = rightOperand.value;
1932 if (rightValue == null) {
1933 return UNKNOWN_VALUE;
1934 }
1935 return new IntState(value ^ rightValue);
1936 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1937 return UNKNOWN_VALUE;
1938 }
1939 throw new EvaluationException(
1940 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1941 }
1942
1943 @override
1944 StringState convertToString() {
1945 if (value == null) {
1946 return StringState.UNKNOWN_VALUE;
1947 }
1948 return new StringState(value.toString());
1949 }
1950
1951 @override
1952 NumState divide(InstanceState rightOperand) {
1953 assertNumOrNull(rightOperand);
1954 if (value == null) {
1955 return DoubleState.UNKNOWN_VALUE;
1956 }
1957 if (rightOperand is IntState) {
1958 int rightValue = rightOperand.value;
1959 if (rightValue == null) {
1960 return DoubleState.UNKNOWN_VALUE;
1961 } else {
1962 return new DoubleState(value.toDouble() / rightValue.toDouble());
1963 }
1964 } else if (rightOperand is DoubleState) {
1965 double rightValue = rightOperand.value;
1966 if (rightValue == null) {
1967 return DoubleState.UNKNOWN_VALUE;
1968 }
1969 return new DoubleState(value.toDouble() / rightValue);
1970 } else if (rightOperand is DynamicState || rightOperand is NumState) {
1971 return DoubleState.UNKNOWN_VALUE;
1972 }
1973 throw new EvaluationException(
1974 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
1975 }
1976
1977 @override
1978 BoolState equalEqual(InstanceState rightOperand) {
1979 assertBoolNumStringOrNull(rightOperand);
1980 return isIdentical(rightOperand);
1981 }
1982
1983 @override
1984 BoolState greaterThan(InstanceState rightOperand) {
1985 assertNumOrNull(rightOperand);
1986 if (value == null) {
1987 return BoolState.UNKNOWN_VALUE;
1988 }
1989 if (rightOperand is IntState) {
1990 int rightValue = rightOperand.value;
1991 if (rightValue == null) {
1992 return BoolState.UNKNOWN_VALUE;
1993 }
1994 return BoolState.from(value.compareTo(rightValue) > 0);
1995 } else if (rightOperand is DoubleState) {
1996 double rightValue = rightOperand.value;
1997 if (rightValue == null) {
1998 return BoolState.UNKNOWN_VALUE;
1999 }
2000 return BoolState.from(value.toDouble() > rightValue);
2001 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2002 return BoolState.UNKNOWN_VALUE;
2003 }
2004 throw new EvaluationException(
2005 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2006 }
2007
2008 @override
2009 BoolState greaterThanOrEqual(InstanceState rightOperand) {
2010 assertNumOrNull(rightOperand);
2011 if (value == null) {
2012 return BoolState.UNKNOWN_VALUE;
2013 }
2014 if (rightOperand is IntState) {
2015 int rightValue = rightOperand.value;
2016 if (rightValue == null) {
2017 return BoolState.UNKNOWN_VALUE;
2018 }
2019 return BoolState.from(value.compareTo(rightValue) >= 0);
2020 } else if (rightOperand is DoubleState) {
2021 double rightValue = rightOperand.value;
2022 if (rightValue == null) {
2023 return BoolState.UNKNOWN_VALUE;
2024 }
2025 return BoolState.from(value.toDouble() >= rightValue);
2026 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2027 return BoolState.UNKNOWN_VALUE;
2028 }
2029 throw new EvaluationException(
2030 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2031 }
2032
2033 @override
2034 IntState integerDivide(InstanceState rightOperand) {
2035 assertNumOrNull(rightOperand);
2036 if (value == null) {
2037 return UNKNOWN_VALUE;
2038 }
2039 if (rightOperand is IntState) {
2040 int rightValue = rightOperand.value;
2041 if (rightValue == null) {
2042 return UNKNOWN_VALUE;
2043 } else if (rightValue == 0) {
2044 throw new EvaluationException(
2045 CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
2046 }
2047 return new IntState(value ~/ rightValue);
2048 } else if (rightOperand is DoubleState) {
2049 double rightValue = rightOperand.value;
2050 if (rightValue == null) {
2051 return UNKNOWN_VALUE;
2052 }
2053 double result = value.toDouble() / rightValue;
2054 return new IntState(result.toInt());
2055 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2056 return UNKNOWN_VALUE;
2057 }
2058 throw new EvaluationException(
2059 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2060 }
2061
2062 @override
2063 BoolState isIdentical(InstanceState rightOperand) {
2064 if (value == null) {
2065 return BoolState.UNKNOWN_VALUE;
2066 }
2067 if (rightOperand is IntState) {
2068 int rightValue = rightOperand.value;
2069 if (rightValue == null) {
2070 return BoolState.UNKNOWN_VALUE;
2071 }
2072 return BoolState.from(value == rightValue);
2073 } else if (rightOperand is DoubleState) {
2074 double rightValue = rightOperand.value;
2075 if (rightValue == null) {
2076 return BoolState.UNKNOWN_VALUE;
2077 }
2078 return BoolState.from(rightValue == value.toDouble());
2079 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2080 return BoolState.UNKNOWN_VALUE;
2081 }
2082 return BoolState.FALSE_STATE;
2083 }
2084
2085 @override
2086 BoolState lessThan(InstanceState rightOperand) {
2087 assertNumOrNull(rightOperand);
2088 if (value == null) {
2089 return BoolState.UNKNOWN_VALUE;
2090 }
2091 if (rightOperand is IntState) {
2092 int rightValue = rightOperand.value;
2093 if (rightValue == null) {
2094 return BoolState.UNKNOWN_VALUE;
2095 }
2096 return BoolState.from(value.compareTo(rightValue) < 0);
2097 } else if (rightOperand is DoubleState) {
2098 double rightValue = rightOperand.value;
2099 if (rightValue == null) {
2100 return BoolState.UNKNOWN_VALUE;
2101 }
2102 return BoolState.from(value.toDouble() < rightValue);
2103 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2104 return BoolState.UNKNOWN_VALUE;
2105 }
2106 throw new EvaluationException(
2107 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2108 }
2109
2110 @override
2111 BoolState lessThanOrEqual(InstanceState rightOperand) {
2112 assertNumOrNull(rightOperand);
2113 if (value == null) {
2114 return BoolState.UNKNOWN_VALUE;
2115 }
2116 if (rightOperand is IntState) {
2117 int rightValue = rightOperand.value;
2118 if (rightValue == null) {
2119 return BoolState.UNKNOWN_VALUE;
2120 }
2121 return BoolState.from(value.compareTo(rightValue) <= 0);
2122 } else if (rightOperand is DoubleState) {
2123 double rightValue = rightOperand.value;
2124 if (rightValue == null) {
2125 return BoolState.UNKNOWN_VALUE;
2126 }
2127 return BoolState.from(value.toDouble() <= rightValue);
2128 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2129 return BoolState.UNKNOWN_VALUE;
2130 }
2131 throw new EvaluationException(
2132 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2133 }
2134
2135 @override
2136 NumState minus(InstanceState rightOperand) {
2137 assertNumOrNull(rightOperand);
2138 if (value == null) {
2139 if (rightOperand is DoubleState) {
2140 return DoubleState.UNKNOWN_VALUE;
2141 }
2142 return UNKNOWN_VALUE;
2143 }
2144 if (rightOperand is IntState) {
2145 int rightValue = rightOperand.value;
2146 if (rightValue == null) {
2147 return UNKNOWN_VALUE;
2148 }
2149 return new IntState(value - rightValue);
2150 } else if (rightOperand is DoubleState) {
2151 double rightValue = rightOperand.value;
2152 if (rightValue == null) {
2153 return DoubleState.UNKNOWN_VALUE;
2154 }
2155 return new DoubleState(value.toDouble() - rightValue);
2156 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2157 return UNKNOWN_VALUE;
2158 }
2159 throw new EvaluationException(
2160 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2161 }
2162
2163 @override
2164 NumState negated() {
2165 if (value == null) {
2166 return UNKNOWN_VALUE;
2167 }
2168 return new IntState(-value);
2169 }
2170
2171 @override
2172 NumState remainder(InstanceState rightOperand) {
2173 assertNumOrNull(rightOperand);
2174 if (value == null) {
2175 if (rightOperand is DoubleState) {
2176 return DoubleState.UNKNOWN_VALUE;
2177 }
2178 return UNKNOWN_VALUE;
2179 }
2180 if (rightOperand is IntState) {
2181 int rightValue = rightOperand.value;
2182 if (rightValue == null) {
2183 return UNKNOWN_VALUE;
2184 } else if (rightValue == 0) {
2185 return new DoubleState(value.toDouble() % rightValue.toDouble());
2186 }
2187 return new IntState(value.remainder(rightValue));
2188 } else if (rightOperand is DoubleState) {
2189 double rightValue = rightOperand.value;
2190 if (rightValue == null) {
2191 return DoubleState.UNKNOWN_VALUE;
2192 }
2193 return new DoubleState(value.toDouble() % rightValue);
2194 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2195 return UNKNOWN_VALUE;
2196 }
2197 throw new EvaluationException(
2198 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2199 }
2200
2201 @override
2202 IntState shiftLeft(InstanceState rightOperand) {
2203 assertIntOrNull(rightOperand);
2204 if (value == null) {
2205 return UNKNOWN_VALUE;
2206 }
2207 if (rightOperand is IntState) {
2208 int rightValue = rightOperand.value;
2209 if (rightValue == null) {
2210 return UNKNOWN_VALUE;
2211 } else if (rightValue.bitLength > 31) {
2212 return UNKNOWN_VALUE;
2213 }
2214 return new IntState(value << rightValue);
2215 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2216 return UNKNOWN_VALUE;
2217 }
2218 throw new EvaluationException(
2219 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2220 }
2221
2222 @override
2223 IntState shiftRight(InstanceState rightOperand) {
2224 assertIntOrNull(rightOperand);
2225 if (value == null) {
2226 return UNKNOWN_VALUE;
2227 }
2228 if (rightOperand is IntState) {
2229 int rightValue = rightOperand.value;
2230 if (rightValue == null) {
2231 return UNKNOWN_VALUE;
2232 } else if (rightValue.bitLength > 31) {
2233 return UNKNOWN_VALUE;
2234 }
2235 return new IntState(value >> rightValue);
2236 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2237 return UNKNOWN_VALUE;
2238 }
2239 throw new EvaluationException(
2240 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2241 }
2242
2243 @override
2244 NumState times(InstanceState rightOperand) {
2245 assertNumOrNull(rightOperand);
2246 if (value == null) {
2247 if (rightOperand is DoubleState) {
2248 return DoubleState.UNKNOWN_VALUE;
2249 }
2250 return UNKNOWN_VALUE;
2251 }
2252 if (rightOperand is IntState) {
2253 int rightValue = rightOperand.value;
2254 if (rightValue == null) {
2255 return UNKNOWN_VALUE;
2256 }
2257 return new IntState(value * rightValue);
2258 } else if (rightOperand is DoubleState) {
2259 double rightValue = rightOperand.value;
2260 if (rightValue == null) {
2261 return DoubleState.UNKNOWN_VALUE;
2262 }
2263 return new DoubleState(value.toDouble() * rightValue);
2264 } else if (rightOperand is DynamicState || rightOperand is NumState) {
2265 return UNKNOWN_VALUE;
2266 }
2267 throw new EvaluationException(
2268 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2269 }
2270
2271 @override
2272 String toString() => value == null ? "-unknown-" : value.toString();
2273 }
2274
2275 /**
2276 * The state of an object representing a list.
2277 */
2278 class ListState extends InstanceState {
2279 /**
2280 * The elements of the list.
2281 */
2282 final List<DartObjectImpl> _elements;
2283
2284 /**
2285 * Initialize a newly created state to represent a list with the given
2286 * [elements].
2287 */
2288 ListState(this._elements);
2289
2290 @override
2291 int get hashCode {
2292 int value = 0;
2293 int count = _elements.length;
2294 for (int i = 0; i < count; i++) {
2295 value = (value << 3) ^ _elements[i].hashCode;
2296 }
2297 return value;
2298 }
2299
2300 @override
2301 String get typeName => "List";
2302
2303 @override
2304 bool operator ==(Object object) {
2305 if (object is ListState) {
2306 List<DartObjectImpl> otherElements = object._elements;
2307 int count = _elements.length;
2308 if (otherElements.length != count) {
2309 return false;
2310 } else if (count == 0) {
2311 return true;
2312 }
2313 for (int i = 0; i < count; i++) {
2314 if (_elements[i] != otherElements[i]) {
2315 return false;
2316 }
2317 }
2318 return true;
2319 }
2320 return false;
2321 }
2322
2323 @override
2324 StringState convertToString() => StringState.UNKNOWN_VALUE;
2325
2326 @override
2327 BoolState equalEqual(InstanceState rightOperand) {
2328 assertBoolNumStringOrNull(rightOperand);
2329 return isIdentical(rightOperand);
2330 }
2331
2332 @override
2333 BoolState isIdentical(InstanceState rightOperand) {
2334 if (rightOperand is DynamicState) {
2335 return BoolState.UNKNOWN_VALUE;
2336 }
2337 return BoolState.from(this == rightOperand);
2338 }
2339
2340 @override
2341 String toString() {
2342 StringBuffer buffer = new StringBuffer();
2343 buffer.write('[');
2344 bool first = true;
2345 _elements.forEach((DartObjectImpl element) {
2346 if (first) {
2347 first = false;
2348 } else {
2349 buffer.write(', ');
2350 }
2351 buffer.write(element);
2352 });
2353 buffer.write(']');
2354 return buffer.toString();
2355 }
2356 }
2357
2358 /**
2359 * The state of an object representing a map.
2360 */
2361 class MapState extends InstanceState {
2362 /**
2363 * The entries in the map.
2364 */
2365 final HashMap<DartObjectImpl, DartObjectImpl> _entries;
2366
2367 /**
2368 * Initialize a newly created state to represent a map with the given
2369 * [entries].
2370 */
2371 MapState(this._entries);
2372
2373 @override
2374 int get hashCode {
2375 int value = 0;
2376 for (DartObjectImpl key in _entries.keys.toSet()) {
2377 value = (value << 3) ^ key.hashCode;
2378 }
2379 return value;
2380 }
2381
2382 @override
2383 String get typeName => "Map";
2384
2385 @override
2386 bool operator ==(Object object) {
2387 if (object is MapState) {
2388 HashMap<DartObjectImpl, DartObjectImpl> otherElements = object._entries;
2389 int count = _entries.length;
2390 if (otherElements.length != count) {
2391 return false;
2392 } else if (count == 0) {
2393 return true;
2394 }
2395 for (DartObjectImpl key in _entries.keys) {
2396 DartObjectImpl value = _entries[key];
2397 DartObjectImpl otherValue = otherElements[key];
2398 if (value != otherValue) {
2399 return false;
2400 }
2401 }
2402 return true;
2403 }
2404 return false;
2405 }
2406
2407 @override
2408 StringState convertToString() => StringState.UNKNOWN_VALUE;
2409
2410 @override
2411 BoolState equalEqual(InstanceState rightOperand) {
2412 assertBoolNumStringOrNull(rightOperand);
2413 return isIdentical(rightOperand);
2414 }
2415
2416 @override
2417 BoolState isIdentical(InstanceState rightOperand) {
2418 if (rightOperand is DynamicState) {
2419 return BoolState.UNKNOWN_VALUE;
2420 }
2421 return BoolState.from(this == rightOperand);
2422 }
2423
2424 @override
2425 String toString() {
2426 StringBuffer buffer = new StringBuffer();
2427 buffer.write('{');
2428 bool first = true;
2429 _entries.forEach((DartObjectImpl key, DartObjectImpl value) {
2430 if (first) {
2431 first = false;
2432 } else {
2433 buffer.write(', ');
2434 }
2435 buffer.write(key);
2436 buffer.write(' = ');
2437 buffer.write(value);
2438 });
2439 buffer.write('}');
2440 return buffer.toString();
2441 }
2442 }
2443
2444 /**
2445 * The state of an object representing the value 'null'.
2446 */
2447 class NullState extends InstanceState {
2448 /**
2449 * An instance representing the boolean value 'null'.
2450 */
2451 static NullState NULL_STATE = new NullState();
2452
2453 @override
2454 int get hashCode => 0;
2455
2456 @override
2457 bool get isBoolNumStringOrNull => true;
2458
2459 @override
2460 String get typeName => "Null";
2461
2462 @override
2463 bool operator ==(Object object) => object is NullState;
2464
2465 @override
2466 BoolState convertToBool() {
2467 throw new EvaluationException(
2468 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2469 }
2470
2471 @override
2472 StringState convertToString() => new StringState("null");
2473
2474 @override
2475 BoolState equalEqual(InstanceState rightOperand) {
2476 assertBoolNumStringOrNull(rightOperand);
2477 return isIdentical(rightOperand);
2478 }
2479
2480 @override
2481 BoolState isIdentical(InstanceState rightOperand) {
2482 if (rightOperand is DynamicState) {
2483 return BoolState.UNKNOWN_VALUE;
2484 }
2485 return BoolState.from(rightOperand is NullState);
2486 }
2487
2488 @override
2489 BoolState logicalNot() {
2490 throw new EvaluationException(
2491 CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
2492 }
2493
2494 @override
2495 String toString() => "null";
2496 }
2497
2498 /**
2499 * The state of an object representing a number of an unknown type (a 'num').
2500 */
2501 class NumState extends InstanceState {
2502 /**
2503 * A state that can be used to represent a number whose value is not known.
2504 */
2505 static NumState UNKNOWN_VALUE = new NumState();
2506
2507 @override
2508 int get hashCode => 7;
2509
2510 @override
2511 bool get isBoolNumStringOrNull => true;
2512
2513 @override
2514 bool get isUnknown => identical(this, UNKNOWN_VALUE);
2515
2516 @override
2517 String get typeName => "num";
2518
2519 @override
2520 bool operator ==(Object object) => object is NumState;
2521
2522 @override
2523 NumState add(InstanceState rightOperand) {
2524 assertNumOrNull(rightOperand);
2525 return UNKNOWN_VALUE;
2526 }
2527
2528 @override
2529 StringState convertToString() => StringState.UNKNOWN_VALUE;
2530
2531 @override
2532 NumState divide(InstanceState rightOperand) {
2533 assertNumOrNull(rightOperand);
2534 return DoubleState.UNKNOWN_VALUE;
2535 }
2536
2537 @override
2538 BoolState equalEqual(InstanceState rightOperand) {
2539 assertBoolNumStringOrNull(rightOperand);
2540 return BoolState.UNKNOWN_VALUE;
2541 }
2542
2543 @override
2544 BoolState greaterThan(InstanceState rightOperand) {
2545 assertNumOrNull(rightOperand);
2546 return BoolState.UNKNOWN_VALUE;
2547 }
2548
2549 @override
2550 BoolState greaterThanOrEqual(InstanceState rightOperand) {
2551 assertNumOrNull(rightOperand);
2552 return BoolState.UNKNOWN_VALUE;
2553 }
2554
2555 @override
2556 IntState integerDivide(InstanceState rightOperand) {
2557 assertNumOrNull(rightOperand);
2558 if (rightOperand is IntState) {
2559 int rightValue = rightOperand.value;
2560 if (rightValue == null) {
2561 return IntState.UNKNOWN_VALUE;
2562 } else if (rightValue == 0) {
2563 throw new EvaluationException(
2564 CompileTimeErrorCode.CONST_EVAL_THROWS_IDBZE);
2565 }
2566 } else if (rightOperand is DynamicState) {
2567 return IntState.UNKNOWN_VALUE;
2568 }
2569 return IntState.UNKNOWN_VALUE;
2570 }
2571
2572 @override
2573 BoolState isIdentical(InstanceState rightOperand) {
2574 return BoolState.UNKNOWN_VALUE;
2575 }
2576
2577 @override
2578 BoolState lessThan(InstanceState rightOperand) {
2579 assertNumOrNull(rightOperand);
2580 return BoolState.UNKNOWN_VALUE;
2581 }
2582
2583 @override
2584 BoolState lessThanOrEqual(InstanceState rightOperand) {
2585 assertNumOrNull(rightOperand);
2586 return BoolState.UNKNOWN_VALUE;
2587 }
2588
2589 @override
2590 NumState minus(InstanceState rightOperand) {
2591 assertNumOrNull(rightOperand);
2592 return UNKNOWN_VALUE;
2593 }
2594
2595 @override
2596 NumState negated() => UNKNOWN_VALUE;
2597
2598 @override
2599 NumState remainder(InstanceState rightOperand) {
2600 assertNumOrNull(rightOperand);
2601 return UNKNOWN_VALUE;
2602 }
2603
2604 @override
2605 NumState times(InstanceState rightOperand) {
2606 assertNumOrNull(rightOperand);
2607 return UNKNOWN_VALUE;
2608 }
2609
2610 @override
2611 String toString() => "-unknown-";
2612 }
2613
2614 /**
2615 * The state of an object representing a string.
2616 */
2617 class StringState extends InstanceState {
2618 /**
2619 * A state that can be used to represent a double whose value is not known.
2620 */
2621 static StringState UNKNOWN_VALUE = new StringState(null);
2622
2623 /**
2624 * The value of this instance.
2625 */
2626 final String value;
2627
2628 /**
2629 * Initialize a newly created state to represent the given [value].
2630 */
2631 StringState(this.value);
2632
2633 @override
2634 int get hashCode => value == null ? 0 : value.hashCode;
2635
2636 @override
2637 bool get isBoolNumStringOrNull => true;
2638
2639 @override
2640 bool get isUnknown => value == null;
2641
2642 @override
2643 String get typeName => "String";
2644
2645 @override
2646 bool operator ==(Object object) =>
2647 object is StringState && (value == object.value);
2648
2649 @override
2650 StringState concatenate(InstanceState rightOperand) {
2651 if (value == null) {
2652 return UNKNOWN_VALUE;
2653 }
2654 if (rightOperand is StringState) {
2655 String rightValue = rightOperand.value;
2656 if (rightValue == null) {
2657 return UNKNOWN_VALUE;
2658 }
2659 return new StringState("$value$rightValue");
2660 } else if (rightOperand is DynamicState) {
2661 return UNKNOWN_VALUE;
2662 }
2663 return super.concatenate(rightOperand);
2664 }
2665
2666 @override
2667 StringState convertToString() => this;
2668
2669 @override
2670 BoolState equalEqual(InstanceState rightOperand) {
2671 assertBoolNumStringOrNull(rightOperand);
2672 return isIdentical(rightOperand);
2673 }
2674
2675 @override
2676 BoolState isIdentical(InstanceState rightOperand) {
2677 if (value == null) {
2678 return BoolState.UNKNOWN_VALUE;
2679 }
2680 if (rightOperand is StringState) {
2681 String rightValue = rightOperand.value;
2682 if (rightValue == null) {
2683 return BoolState.UNKNOWN_VALUE;
2684 }
2685 return BoolState.from(value == rightValue);
2686 } else if (rightOperand is DynamicState) {
2687 return BoolState.UNKNOWN_VALUE;
2688 }
2689 return BoolState.FALSE_STATE;
2690 }
2691
2692 @override
2693 IntState stringLength() {
2694 if (value == null) {
2695 return IntState.UNKNOWN_VALUE;
2696 }
2697 return new IntState(value.length);
2698 }
2699
2700 @override
2701 String toString() => value == null ? "-unknown-" : "'$value'";
2702 }
2703
2704 /**
2705 * The state of an object representing a symbol.
2706 */
2707 class SymbolState extends InstanceState {
2708 /**
2709 * The value of this instance.
2710 */
2711 final String value;
2712
2713 /**
2714 * Initialize a newly created state to represent the given [value].
2715 */
2716 SymbolState(this.value);
2717
2718 @override
2719 int get hashCode => value == null ? 0 : value.hashCode;
2720
2721 @override
2722 String get typeName => "Symbol";
2723
2724 @override
2725 bool operator ==(Object object) =>
2726 object is SymbolState && (value == object.value);
2727
2728 @override
2729 StringState convertToString() {
2730 if (value == null) {
2731 return StringState.UNKNOWN_VALUE;
2732 }
2733 return new StringState(value);
2734 }
2735
2736 @override
2737 BoolState equalEqual(InstanceState rightOperand) {
2738 assertBoolNumStringOrNull(rightOperand);
2739 return isIdentical(rightOperand);
2740 }
2741
2742 @override
2743 BoolState isIdentical(InstanceState rightOperand) {
2744 if (value == null) {
2745 return BoolState.UNKNOWN_VALUE;
2746 }
2747 if (rightOperand is SymbolState) {
2748 String rightValue = rightOperand.value;
2749 if (rightValue == null) {
2750 return BoolState.UNKNOWN_VALUE;
2751 }
2752 return BoolState.from(value == rightValue);
2753 } else if (rightOperand is DynamicState) {
2754 return BoolState.UNKNOWN_VALUE;
2755 }
2756 return BoolState.FALSE_STATE;
2757 }
2758
2759 @override
2760 String toString() => value == null ? "-unknown-" : "#$value";
2761 }
2762
2763 /**
2764 * The state of an object representing a type.
2765 */
2766 class TypeState extends InstanceState {
2767 /**
2768 * The element representing the type being modeled.
2769 */
2770 final DartType _type;
2771
2772 /**
2773 * Initialize a newly created state to represent the given [value].
2774 */
2775 TypeState(this._type);
2776
2777 @override
2778 int get hashCode => _type?.hashCode ?? 0;
2779
2780 @override
2781 String get typeName => "Type";
2782
2783 @override
2784 bool operator ==(Object object) =>
2785 object is TypeState && (_type == object._type);
2786
2787 @override
2788 StringState convertToString() {
2789 if (_type == null) {
2790 return StringState.UNKNOWN_VALUE;
2791 }
2792 return new StringState(_type.displayName);
2793 }
2794
2795 @override
2796 BoolState equalEqual(InstanceState rightOperand) {
2797 assertBoolNumStringOrNull(rightOperand);
2798 return isIdentical(rightOperand);
2799 }
2800
2801 @override
2802 BoolState isIdentical(InstanceState rightOperand) {
2803 if (_type == null) {
2804 return BoolState.UNKNOWN_VALUE;
2805 }
2806 if (rightOperand is TypeState) {
2807 DartType rightType = rightOperand._type;
2808 if (rightType == null) {
2809 return BoolState.UNKNOWN_VALUE;
2810 }
2811 return BoolState.from(_type == rightType);
2812 } else if (rightOperand is DynamicState) {
2813 return BoolState.UNKNOWN_VALUE;
2814 }
2815 return BoolState.FALSE_STATE;
2816 }
2817
2818 @override
2819 String toString() => _type?.toString() ?? "-unknown-";
2820 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/dart/constant/utilities.dart ('k') | packages/analyzer/lib/src/dart/element/builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698