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

Side by Side Diff: pkg/analyzer/test/generated/strong_mode_test.dart

Issue 2954523002: fix #27259, implement covariance checking for strong mode and DDC (Closed)
Patch Set: merged and fix an analysis error Created 3 years, 5 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
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.test.generated.strong_mode_test; 5 library analyzer.test.generated.strong_mode_test;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analyzer/dart/ast/ast.dart'; 9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/ast/standard_resolution_map.dart'; 10 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
11 import 'package:analyzer/dart/element/element.dart'; 11 import 'package:analyzer/dart/element/element.dart';
12 import 'package:analyzer/dart/element/type.dart'; 12 import 'package:analyzer/dart/element/type.dart';
13 import 'package:analyzer/src/dart/element/element.dart'; 13 import 'package:analyzer/src/dart/element/element.dart';
14 import 'package:analyzer/src/error/codes.dart'; 14 import 'package:analyzer/src/error/codes.dart';
15 import 'package:analyzer/src/generated/engine.dart'; 15 import 'package:analyzer/src/generated/engine.dart';
16 import 'package:analyzer/src/generated/source_io.dart'; 16 import 'package:analyzer/src/generated/source_io.dart';
17 import 'package:analyzer/src/task/strong/ast_properties.dart';
17 import 'package:front_end/src/base/errors.dart'; 18 import 'package:front_end/src/base/errors.dart';
18 import 'package:test/test.dart'; 19 import 'package:test/test.dart';
19 import 'package:test_reflective_loader/test_reflective_loader.dart'; 20 import 'package:test_reflective_loader/test_reflective_loader.dart';
20 21
21 import '../utils.dart'; 22 import '../utils.dart';
22 import 'resolver_test_case.dart'; 23 import 'resolver_test_case.dart';
23 24
24 main() { 25 main() {
25 defineReflectiveSuite(() { 26 defineReflectiveSuite(() {
26 defineReflectiveTests(StrongModeLocalInferenceTest); 27 defineReflectiveTests(StrongModeLocalInferenceTest);
(...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 } 414 }
414 '''; 415 ''';
415 CompilationUnit unit = await resolveSource(code); 416 CompilationUnit unit = await resolveSource(code);
416 ConstructorDeclaration constructor = 417 ConstructorDeclaration constructor =
417 AstFinder.getConstructorInClass(unit, "A", null); 418 AstFinder.getConstructorInClass(unit, "A", null);
418 ConstructorFieldInitializer assignment = constructor.initializers[0]; 419 ConstructorFieldInitializer assignment = constructor.initializers[0];
419 Expression exp = assignment.expression; 420 Expression exp = assignment.expression;
420 _isListOf(_isString)(exp.staticType); 421 _isListOf(_isString)(exp.staticType);
421 } 422 }
422 423
424 test_covarianceChecks() async {
425 var source = addSource(r'''
426 class C<T> {
427 add(T t) {}
428 forEach(void f(T t)) {}
429 }
430 class D extends C<int> {
431 add(int t) {}
432 forEach(void f(int t)) {}
433 }
434 class E extends C<int> {
435 add(Object t) {}
436 forEach(void f(Null t)) {}
437 }
438 ''');
439 var unit = (await computeAnalysisResult(source)).unit;
440 assertNoErrors(source);
441 var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
442 var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
443 expect(covariantC.toList(), [cAdd.element.parameters[0]]);
444
445 var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
446 var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
447 expect(covariantD.toList(), [dAdd.element.parameters[0]]);
448
449 var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
450 expect(covariantE.toList(), []);
451 }
452
453 test_covarianceChecks_genericMethods() async {
454 var source = addSource(r'''
455 class C<T> {
456 add<S>(T t) {}
457 forEach<S>(S f(T t)) {}
458 }
459 class D extends C<int> {
460 add<S>(int t) {}
461 forEach<S>(S f(int t)) {}
462 }
463 class E extends C<int> {
464 add<S>(Object t) {}
465 forEach<S>(S f(Null t)) {}
466 }
467 ''');
468 var unit = (await computeAnalysisResult(source)).unit;
469 assertNoErrors(source);
470
471 var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
472 var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
473 expect(covariantC.toList(), [cAdd.element.parameters[0]]);
474
475 var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
476 var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
477 expect(covariantD.toList(), [dAdd.element.parameters[0]]);
478
479 var covariantE = getClassCovariantParameters(AstFinder.getClass(unit, "E"));
480 expect(covariantE.toList(), []);
481 }
482
483 test_covarianceChecks_superclass() async {
484 var source = addSource(r'''
485 class C<T> {
486 add(T t) {}
487 forEach(void f(T t)) {}
488 }
489 class D {
490 add(int t) {}
491 forEach(void f(int t)) {}
492 }
493 class E extends D implements C<int> {}
494 ''');
495 var unit = (await computeAnalysisResult(source)).unit;
496 assertNoErrors(source);
497 var cAdd = AstFinder.getMethodInClass(unit, "C", "add");
498 var covariantC = getClassCovariantParameters(AstFinder.getClass(unit, "C"));
499 expect(covariantC.toList(), [cAdd.element.parameters[0]]);
500
501 var dAdd = AstFinder.getMethodInClass(unit, "D", "add");
502 var covariantD = getClassCovariantParameters(AstFinder.getClass(unit, "D"));
503 expect(covariantD, null);
504
505 var classE = AstFinder.getClass(unit, "E");
506 var covariantE = getClassCovariantParameters(classE);
507 var superCovariantE = getSuperclassCovariantParameters(classE);
508 expect(covariantE.toList(), []);
509 expect(superCovariantE.toList(), [dAdd.element.parameters[0]]);
510 }
511
512 @soloTest
513 test_covarianceChecks_returnFunction() async {
514 var source = addSource(r'''
515 typedef F<T>(T t);
516 typedef T R<T>();
517 class C<T> {
518 F<T> f;
519
520 C();
521 factory C.fact() => new C<Null>();
522
523 F<T> get g => null;
524 F<T> m1() => null;
525 R<F<T>> m2() => null;
526
527 casts(C<T> other, T t) {
528 other.f;
529 other.g(t);
530 other.m1();
531 other.m2;
532
533 new C<T>.fact().f(t);
534 new C<int>.fact().g;
535 new C<int>.fact().m1;
536 new C<T>.fact().m2();
537
538 new C<Object>.fact().f(42);
539 new C<Object>.fact().g;
540 new C<Object>.fact().m1;
541 new C<Object>.fact().m2();
542 }
543
544 noCasts(T t) {
545 f;
546 g;
547 m1();
548 m2();
549
550 f(t);
551 g(t);
552 (f)(t);
553 (g)(t);
554 m1;
555 m2;
556
557 this.f;
558 this.g;
559 this.m1();
560 this.m2();
561 this.m1;
562 this.m2;
563 (this.m1)();
564 (this.m2)();
565 this.f(t);
566 this.g(t);
567 (this.f)(t);
568 (this.g)(t);
569
570 new C<int>().f;
571 new C<T>().g;
572 new C<int>().m1();
573 new C().m2();
574
575 new D().f;
576 new D().g;
577 new D().m1();
578 new D().m2();
579
580 // fuzzy arrows are currently checked at the call, they skip this cast.
581 new C.fact().f(42);
582 new C.fact().g;
583 new C.fact().m1;
584 new C.fact().m2();
585 }
586 }
587 class D extends C<num> {
588 noCasts(t) {
589 f;
590 this.g;
591 this.m1();
592 m2;
593
594 super.f;
595 super.g;
596 super.m1;
597 super.m2();
598 }
599 }
600
601 D d;
602 C<Object> c;
603 C cD;
604 C<Null> cN;
605 F<Object> f;
606 F<Null> fN;
607 R<F<Object>> rf;
608 R<F<Null>> rfN;
609 R<R<F<Object>>> rrf;
610 R<R<F<Null>>> rrfN;
611 Object obj;
612 F<int> fi;
613 R<F<int>> rfi;
614 R<R<F<int>>> rrfi;
615
616 casts() {
617 c.f;
618 c.g;
619 c.m1;
620 c.m1();
621 c.m2();
622
623 fN = c.f;
624 fN = c.g;
625 rfN = c.m1;
626 rrfN = c.m2;
627 fN = c.m1();
628 rfN = c.m2();
629
630 f = c.f;
631 f = c.g;
632 rf = c.m1;
633 rrf = c.m2;
634 f = c.m1();
635 rf = c.m2();
636 c.m2()();
637
638 c.f(obj);
639 c.g(obj);
640 (c.f)(obj);
641 (c.g)(obj);
642 (c.m1)();
643 c.m1()(obj);
644 (c.m2)();
645 }
646
647 noCasts() {
648 fi = d.f;
649 fi = d.g;
650 rfi = d.m1;
651 fi = d.m1();
652 rrfi = d.m2;
653 rfi = d.m2();
654 d.f(42);
655 d.g(42);
656 (d.f)(42);
657 (d.g)(42);
658 d.m1()(42);
659 d.m2()()(42);
660
661 cN.f;
662 cN.g;
663 cN.m1;
664 cN.m1();
665 cN.m2();
666
667 // fuzzy arrows are currently checked at the call, they skip this cast.
668 cD.f;
669 cD.g;
670 cD.m1;
671 cD.m1();
672 cD.m2();
673 }
674 ''');
675 var unit = (await computeAnalysisResult(source)).unit;
676 assertNoErrors(source);
677
678 void expectCast(Statement statement, bool hasCast) {
679 var value = (statement as ExpressionStatement).expression;
680 if (value is AssignmentExpression) {
681 value = (value as AssignmentExpression).rightHandSide;
682 }
683 while (value is FunctionExpressionInvocation) {
684 value = (value as FunctionExpressionInvocation).function;
685 }
686 while (value is ParenthesizedExpression) {
687 value = (value as ParenthesizedExpression).expression;
688 }
689 var isCallingGetter =
690 value is MethodInvocation && !value.methodName.name.startsWith('m');
691 var cast = isCallingGetter
692 ? getImplicitOperationCast(value)
693 : getImplicitCast(value);
694 var castKind = isCallingGetter ? 'special cast' : 'cast';
695 expect(cast, hasCast ? isNotNull : isNull,
696 reason: '`$statement` should ' +
697 (hasCast ? '' : 'not ') +
698 'have a $castKind on `$value`.');
699 }
700
701 for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'noCasts')) {
702 expectCast(s, false);
703 }
704 for (var s in AstFinder.getStatementsInMethod(unit, 'C', 'casts')) {
705 expectCast(s, true);
706 }
707 for (var s in AstFinder.getStatementsInMethod(unit, 'D', 'noCasts')) {
708 expectCast(s, false);
709 }
710 for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'noCasts')) {
711 expectCast(s, false);
712 }
713 for (var s in AstFinder.getStatementsInTopLevelFunction(unit, 'casts')) {
714 expectCast(s, true);
715 }
716 }
717
423 test_factoryConstructor_propagation() async { 718 test_factoryConstructor_propagation() async {
424 String code = r''' 719 String code = r'''
425 class A<T> { 720 class A<T> {
426 factory A() { return new B(); } 721 factory A() { return new B(); }
427 } 722 }
428 class B<S> extends A<S> {} 723 class B<S> extends A<S> {}
429 '''; 724 ''';
430 CompilationUnit unit = await resolveSource(code); 725 CompilationUnit unit = await resolveSource(code);
431 726
432 ConstructorDeclaration constructor = 727 ConstructorDeclaration constructor =
(...skipping 3486 matching lines...) Expand 10 before | Expand all | Expand 10 after
3919 var v = x; 4214 var v = x;
3920 v; // marker 4215 v; // marker
3921 } 4216 }
3922 int x = 3; 4217 int x = 3;
3923 '''; 4218 ''';
3924 CompilationUnit unit = await resolveSource(code); 4219 CompilationUnit unit = await resolveSource(code);
3925 assertPropagatedAssignedType(code, unit, typeProvider.intType, null); 4220 assertPropagatedAssignedType(code, unit, typeProvider.intType, null);
3926 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null); 4221 assertTypeOfMarkedExpression(code, unit, typeProvider.intType, null);
3927 } 4222 }
3928 } 4223 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/task/strong/checker.dart ('k') | pkg/dev_compiler/lib/js/legacy/dart_library.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698