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

Side by Side Diff: pkg/analyzer/test/src/dart/constant/evaluation_test.dart

Issue 1816923002: Move constant implementation out of generated (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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) 2016, 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 library analyzer.test.constant_test;
6
7 import 'package:analyzer/context/declared_variables.dart';
8 import 'package:analyzer/dart/ast/ast.dart';
9 import 'package:analyzer/dart/ast/token.dart';
10 import 'package:analyzer/dart/element/element.dart';
11 import 'package:analyzer/src/dart/element/element.dart';
12 import 'package:analyzer/src/generated/constant.dart';
13 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/error.dart';
15 import 'package:analyzer/src/generated/resolver.dart';
16 import 'package:analyzer/src/generated/source.dart';
17 import 'package:analyzer/src/generated/source_io.dart';
18 import 'package:analyzer/src/generated/testing/ast_factory.dart';
19 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
20 import 'package:analyzer/src/task/dart.dart';
21 import 'package:path/path.dart';
22 import 'package:unittest/unittest.dart';
23
24 import '../../../generated/resolver_test_case.dart';
25 import '../../../generated/test_support.dart';
26 import '../../../reflective_tests.dart';
27 import '../../../utils.dart';
28
29 main() {
30 initializeTestEnvironment();
31 runReflectiveTests(ConstantValueComputerTest);
32 runReflectiveTests(ConstantVisitorTest);
33 }
34
35 /**
36 * Implementation of [ConstantEvaluationValidator] used during unit tests;
37 * verifies that any nodes referenced during constant evaluation are present in
38 * the dependency graph.
39 */
40 class ConstantEvaluationValidator_ForTest
41 implements ConstantEvaluationValidator {
42 final InternalAnalysisContext context;
43 ConstantValueComputer computer;
44 ConstantEvaluationTarget _nodeBeingEvaluated;
45
46 ConstantEvaluationValidator_ForTest(this.context);
47
48 @override
49 void beforeComputeValue(ConstantEvaluationTarget constant) {
50 _nodeBeingEvaluated = constant;
51 }
52
53 @override
54 void beforeGetConstantInitializers(ConstructorElement constructor) =>
55 _checkPathTo(constructor);
56
57 @override
58 void beforeGetEvaluationResult(ConstantEvaluationTarget constant) =>
59 _checkPathTo(constant);
60
61 @override
62 void beforeGetFieldEvaluationResult(FieldElementImpl field) =>
63 _checkPathTo(field);
64
65 @override
66 void beforeGetParameterDefault(ParameterElement parameter) =>
67 _checkPathTo(parameter);
68
69 void _checkPathTo(ConstantEvaluationTarget target) {
70 if (computer.referenceGraph.containsPath(_nodeBeingEvaluated, target)) {
71 return; // pass
72 }
73 // print a nice error message on failure
74 StringBuffer out = new StringBuffer();
75 out.writeln("missing path in constant dependency graph");
76 out.writeln("from $_nodeBeingEvaluated to $target");
77 for (var s in context.analysisCache.sources) {
78 String text = context.getContents(s).data;
79 if (text != "") {
80 out.writeln('''
81 === ${s.shortName}
82 $text''');
83 }
84 }
85 fail(out.toString());
86 }
87 }
88
89 @reflectiveTest
90 class ConstantValueComputerTest extends ResolverTestCase {
91 void test_annotation_constConstructor() {
92 CompilationUnit compilationUnit = resolveSource(r'''
93 class A {
94 final int i;
95 const A(this.i);
96 }
97
98 class C {
99 @A(5)
100 f() {}
101 }
102 ''');
103 EvaluationResultImpl result =
104 _evaluateAnnotation(compilationUnit, "C", "f");
105 Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
106 _assertIntField(annotationFields, 'i', 5);
107 }
108
109 void test_annotation_constConstructor_named() {
110 CompilationUnit compilationUnit = resolveSource(r'''
111 class A {
112 final int i;
113 const A.named(this.i);
114 }
115
116 class C {
117 @A.named(5)
118 f() {}
119 }
120 ''');
121 EvaluationResultImpl result =
122 _evaluateAnnotation(compilationUnit, "C", "f");
123 Map<String, DartObjectImpl> annotationFields = _assertType(result, 'A');
124 _assertIntField(annotationFields, 'i', 5);
125 }
126
127 void test_annotation_constConstructor_noArgs() {
128 // Failing to pass arguments to an annotation which is a constant
129 // constructor is illegal, but shouldn't crash analysis.
130 CompilationUnit compilationUnit = resolveSource(r'''
131 class A {
132 final int i;
133 const A(this.i);
134 }
135
136 class C {
137 @A
138 f() {}
139 }
140 ''');
141 _evaluateAnnotation(compilationUnit, "C", "f");
142 }
143
144 void test_annotation_constConstructor_noArgs_named() {
145 // Failing to pass arguments to an annotation which is a constant
146 // constructor is illegal, but shouldn't crash analysis.
147 CompilationUnit compilationUnit = resolveSource(r'''
148 class A {
149 final int i;
150 const A.named(this.i);
151 }
152
153 class C {
154 @A.named
155 f() {}
156 }
157 ''');
158 _evaluateAnnotation(compilationUnit, "C", "f");
159 }
160
161 void test_annotation_nonConstConstructor() {
162 // Calling a non-const constructor from an annotation that is illegal, but
163 // shouldn't crash analysis.
164 CompilationUnit compilationUnit = resolveSource(r'''
165 class A {
166 final int i;
167 A(this.i);
168 }
169
170 class C {
171 @A(5)
172 f() {}
173 }
174 ''');
175 _evaluateAnnotation(compilationUnit, "C", "f");
176 }
177
178 void test_annotation_staticConst() {
179 CompilationUnit compilationUnit = resolveSource(r'''
180 class C {
181 static const int i = 5;
182
183 @i
184 f() {}
185 }
186 ''');
187 EvaluationResultImpl result =
188 _evaluateAnnotation(compilationUnit, "C", "f");
189 expect(_assertValidInt(result), 5);
190 }
191
192 void test_annotation_staticConst_args() {
193 // Applying arguments to an annotation that is a static const is
194 // illegal, but shouldn't crash analysis.
195 CompilationUnit compilationUnit = resolveSource(r'''
196 class C {
197 static const int i = 5;
198
199 @i(1)
200 f() {}
201 }
202 ''');
203 _evaluateAnnotation(compilationUnit, "C", "f");
204 }
205
206 void test_annotation_staticConst_otherClass() {
207 CompilationUnit compilationUnit = resolveSource(r'''
208 class A {
209 static const int i = 5;
210 }
211
212 class C {
213 @A.i
214 f() {}
215 }
216 ''');
217 EvaluationResultImpl result =
218 _evaluateAnnotation(compilationUnit, "C", "f");
219 expect(_assertValidInt(result), 5);
220 }
221
222 void test_annotation_staticConst_otherClass_args() {
223 // Applying arguments to an annotation that is a static const is
224 // illegal, but shouldn't crash analysis.
225 CompilationUnit compilationUnit = resolveSource(r'''
226 class A {
227 static const int i = 5;
228 }
229
230 class C {
231 @A.i(1)
232 f() {}
233 }
234 ''');
235 _evaluateAnnotation(compilationUnit, "C", "f");
236 }
237
238 void test_annotation_topLevelVariable() {
239 CompilationUnit compilationUnit = resolveSource(r'''
240 const int i = 5;
241 class C {
242 @i
243 f() {}
244 }
245 ''');
246 EvaluationResultImpl result =
247 _evaluateAnnotation(compilationUnit, "C", "f");
248 expect(_assertValidInt(result), 5);
249 }
250
251 void test_annotation_topLevelVariable_args() {
252 // Applying arguments to an annotation that is a top-level variable is
253 // illegal, but shouldn't crash analysis.
254 CompilationUnit compilationUnit = resolveSource(r'''
255 const int i = 5;
256 class C {
257 @i(1)
258 f() {}
259 }
260 ''');
261 _evaluateAnnotation(compilationUnit, "C", "f");
262 }
263
264 void test_computeValues_cycle() {
265 TestLogger logger = new TestLogger();
266 AnalysisEngine.instance.logger = logger;
267 try {
268 Source source = addSource(r'''
269 const int a = c;
270 const int b = a;
271 const int c = b;''');
272 LibraryElement libraryElement = resolve2(source);
273 CompilationUnit unit =
274 analysisContext.resolveCompilationUnit(source, libraryElement);
275 analysisContext.computeErrors(source);
276 expect(unit, isNotNull);
277 ConstantValueComputer computer = _makeConstantValueComputer();
278 computer.add(unit, source, source);
279 computer.computeValues();
280 NodeList<CompilationUnitMember> members = unit.declarations;
281 expect(members, hasLength(3));
282 _validate(false, (members[0] as TopLevelVariableDeclaration).variables);
283 _validate(false, (members[1] as TopLevelVariableDeclaration).variables);
284 _validate(false, (members[2] as TopLevelVariableDeclaration).variables);
285 } finally {
286 AnalysisEngine.instance.logger = Logger.NULL;
287 }
288 }
289
290 void test_computeValues_dependentVariables() {
291 Source source = addSource(r'''
292 const int b = a;
293 const int a = 0;''');
294 LibraryElement libraryElement = resolve2(source);
295 CompilationUnit unit =
296 analysisContext.resolveCompilationUnit(source, libraryElement);
297 expect(unit, isNotNull);
298 ConstantValueComputer computer = _makeConstantValueComputer();
299 computer.add(unit, source, source);
300 computer.computeValues();
301 NodeList<CompilationUnitMember> members = unit.declarations;
302 expect(members, hasLength(2));
303 _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
304 _validate(true, (members[1] as TopLevelVariableDeclaration).variables);
305 }
306
307 void test_computeValues_empty() {
308 ConstantValueComputer computer = _makeConstantValueComputer();
309 computer.computeValues();
310 }
311
312 void test_computeValues_multipleSources() {
313 Source librarySource = addNamedSource(
314 "/lib.dart",
315 r'''
316 library lib;
317 part 'part.dart';
318 const int c = b;
319 const int a = 0;''');
320 Source partSource = addNamedSource(
321 "/part.dart",
322 r'''
323 part of lib;
324 const int b = a;
325 const int d = c;''');
326 LibraryElement libraryElement = resolve2(librarySource);
327 CompilationUnit libraryUnit =
328 analysisContext.resolveCompilationUnit(librarySource, libraryElement);
329 expect(libraryUnit, isNotNull);
330 CompilationUnit partUnit =
331 analysisContext.resolveCompilationUnit(partSource, libraryElement);
332 expect(partUnit, isNotNull);
333 ConstantValueComputer computer = _makeConstantValueComputer();
334 computer.add(libraryUnit, librarySource, librarySource);
335 computer.add(partUnit, partSource, librarySource);
336 computer.computeValues();
337 NodeList<CompilationUnitMember> libraryMembers = libraryUnit.declarations;
338 expect(libraryMembers, hasLength(2));
339 _validate(
340 true, (libraryMembers[0] as TopLevelVariableDeclaration).variables);
341 _validate(
342 true, (libraryMembers[1] as TopLevelVariableDeclaration).variables);
343 NodeList<CompilationUnitMember> partMembers = libraryUnit.declarations;
344 expect(partMembers, hasLength(2));
345 _validate(true, (partMembers[0] as TopLevelVariableDeclaration).variables);
346 _validate(true, (partMembers[1] as TopLevelVariableDeclaration).variables);
347 }
348
349 void test_computeValues_singleVariable() {
350 Source source = addSource("const int a = 0;");
351 LibraryElement libraryElement = resolve2(source);
352 CompilationUnit unit =
353 analysisContext.resolveCompilationUnit(source, libraryElement);
354 expect(unit, isNotNull);
355 ConstantValueComputer computer = _makeConstantValueComputer();
356 computer.add(unit, source, source);
357 computer.computeValues();
358 NodeList<CompilationUnitMember> members = unit.declarations;
359 expect(members, hasLength(1));
360 _validate(true, (members[0] as TopLevelVariableDeclaration).variables);
361 }
362
363 void test_computeValues_value_depends_on_enum() {
364 Source source = addSource('''
365 enum E { id0, id1 }
366 const E e = E.id0;
367 ''');
368 LibraryElement libraryElement = resolve2(source);
369 CompilationUnit unit =
370 analysisContext.resolveCompilationUnit(source, libraryElement);
371 expect(unit, isNotNull);
372 ConstantValueComputer computer = _makeConstantValueComputer();
373 computer.add(unit, source, source);
374 computer.computeValues();
375 TopLevelVariableDeclaration declaration = unit.declarations
376 .firstWhere((member) => member is TopLevelVariableDeclaration);
377 _validate(true, declaration.variables);
378 }
379
380 void test_dependencyOnConstructor() {
381 // x depends on "const A()"
382 _assertProperDependencies(r'''
383 class A {
384 const A();
385 }
386 const x = const A();''');
387 }
388
389 void test_dependencyOnConstructorArgument() {
390 // "const A(x)" depends on x
391 _assertProperDependencies(r'''
392 class A {
393 const A(this.next);
394 final A next;
395 }
396 const A x = const A(null);
397 const A y = const A(x);''');
398 }
399
400 void test_dependencyOnConstructorArgument_unresolvedConstructor() {
401 // "const A.a(x)" depends on x even if the constructor A.a can't be found.
402 _assertProperDependencies(
403 r'''
404 class A {
405 }
406 const int x = 1;
407 const A y = const A.a(x);''',
408 [CompileTimeErrorCode.CONST_WITH_UNDEFINED_CONSTRUCTOR]);
409 }
410
411 void test_dependencyOnConstructorInitializer() {
412 // "const A()" depends on x
413 _assertProperDependencies(r'''
414 const int x = 1;
415 class A {
416 const A() : v = x;
417 final int v;
418 }''');
419 }
420
421 void test_dependencyOnExplicitSuperConstructor() {
422 // b depends on B() depends on A()
423 _assertProperDependencies(r'''
424 class A {
425 const A(this.x);
426 final int x;
427 }
428 class B extends A {
429 const B() : super(5);
430 }
431 const B b = const B();''');
432 }
433
434 void test_dependencyOnExplicitSuperConstructorParameters() {
435 // b depends on B() depends on i
436 _assertProperDependencies(r'''
437 class A {
438 const A(this.x);
439 final int x;
440 }
441 class B extends A {
442 const B() : super(i);
443 }
444 const B b = const B();
445 const int i = 5;''');
446 }
447
448 void test_dependencyOnFactoryRedirect() {
449 // a depends on A.foo() depends on A.bar()
450 _assertProperDependencies(r'''
451 const A a = const A.foo();
452 class A {
453 factory const A.foo() = A.bar;
454 const A.bar();
455 }''');
456 }
457
458 void test_dependencyOnFactoryRedirectWithTypeParams() {
459 _assertProperDependencies(r'''
460 class A {
461 const factory A(var a) = B<int>;
462 }
463
464 class B<T> implements A {
465 final T x;
466 const B(this.x);
467 }
468
469 const A a = const A(10);''');
470 }
471
472 void test_dependencyOnImplicitSuperConstructor() {
473 // b depends on B() depends on A()
474 _assertProperDependencies(r'''
475 class A {
476 const A() : x = 5;
477 final int x;
478 }
479 class B extends A {
480 const B();
481 }
482 const B b = const B();''');
483 }
484
485 void test_dependencyOnInitializedFinal() {
486 // a depends on A() depends on A.x
487 _assertProperDependencies('''
488 class A {
489 const A();
490 final int x = 1;
491 }
492 const A a = const A();
493 ''');
494 }
495
496 void test_dependencyOnInitializedNonStaticConst() {
497 // Even though non-static consts are not allowed by the language, we need
498 // to handle them for error recovery purposes.
499 // a depends on A() depends on A.x
500 _assertProperDependencies(
501 '''
502 class A {
503 const A();
504 const int x = 1;
505 }
506 const A a = const A();
507 ''',
508 [CompileTimeErrorCode.CONST_INSTANCE_FIELD]);
509 }
510
511 void test_dependencyOnNonFactoryRedirect() {
512 // a depends on A.foo() depends on A.bar()
513 _assertProperDependencies(r'''
514 const A a = const A.foo();
515 class A {
516 const A.foo() : this.bar();
517 const A.bar();
518 }''');
519 }
520
521 void test_dependencyOnNonFactoryRedirect_arg() {
522 // a depends on A.foo() depends on b
523 _assertProperDependencies(r'''
524 const A a = const A.foo();
525 const int b = 1;
526 class A {
527 const A.foo() : this.bar(b);
528 const A.bar(x) : y = x;
529 final int y;
530 }''');
531 }
532
533 void test_dependencyOnNonFactoryRedirect_defaultValue() {
534 // a depends on A.foo() depends on A.bar() depends on b
535 _assertProperDependencies(r'''
536 const A a = const A.foo();
537 const int b = 1;
538 class A {
539 const A.foo() : this.bar();
540 const A.bar([x = b]) : y = x;
541 final int y;
542 }''');
543 }
544
545 void test_dependencyOnNonFactoryRedirect_toMissing() {
546 // a depends on A.foo() which depends on nothing, since A.bar() is
547 // missing.
548 _assertProperDependencies(
549 r'''
550 const A a = const A.foo();
551 class A {
552 const A.foo() : this.bar();
553 }''',
554 [CompileTimeErrorCode.REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR]);
555 }
556
557 void test_dependencyOnNonFactoryRedirect_toNonConst() {
558 // a depends on A.foo() which depends on nothing, since A.bar() is
559 // non-const.
560 _assertProperDependencies(r'''
561 const A a = const A.foo();
562 class A {
563 const A.foo() : this.bar();
564 A.bar();
565 }''');
566 }
567
568 void test_dependencyOnNonFactoryRedirect_unnamed() {
569 // a depends on A.foo() depends on A()
570 _assertProperDependencies(r'''
571 const A a = const A.foo();
572 class A {
573 const A.foo() : this();
574 const A();
575 }''');
576 }
577
578 void test_dependencyOnOptionalParameterDefault() {
579 // a depends on A() depends on B()
580 _assertProperDependencies(r'''
581 class A {
582 const A([x = const B()]) : b = x;
583 final B b;
584 }
585 class B {
586 const B();
587 }
588 const A a = const A();''');
589 }
590
591 void test_dependencyOnVariable() {
592 // x depends on y
593 _assertProperDependencies(r'''
594 const x = y + 1;
595 const y = 2;''');
596 }
597
598 void test_final_initialized_at_declaration() {
599 CompilationUnit compilationUnit = resolveSource('''
600 class A {
601 final int i = 123;
602 const A();
603 }
604
605 const A a = const A();
606 ''');
607 EvaluationResultImpl result =
608 _evaluateTopLevelVariable(compilationUnit, 'a');
609 Map<String, DartObjectImpl> fields = _assertType(result, "A");
610 expect(fields, hasLength(1));
611 _assertIntField(fields, "i", 123);
612 }
613
614 void test_fromEnvironment_bool_default_false() {
615 expect(_assertValidBool(_check_fromEnvironment_bool(null, "false")), false);
616 }
617
618 void test_fromEnvironment_bool_default_overridden() {
619 expect(
620 _assertValidBool(_check_fromEnvironment_bool("false", "true")), false);
621 }
622
623 void test_fromEnvironment_bool_default_parseError() {
624 expect(_assertValidBool(_check_fromEnvironment_bool("parseError", "true")),
625 true);
626 }
627
628 void test_fromEnvironment_bool_default_true() {
629 expect(_assertValidBool(_check_fromEnvironment_bool(null, "true")), true);
630 }
631
632 void test_fromEnvironment_bool_false() {
633 expect(_assertValidBool(_check_fromEnvironment_bool("false", null)), false);
634 }
635
636 void test_fromEnvironment_bool_parseError() {
637 expect(_assertValidBool(_check_fromEnvironment_bool("parseError", null)),
638 false);
639 }
640
641 void test_fromEnvironment_bool_true() {
642 expect(_assertValidBool(_check_fromEnvironment_bool("true", null)), true);
643 }
644
645 void test_fromEnvironment_bool_undeclared() {
646 _assertValidUnknown(_check_fromEnvironment_bool(null, null));
647 }
648
649 void test_fromEnvironment_int_default_overridden() {
650 expect(_assertValidInt(_check_fromEnvironment_int("234", "123")), 234);
651 }
652
653 void test_fromEnvironment_int_default_parseError() {
654 expect(
655 _assertValidInt(_check_fromEnvironment_int("parseError", "123")), 123);
656 }
657
658 void test_fromEnvironment_int_default_undeclared() {
659 expect(_assertValidInt(_check_fromEnvironment_int(null, "123")), 123);
660 }
661
662 void test_fromEnvironment_int_ok() {
663 expect(_assertValidInt(_check_fromEnvironment_int("234", null)), 234);
664 }
665
666 void test_fromEnvironment_int_parseError() {
667 _assertValidNull(_check_fromEnvironment_int("parseError", null));
668 }
669
670 void test_fromEnvironment_int_parseError_nullDefault() {
671 _assertValidNull(_check_fromEnvironment_int("parseError", "null"));
672 }
673
674 void test_fromEnvironment_int_undeclared() {
675 _assertValidUnknown(_check_fromEnvironment_int(null, null));
676 }
677
678 void test_fromEnvironment_int_undeclared_nullDefault() {
679 _assertValidNull(_check_fromEnvironment_int(null, "null"));
680 }
681
682 void test_fromEnvironment_string_default_overridden() {
683 expect(_assertValidString(_check_fromEnvironment_string("abc", "'def'")),
684 "abc");
685 }
686
687 void test_fromEnvironment_string_default_undeclared() {
688 expect(_assertValidString(_check_fromEnvironment_string(null, "'def'")),
689 "def");
690 }
691
692 void test_fromEnvironment_string_empty() {
693 expect(_assertValidString(_check_fromEnvironment_string("", null)), "");
694 }
695
696 void test_fromEnvironment_string_ok() {
697 expect(
698 _assertValidString(_check_fromEnvironment_string("abc", null)), "abc");
699 }
700
701 void test_fromEnvironment_string_undeclared() {
702 _assertValidUnknown(_check_fromEnvironment_string(null, null));
703 }
704
705 void test_fromEnvironment_string_undeclared_nullDefault() {
706 _assertValidNull(_check_fromEnvironment_string(null, "null"));
707 }
708
709 void test_instanceCreationExpression_computedField() {
710 CompilationUnit compilationUnit = resolveSource(r'''
711 const foo = const A(4, 5);
712 class A {
713 const A(int i, int j) : k = 2 * i + j;
714 final int k;
715 }''');
716 EvaluationResultImpl result =
717 _evaluateTopLevelVariable(compilationUnit, "foo");
718 Map<String, DartObjectImpl> fields = _assertType(result, "A");
719 expect(fields, hasLength(1));
720 _assertIntField(fields, "k", 13);
721 }
722
723 void
724 test_instanceCreationExpression_computedField_namedOptionalWithDefault() {
725 _checkInstanceCreationOptionalParams(false, true, true);
726 }
727
728 void
729 test_instanceCreationExpression_computedField_namedOptionalWithoutDefault( ) {
730 _checkInstanceCreationOptionalParams(false, true, false);
731 }
732
733 void
734 test_instanceCreationExpression_computedField_unnamedOptionalWithDefault() {
735 _checkInstanceCreationOptionalParams(false, false, true);
736 }
737
738 void
739 test_instanceCreationExpression_computedField_unnamedOptionalWithoutDefaul t() {
740 _checkInstanceCreationOptionalParams(false, false, false);
741 }
742
743 void test_instanceCreationExpression_computedField_usesConstConstructor() {
744 CompilationUnit compilationUnit = resolveSource(r'''
745 const foo = const A(3);
746 class A {
747 const A(int i) : b = const B(4);
748 final int b;
749 }
750 class B {
751 const B(this.k);
752 final int k;
753 }''');
754 EvaluationResultImpl result =
755 _evaluateTopLevelVariable(compilationUnit, "foo");
756 Map<String, DartObjectImpl> fieldsOfA = _assertType(result, "A");
757 expect(fieldsOfA, hasLength(1));
758 Map<String, DartObjectImpl> fieldsOfB =
759 _assertFieldType(fieldsOfA, "b", "B");
760 expect(fieldsOfB, hasLength(1));
761 _assertIntField(fieldsOfB, "k", 4);
762 }
763
764 void test_instanceCreationExpression_computedField_usesStaticConst() {
765 CompilationUnit compilationUnit = resolveSource(r'''
766 const foo = const A(3);
767 class A {
768 const A(int i) : k = i + B.bar;
769 final int k;
770 }
771 class B {
772 static const bar = 4;
773 }''');
774 EvaluationResultImpl result =
775 _evaluateTopLevelVariable(compilationUnit, "foo");
776 Map<String, DartObjectImpl> fields = _assertType(result, "A");
777 expect(fields, hasLength(1));
778 _assertIntField(fields, "k", 7);
779 }
780
781 void test_instanceCreationExpression_computedField_usesTopLevelConst() {
782 CompilationUnit compilationUnit = resolveSource(r'''
783 const foo = const A(3);
784 const bar = 4;
785 class A {
786 const A(int i) : k = i + bar;
787 final int k;
788 }''');
789 EvaluationResultImpl result =
790 _evaluateTopLevelVariable(compilationUnit, "foo");
791 Map<String, DartObjectImpl> fields = _assertType(result, "A");
792 expect(fields, hasLength(1));
793 _assertIntField(fields, "k", 7);
794 }
795
796 void test_instanceCreationExpression_explicitSuper() {
797 CompilationUnit compilationUnit = resolveSource(r'''
798 const foo = const B(4, 5);
799 class A {
800 const A(this.x);
801 final int x;
802 }
803 class B extends A {
804 const B(int x, this.y) : super(x * 2);
805 final int y;
806 }''');
807 EvaluationResultImpl result =
808 _evaluateTopLevelVariable(compilationUnit, "foo");
809 Map<String, DartObjectImpl> fields = _assertType(result, "B");
810 expect(fields, hasLength(2));
811 _assertIntField(fields, "y", 5);
812 Map<String, DartObjectImpl> superclassFields =
813 _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
814 expect(superclassFields, hasLength(1));
815 _assertIntField(superclassFields, "x", 8);
816 }
817
818 void test_instanceCreationExpression_fieldFormalParameter() {
819 CompilationUnit compilationUnit = resolveSource(r'''
820 const foo = const A(42);
821 class A {
822 int x;
823 const A(this.x)
824 }''');
825 EvaluationResultImpl result =
826 _evaluateTopLevelVariable(compilationUnit, "foo");
827 Map<String, DartObjectImpl> fields = _assertType(result, "A");
828 expect(fields, hasLength(1));
829 _assertIntField(fields, "x", 42);
830 }
831
832 void
833 test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithDefa ult() {
834 _checkInstanceCreationOptionalParams(true, true, true);
835 }
836
837 void
838 test_instanceCreationExpression_fieldFormalParameter_namedOptionalWithoutD efault() {
839 _checkInstanceCreationOptionalParams(true, true, false);
840 }
841
842 void
843 test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithDe fault() {
844 _checkInstanceCreationOptionalParams(true, false, true);
845 }
846
847 void
848 test_instanceCreationExpression_fieldFormalParameter_unnamedOptionalWithou tDefault() {
849 _checkInstanceCreationOptionalParams(true, false, false);
850 }
851
852 void test_instanceCreationExpression_implicitSuper() {
853 CompilationUnit compilationUnit = resolveSource(r'''
854 const foo = const B(4);
855 class A {
856 const A() : x = 3;
857 final int x;
858 }
859 class B extends A {
860 const B(this.y);
861 final int y;
862 }''');
863 EvaluationResultImpl result =
864 _evaluateTopLevelVariable(compilationUnit, "foo");
865 Map<String, DartObjectImpl> fields = _assertType(result, "B");
866 expect(fields, hasLength(2));
867 _assertIntField(fields, "y", 4);
868 Map<String, DartObjectImpl> superclassFields =
869 _assertFieldType(fields, GenericState.SUPERCLASS_FIELD, "A");
870 expect(superclassFields, hasLength(1));
871 _assertIntField(superclassFields, "x", 3);
872 }
873
874 void test_instanceCreationExpression_nonFactoryRedirect() {
875 CompilationUnit compilationUnit = resolveSource(r'''
876 const foo = const A.a1();
877 class A {
878 const A.a1() : this.a2();
879 const A.a2() : x = 5;
880 final int x;
881 }''');
882 Map<String, DartObjectImpl> aFields =
883 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
884 _assertIntField(aFields, 'x', 5);
885 }
886
887 void test_instanceCreationExpression_nonFactoryRedirect_arg() {
888 CompilationUnit compilationUnit = resolveSource(r'''
889 const foo = const A.a1(1);
890 class A {
891 const A.a1(x) : this.a2(x + 100);
892 const A.a2(x) : y = x + 10;
893 final int y;
894 }''');
895 Map<String, DartObjectImpl> aFields =
896 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
897 _assertIntField(aFields, 'y', 111);
898 }
899
900 void test_instanceCreationExpression_nonFactoryRedirect_cycle() {
901 // It is an error to have a cycle in non-factory redirects; however, we
902 // need to make sure that even if the error occurs, attempting to evaluate
903 // the constant will terminate.
904 CompilationUnit compilationUnit = resolveSource(r'''
905 const foo = const A();
906 class A {
907 const A() : this.b();
908 const A.b() : this();
909 }''');
910 _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
911 }
912
913 void test_instanceCreationExpression_nonFactoryRedirect_defaultArg() {
914 CompilationUnit compilationUnit = resolveSource(r'''
915 const foo = const A.a1();
916 class A {
917 const A.a1() : this.a2();
918 const A.a2([x = 100]) : y = x + 10;
919 final int y;
920 }''');
921 Map<String, DartObjectImpl> aFields =
922 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
923 _assertIntField(aFields, 'y', 110);
924 }
925
926 void test_instanceCreationExpression_nonFactoryRedirect_toMissing() {
927 CompilationUnit compilationUnit = resolveSource(r'''
928 const foo = const A.a1();
929 class A {
930 const A.a1() : this.a2();
931 }''');
932 // We don't care what value foo evaluates to (since there is a compile
933 // error), but we shouldn't crash, and we should figure
934 // out that it evaluates to an instance of class A.
935 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
936 }
937
938 void test_instanceCreationExpression_nonFactoryRedirect_toNonConst() {
939 CompilationUnit compilationUnit = resolveSource(r'''
940 const foo = const A.a1();
941 class A {
942 const A.a1() : this.a2();
943 A.a2();
944 }''');
945 // We don't care what value foo evaluates to (since there is a compile
946 // error), but we shouldn't crash, and we should figure
947 // out that it evaluates to an instance of class A.
948 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
949 }
950
951 void test_instanceCreationExpression_nonFactoryRedirect_unnamed() {
952 CompilationUnit compilationUnit = resolveSource(r'''
953 const foo = const A.a1();
954 class A {
955 const A.a1() : this();
956 const A() : x = 5;
957 final int x;
958 }''');
959 Map<String, DartObjectImpl> aFields =
960 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "A");
961 _assertIntField(aFields, 'x', 5);
962 }
963
964 void test_instanceCreationExpression_redirect() {
965 CompilationUnit compilationUnit = resolveSource(r'''
966 const foo = const A();
967 class A {
968 const factory A() = B;
969 }
970 class B implements A {
971 const B();
972 }''');
973 _assertType(_evaluateTopLevelVariable(compilationUnit, "foo"), "B");
974 }
975
976 void test_instanceCreationExpression_redirect_cycle() {
977 // It is an error to have a cycle in factory redirects; however, we need
978 // to make sure that even if the error occurs, attempting to evaluate the
979 // constant will terminate.
980 CompilationUnit compilationUnit = resolveSource(r'''
981 const foo = const A();
982 class A {
983 const factory A() = A.b;
984 const factory A.b() = A;
985 }''');
986 _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
987 }
988
989 void test_instanceCreationExpression_redirect_external() {
990 CompilationUnit compilationUnit = resolveSource(r'''
991 const foo = const A();
992 class A {
993 external const factory A();
994 }''');
995 _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
996 }
997
998 void test_instanceCreationExpression_redirect_nonConst() {
999 // It is an error for a const factory constructor redirect to a non-const
1000 // constructor; however, we need to make sure that even if the error
1001 // attempting to evaluate the constant won't cause a crash.
1002 CompilationUnit compilationUnit = resolveSource(r'''
1003 const foo = const A();
1004 class A {
1005 const factory A() = A.b;
1006 A.b();
1007 }''');
1008 _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
1009 }
1010
1011 void test_instanceCreationExpression_redirectWithTypeParams() {
1012 CompilationUnit compilationUnit = resolveSource(r'''
1013 class A {
1014 const factory A(var a) = B<int>;
1015 }
1016
1017 class B<T> implements A {
1018 final T x;
1019 const B(this.x);
1020 }
1021
1022 const A a = const A(10);''');
1023 EvaluationResultImpl result =
1024 _evaluateTopLevelVariable(compilationUnit, "a");
1025 Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
1026 expect(fields, hasLength(1));
1027 _assertIntField(fields, "x", 10);
1028 }
1029
1030 void test_instanceCreationExpression_redirectWithTypeSubstitution() {
1031 // To evaluate the redirection of A<int>,
1032 // A's template argument (T=int) must be substituted
1033 // into B's template argument (B<U> where U=T) to get B<int>.
1034 CompilationUnit compilationUnit = resolveSource(r'''
1035 class A<T> {
1036 const factory A(var a) = B<T>;
1037 }
1038
1039 class B<U> implements A {
1040 final U x;
1041 const B(this.x);
1042 }
1043
1044 const A<int> a = const A<int>(10);''');
1045 EvaluationResultImpl result =
1046 _evaluateTopLevelVariable(compilationUnit, "a");
1047 Map<String, DartObjectImpl> fields = _assertType(result, "B<int>");
1048 expect(fields, hasLength(1));
1049 _assertIntField(fields, "x", 10);
1050 }
1051
1052 void test_instanceCreationExpression_symbol() {
1053 CompilationUnit compilationUnit =
1054 resolveSource("const foo = const Symbol('a');");
1055 EvaluationResultImpl evaluationResult =
1056 _evaluateTopLevelVariable(compilationUnit, "foo");
1057 expect(evaluationResult.value, isNotNull);
1058 DartObjectImpl value = evaluationResult.value;
1059 expect(value.type, typeProvider.symbolType);
1060 expect(value.toSymbolValue(), "a");
1061 }
1062
1063 void test_instanceCreationExpression_withSupertypeParams_explicit() {
1064 _checkInstanceCreation_withSupertypeParams(true);
1065 }
1066
1067 void test_instanceCreationExpression_withSupertypeParams_implicit() {
1068 _checkInstanceCreation_withSupertypeParams(false);
1069 }
1070
1071 void test_instanceCreationExpression_withTypeParams() {
1072 CompilationUnit compilationUnit = resolveSource(r'''
1073 class C<E> {
1074 const C();
1075 }
1076 const c_int = const C<int>();
1077 const c_num = const C<num>();''');
1078 EvaluationResultImpl c_int =
1079 _evaluateTopLevelVariable(compilationUnit, "c_int");
1080 _assertType(c_int, "C<int>");
1081 DartObjectImpl c_int_value = c_int.value;
1082 EvaluationResultImpl c_num =
1083 _evaluateTopLevelVariable(compilationUnit, "c_num");
1084 _assertType(c_num, "C<num>");
1085 DartObjectImpl c_num_value = c_num.value;
1086 expect(c_int_value == c_num_value, isFalse);
1087 }
1088
1089 void test_isValidSymbol() {
1090 expect(ConstantEvaluationEngine.isValidPublicSymbol(""), isTrue);
1091 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo"), isTrue);
1092 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar"), isTrue);
1093 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$"), isTrue);
1094 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo\$bar"), isTrue);
1095 expect(ConstantEvaluationEngine.isValidPublicSymbol("iff"), isTrue);
1096 expect(ConstantEvaluationEngine.isValidPublicSymbol("gif"), isTrue);
1097 expect(ConstantEvaluationEngine.isValidPublicSymbol("if\$"), isTrue);
1098 expect(ConstantEvaluationEngine.isValidPublicSymbol("\$if"), isTrue);
1099 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo="), isTrue);
1100 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.bar="), isTrue);
1101 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.+"), isTrue);
1102 expect(ConstantEvaluationEngine.isValidPublicSymbol("void"), isTrue);
1103 expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo"), isFalse);
1104 expect(ConstantEvaluationEngine.isValidPublicSymbol("_foo.bar"), isFalse);
1105 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo._bar"), isFalse);
1106 expect(ConstantEvaluationEngine.isValidPublicSymbol("if"), isFalse);
1107 expect(ConstantEvaluationEngine.isValidPublicSymbol("if.foo"), isFalse);
1108 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.if"), isFalse);
1109 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo=.bar"), isFalse);
1110 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo."), isFalse);
1111 expect(ConstantEvaluationEngine.isValidPublicSymbol("+.foo"), isFalse);
1112 expect(ConstantEvaluationEngine.isValidPublicSymbol("void.foo"), isFalse);
1113 expect(ConstantEvaluationEngine.isValidPublicSymbol("foo.void"), isFalse);
1114 }
1115
1116 void test_length_of_improperly_typed_string_expression() {
1117 // Since type annotations are ignored in unchecked mode, the improper
1118 // types on s1 and s2 shouldn't prevent us from evaluating i to
1119 // 'alpha'.length.
1120 CompilationUnit compilationUnit = resolveSource('''
1121 const int s1 = 'alpha';
1122 const int s2 = 'beta';
1123 const int i = (true ? s1 : s2).length;
1124 ''');
1125 ConstTopLevelVariableElementImpl element =
1126 findTopLevelDeclaration(compilationUnit, 'i').element;
1127 EvaluationResultImpl result = element.evaluationResult;
1128 expect(_assertValidInt(result), 5);
1129 }
1130
1131 void test_length_of_improperly_typed_string_identifier() {
1132 // Since type annotations are ignored in unchecked mode, the improper type
1133 // on s shouldn't prevent us from evaluating i to 'alpha'.length.
1134 CompilationUnit compilationUnit = resolveSource('''
1135 const int s = 'alpha';
1136 const int i = s.length;
1137 ''');
1138 ConstTopLevelVariableElementImpl element =
1139 findTopLevelDeclaration(compilationUnit, 'i').element;
1140 EvaluationResultImpl result = element.evaluationResult;
1141 expect(_assertValidInt(result), 5);
1142 }
1143
1144 void test_non_static_const_initialized_at_declaration() {
1145 // Even though non-static consts are not allowed by the language, we need
1146 // to handle them for error recovery purposes.
1147 CompilationUnit compilationUnit = resolveSource('''
1148 class A {
1149 const int i = 123;
1150 const A();
1151 }
1152
1153 const A a = const A();
1154 ''');
1155 EvaluationResultImpl result =
1156 _evaluateTopLevelVariable(compilationUnit, 'a');
1157 Map<String, DartObjectImpl> fields = _assertType(result, "A");
1158 expect(fields, hasLength(1));
1159 _assertIntField(fields, "i", 123);
1160 }
1161
1162 void test_symbolLiteral_void() {
1163 CompilationUnit compilationUnit =
1164 resolveSource("const voidSymbol = #void;");
1165 VariableDeclaration voidSymbol =
1166 findTopLevelDeclaration(compilationUnit, "voidSymbol");
1167 EvaluationResultImpl voidSymbolResult =
1168 (voidSymbol.element as VariableElementImpl).evaluationResult;
1169 DartObjectImpl value = voidSymbolResult.value;
1170 expect(value.type, typeProvider.symbolType);
1171 expect(value.toSymbolValue(), "void");
1172 }
1173
1174 Map<String, DartObjectImpl> _assertFieldType(
1175 Map<String, DartObjectImpl> fields,
1176 String fieldName,
1177 String expectedType) {
1178 DartObjectImpl field = fields[fieldName];
1179 expect(field.type.displayName, expectedType);
1180 return field.fields;
1181 }
1182
1183 void _assertIntField(
1184 Map<String, DartObjectImpl> fields, String fieldName, int expectedValue) {
1185 DartObjectImpl field = fields[fieldName];
1186 expect(field.type.name, "int");
1187 expect(field.toIntValue(), expectedValue);
1188 }
1189
1190 void _assertNullField(Map<String, DartObjectImpl> fields, String fieldName) {
1191 DartObjectImpl field = fields[fieldName];
1192 expect(field.isNull, isTrue);
1193 }
1194
1195 void _assertProperDependencies(String sourceText,
1196 [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
1197 Source source = addSource(sourceText);
1198 LibraryElement element = resolve2(source);
1199 CompilationUnit unit =
1200 analysisContext.resolveCompilationUnit(source, element);
1201 expect(unit, isNotNull);
1202 ConstantValueComputer computer = _makeConstantValueComputer();
1203 computer.add(unit, source, source);
1204 computer.computeValues();
1205 assertErrors(source, expectedErrorCodes);
1206 }
1207
1208 Map<String, DartObjectImpl> _assertType(
1209 EvaluationResultImpl result, String typeName) {
1210 expect(result.value, isNotNull);
1211 DartObjectImpl value = result.value;
1212 expect(value.type.displayName, typeName);
1213 return value.fields;
1214 }
1215
1216 bool _assertValidBool(EvaluationResultImpl result) {
1217 expect(result.value, isNotNull);
1218 DartObjectImpl value = result.value;
1219 expect(value.type, typeProvider.boolType);
1220 bool boolValue = value.toBoolValue();
1221 expect(boolValue, isNotNull);
1222 return boolValue;
1223 }
1224
1225 int _assertValidInt(EvaluationResultImpl result) {
1226 expect(result, isNotNull);
1227 expect(result.value, isNotNull);
1228 DartObjectImpl value = result.value;
1229 expect(value.type, typeProvider.intType);
1230 return value.toIntValue();
1231 }
1232
1233 void _assertValidNull(EvaluationResultImpl result) {
1234 expect(result.value, isNotNull);
1235 DartObjectImpl value = result.value;
1236 expect(value.type, typeProvider.nullType);
1237 }
1238
1239 String _assertValidString(EvaluationResultImpl result) {
1240 expect(result.value, isNotNull);
1241 DartObjectImpl value = result.value;
1242 expect(value.type, typeProvider.stringType);
1243 return value.toStringValue();
1244 }
1245
1246 void _assertValidUnknown(EvaluationResultImpl result) {
1247 expect(result.value, isNotNull);
1248 DartObjectImpl value = result.value;
1249 expect(value.isUnknown, isTrue);
1250 }
1251
1252 EvaluationResultImpl _check_fromEnvironment_bool(
1253 String valueInEnvironment, String defaultExpr) {
1254 String envVarName = "x";
1255 String varName = "foo";
1256 if (valueInEnvironment != null) {
1257 analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
1258 }
1259 String defaultArg =
1260 defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
1261 CompilationUnit compilationUnit = resolveSource(
1262 "const $varName = const bool.fromEnvironment('$envVarName'$defaultArg);" );
1263 return _evaluateTopLevelVariable(compilationUnit, varName);
1264 }
1265
1266 EvaluationResultImpl _check_fromEnvironment_int(
1267 String valueInEnvironment, String defaultExpr) {
1268 String envVarName = "x";
1269 String varName = "foo";
1270 if (valueInEnvironment != null) {
1271 analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
1272 }
1273 String defaultArg =
1274 defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
1275 CompilationUnit compilationUnit = resolveSource(
1276 "const $varName = const int.fromEnvironment('$envVarName'$defaultArg);") ;
1277 return _evaluateTopLevelVariable(compilationUnit, varName);
1278 }
1279
1280 EvaluationResultImpl _check_fromEnvironment_string(
1281 String valueInEnvironment, String defaultExpr) {
1282 String envVarName = "x";
1283 String varName = "foo";
1284 if (valueInEnvironment != null) {
1285 analysisContext2.declaredVariables.define(envVarName, valueInEnvironment);
1286 }
1287 String defaultArg =
1288 defaultExpr == null ? "" : ", defaultValue: $defaultExpr";
1289 CompilationUnit compilationUnit = resolveSource(
1290 "const $varName = const String.fromEnvironment('$envVarName'$defaultArg) ;");
1291 return _evaluateTopLevelVariable(compilationUnit, varName);
1292 }
1293
1294 void _checkInstanceCreation_withSupertypeParams(bool isExplicit) {
1295 String superCall = isExplicit ? " : super()" : "";
1296 CompilationUnit compilationUnit = resolveSource("""
1297 class A<T> {
1298 const A();
1299 }
1300 class B<T, U> extends A<T> {
1301 const B()$superCall;
1302 }
1303 class C<T, U> extends A<U> {
1304 const C()$superCall;
1305 }
1306 const b_int_num = const B<int, num>();
1307 const c_int_num = const C<int, num>();""");
1308 EvaluationResultImpl b_int_num =
1309 _evaluateTopLevelVariable(compilationUnit, "b_int_num");
1310 Map<String, DartObjectImpl> b_int_num_fields =
1311 _assertType(b_int_num, "B<int, num>");
1312 _assertFieldType(b_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<int>");
1313 EvaluationResultImpl c_int_num =
1314 _evaluateTopLevelVariable(compilationUnit, "c_int_num");
1315 Map<String, DartObjectImpl> c_int_num_fields =
1316 _assertType(c_int_num, "C<int, num>");
1317 _assertFieldType(c_int_num_fields, GenericState.SUPERCLASS_FIELD, "A<num>");
1318 }
1319
1320 void _checkInstanceCreationOptionalParams(
1321 bool isFieldFormal, bool isNamed, bool hasDefault) {
1322 String fieldName = "j";
1323 String paramName = isFieldFormal ? fieldName : "i";
1324 String formalParam =
1325 "${isFieldFormal ? "this." : "int "}$paramName${hasDefault ? " = 3" : "" }";
1326 CompilationUnit compilationUnit = resolveSource("""
1327 const x = const A();
1328 const y = const A(${isNamed ? '$paramName: ' : ''}10);
1329 class A {
1330 const A(${isNamed ? "{$formalParam}" : "[$formalParam]"})${isFieldFormal ? "" : " : $fieldName = $paramName"};
1331 final int $fieldName;
1332 }""");
1333 EvaluationResultImpl x = _evaluateTopLevelVariable(compilationUnit, "x");
1334 Map<String, DartObjectImpl> fieldsOfX = _assertType(x, "A");
1335 expect(fieldsOfX, hasLength(1));
1336 if (hasDefault) {
1337 _assertIntField(fieldsOfX, fieldName, 3);
1338 } else {
1339 _assertNullField(fieldsOfX, fieldName);
1340 }
1341 EvaluationResultImpl y = _evaluateTopLevelVariable(compilationUnit, "y");
1342 Map<String, DartObjectImpl> fieldsOfY = _assertType(y, "A");
1343 expect(fieldsOfY, hasLength(1));
1344 _assertIntField(fieldsOfY, fieldName, 10);
1345 }
1346
1347 /**
1348 * Search [compilationUnit] for a class named [className], containing a
1349 * method [methodName], with exactly one annotation. Return the constant
1350 * value of the annotation.
1351 */
1352 EvaluationResultImpl _evaluateAnnotation(
1353 CompilationUnit compilationUnit, String className, String memberName) {
1354 for (CompilationUnitMember member in compilationUnit.declarations) {
1355 if (member is ClassDeclaration && member.name.name == className) {
1356 for (ClassMember classMember in member.members) {
1357 if (classMember is MethodDeclaration &&
1358 classMember.name.name == memberName) {
1359 expect(classMember.metadata, hasLength(1));
1360 ElementAnnotationImpl elementAnnotation =
1361 classMember.metadata[0].elementAnnotation;
1362 return elementAnnotation.evaluationResult;
1363 }
1364 }
1365 }
1366 }
1367 fail('Class member not found');
1368 return null;
1369 }
1370
1371 EvaluationResultImpl _evaluateTopLevelVariable(
1372 CompilationUnit compilationUnit, String name) {
1373 VariableDeclaration varDecl =
1374 findTopLevelDeclaration(compilationUnit, name);
1375 ConstTopLevelVariableElementImpl varElement = varDecl.element;
1376 return varElement.evaluationResult;
1377 }
1378
1379 ConstantValueComputer _makeConstantValueComputer() {
1380 ConstantEvaluationValidator_ForTest validator =
1381 new ConstantEvaluationValidator_ForTest(analysisContext2);
1382 validator.computer = new ConstantValueComputer(
1383 analysisContext2,
1384 analysisContext2.typeProvider,
1385 analysisContext2.declaredVariables,
1386 validator,
1387 analysisContext2.typeSystem);
1388 return validator.computer;
1389 }
1390
1391 void _validate(bool shouldBeValid, VariableDeclarationList declarationList) {
1392 for (VariableDeclaration declaration in declarationList.variables) {
1393 VariableElementImpl element = declaration.element as VariableElementImpl;
1394 expect(element, isNotNull);
1395 EvaluationResultImpl result = element.evaluationResult;
1396 if (shouldBeValid) {
1397 expect(result.value, isNotNull);
1398 } else {
1399 expect(result.value, isNull);
1400 }
1401 }
1402 }
1403 }
1404
1405 @reflectiveTest
1406 class ConstantVisitorTest extends ResolverTestCase {
1407 void test_visitBinaryExpression_questionQuestion_notNull_notNull() {
1408 Expression left = AstFactory.string2('a');
1409 Expression right = AstFactory.string2('b');
1410 Expression expression =
1411 AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
1412
1413 GatheringErrorListener errorListener = new GatheringErrorListener();
1414 ErrorReporter errorReporter =
1415 new ErrorReporter(errorListener, _dummySource());
1416 DartObjectImpl result = _evaluate(expression, errorReporter);
1417 expect(result, isNotNull);
1418 expect(result.isNull, isFalse);
1419 expect(result.toStringValue(), 'a');
1420 errorListener.assertNoErrors();
1421 }
1422
1423 void test_visitBinaryExpression_questionQuestion_null_notNull() {
1424 Expression left = AstFactory.nullLiteral();
1425 Expression right = AstFactory.string2('b');
1426 Expression expression =
1427 AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
1428
1429 GatheringErrorListener errorListener = new GatheringErrorListener();
1430 ErrorReporter errorReporter =
1431 new ErrorReporter(errorListener, _dummySource());
1432 DartObjectImpl result = _evaluate(expression, errorReporter);
1433 expect(result, isNotNull);
1434 expect(result.isNull, isFalse);
1435 expect(result.toStringValue(), 'b');
1436 errorListener.assertNoErrors();
1437 }
1438
1439 void test_visitBinaryExpression_questionQuestion_null_null() {
1440 Expression left = AstFactory.nullLiteral();
1441 Expression right = AstFactory.nullLiteral();
1442 Expression expression =
1443 AstFactory.binaryExpression(left, TokenType.QUESTION_QUESTION, right);
1444
1445 GatheringErrorListener errorListener = new GatheringErrorListener();
1446 ErrorReporter errorReporter =
1447 new ErrorReporter(errorListener, _dummySource());
1448 DartObjectImpl result = _evaluate(expression, errorReporter);
1449 expect(result, isNotNull);
1450 expect(result.isNull, isTrue);
1451 errorListener.assertNoErrors();
1452 }
1453
1454 void test_visitConditionalExpression_false() {
1455 Expression thenExpression = AstFactory.integer(1);
1456 Expression elseExpression = AstFactory.integer(0);
1457 ConditionalExpression expression = AstFactory.conditionalExpression(
1458 AstFactory.booleanLiteral(false), thenExpression, elseExpression);
1459 GatheringErrorListener errorListener = new GatheringErrorListener();
1460 ErrorReporter errorReporter =
1461 new ErrorReporter(errorListener, _dummySource());
1462 _assertValue(0, _evaluate(expression, errorReporter));
1463 errorListener.assertNoErrors();
1464 }
1465
1466 void test_visitConditionalExpression_nonBooleanCondition() {
1467 Expression thenExpression = AstFactory.integer(1);
1468 Expression elseExpression = AstFactory.integer(0);
1469 NullLiteral conditionExpression = AstFactory.nullLiteral();
1470 ConditionalExpression expression = AstFactory.conditionalExpression(
1471 conditionExpression, thenExpression, elseExpression);
1472 GatheringErrorListener errorListener = new GatheringErrorListener();
1473 ErrorReporter errorReporter =
1474 new ErrorReporter(errorListener, _dummySource());
1475 DartObjectImpl result = _evaluate(expression, errorReporter);
1476 expect(result, isNull);
1477 errorListener
1478 .assertErrorsWithCodes([CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL]);
1479 }
1480
1481 void test_visitConditionalExpression_nonConstantElse() {
1482 Expression thenExpression = AstFactory.integer(1);
1483 Expression elseExpression = AstFactory.identifier3("x");
1484 ConditionalExpression expression = AstFactory.conditionalExpression(
1485 AstFactory.booleanLiteral(true), thenExpression, elseExpression);
1486 GatheringErrorListener errorListener = new GatheringErrorListener();
1487 ErrorReporter errorReporter =
1488 new ErrorReporter(errorListener, _dummySource());
1489 DartObjectImpl result = _evaluate(expression, errorReporter);
1490 expect(result, isNull);
1491 errorListener
1492 .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
1493 }
1494
1495 void test_visitConditionalExpression_nonConstantThen() {
1496 Expression thenExpression = AstFactory.identifier3("x");
1497 Expression elseExpression = AstFactory.integer(0);
1498 ConditionalExpression expression = AstFactory.conditionalExpression(
1499 AstFactory.booleanLiteral(true), thenExpression, elseExpression);
1500 GatheringErrorListener errorListener = new GatheringErrorListener();
1501 ErrorReporter errorReporter =
1502 new ErrorReporter(errorListener, _dummySource());
1503 DartObjectImpl result = _evaluate(expression, errorReporter);
1504 expect(result, isNull);
1505 errorListener
1506 .assertErrorsWithCodes([CompileTimeErrorCode.INVALID_CONSTANT]);
1507 }
1508
1509 void test_visitConditionalExpression_true() {
1510 Expression thenExpression = AstFactory.integer(1);
1511 Expression elseExpression = AstFactory.integer(0);
1512 ConditionalExpression expression = AstFactory.conditionalExpression(
1513 AstFactory.booleanLiteral(true), thenExpression, elseExpression);
1514 GatheringErrorListener errorListener = new GatheringErrorListener();
1515 ErrorReporter errorReporter =
1516 new ErrorReporter(errorListener, _dummySource());
1517 _assertValue(1, _evaluate(expression, errorReporter));
1518 errorListener.assertNoErrors();
1519 }
1520
1521 void test_visitSimpleIdentifier_className() {
1522 CompilationUnit compilationUnit = resolveSource('''
1523 const a = C;
1524 class C {}
1525 ''');
1526 DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
1527 expect(result.type, typeProvider.typeType);
1528 expect(result.toTypeValue().name, 'C');
1529 }
1530
1531 void test_visitSimpleIdentifier_dynamic() {
1532 CompilationUnit compilationUnit = resolveSource('''
1533 const a = dynamic;
1534 ''');
1535 DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
1536 expect(result.type, typeProvider.typeType);
1537 expect(result.toTypeValue(), typeProvider.dynamicType);
1538 }
1539
1540 void test_visitSimpleIdentifier_inEnvironment() {
1541 CompilationUnit compilationUnit = resolveSource(r'''
1542 const a = b;
1543 const b = 3;''');
1544 Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
1545 DartObjectImpl six =
1546 new DartObjectImpl(typeProvider.intType, new IntState(6));
1547 environment["b"] = six;
1548 _assertValue(6, _evaluateConstant(compilationUnit, "a", environment));
1549 }
1550
1551 void test_visitSimpleIdentifier_notInEnvironment() {
1552 CompilationUnit compilationUnit = resolveSource(r'''
1553 const a = b;
1554 const b = 3;''');
1555 Map<String, DartObjectImpl> environment = new Map<String, DartObjectImpl>();
1556 DartObjectImpl six =
1557 new DartObjectImpl(typeProvider.intType, new IntState(6));
1558 environment["c"] = six;
1559 _assertValue(3, _evaluateConstant(compilationUnit, "a", environment));
1560 }
1561
1562 void test_visitSimpleIdentifier_withoutEnvironment() {
1563 CompilationUnit compilationUnit = resolveSource(r'''
1564 const a = b;
1565 const b = 3;''');
1566 _assertValue(3, _evaluateConstant(compilationUnit, "a", null));
1567 }
1568
1569 void _assertValue(int expectedValue, DartObjectImpl result) {
1570 expect(result, isNotNull);
1571 expect(result.type.name, "int");
1572 expect(result.toIntValue(), expectedValue);
1573 }
1574
1575 NonExistingSource _dummySource() {
1576 String path = '/test.dart';
1577 return new NonExistingSource(path, toUri(path), UriKind.FILE_URI);
1578 }
1579
1580 DartObjectImpl _evaluate(Expression expression, ErrorReporter errorReporter) {
1581 return expression.accept(new ConstantVisitor(
1582 new ConstantEvaluationEngine(
1583 new TestTypeProvider(), new DeclaredVariables(),
1584 typeSystem: new TypeSystemImpl()),
1585 errorReporter));
1586 }
1587
1588 DartObjectImpl _evaluateConstant(CompilationUnit compilationUnit, String name,
1589 Map<String, DartObjectImpl> lexicalEnvironment) {
1590 Source source = compilationUnit.element.source;
1591 Expression expression =
1592 findTopLevelConstantExpression(compilationUnit, name);
1593 GatheringErrorListener errorListener = new GatheringErrorListener();
1594 ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
1595 DartObjectImpl result = expression.accept(new ConstantVisitor(
1596 new ConstantEvaluationEngine(typeProvider, new DeclaredVariables(),
1597 typeSystem: typeSystem),
1598 errorReporter,
1599 lexicalEnvironment: lexicalEnvironment));
1600 errorListener.assertNoErrors();
1601 return result;
1602 }
1603 }
OLDNEW
« no previous file with comments | « pkg/analyzer/test/generated/constant_test.dart ('k') | pkg/analyzer/test/src/dart/constant/test_all.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698