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

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

Powered by Google App Engine
This is Rietveld 408576698