Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 import 'package:kernel/ast.dart'; | 5 import 'package:kernel/ast.dart'; |
| 6 import 'package:kernel/class_hierarchy.dart'; | 6 import 'package:kernel/class_hierarchy.dart'; |
| 7 import 'package:kernel/core_types.dart'; | 7 import 'package:kernel/core_types.dart'; |
| 8 import 'package:kernel/testing/mock_sdk_program.dart'; | 8 import 'package:kernel/testing/mock_sdk_program.dart'; |
| 9 import 'package:kernel/text/ast_to_text.dart'; | 9 import 'package:kernel/text/ast_to_text.dart'; |
| 10 import 'package:test/test.dart'; | 10 import 'package:test/test.dart'; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 82 } | 82 } |
| 83 | 83 |
| 84 ClassHierarchy createClassHierarchy(Program program); | 84 ClassHierarchy createClassHierarchy(Program program); |
| 85 | 85 |
| 86 Procedure newEmptyMethod(String name, {bool abstract: false}) { | 86 Procedure newEmptyMethod(String name, {bool abstract: false}) { |
| 87 var body = abstract ? null : new Block([]); | 87 var body = abstract ? null : new Block([]); |
| 88 return new Procedure(new Name(name), ProcedureKind.Method, | 88 return new Procedure(new Name(name), ProcedureKind.Method, |
| 89 new FunctionNode(body, returnType: const VoidType())); | 89 new FunctionNode(body, returnType: const VoidType())); |
| 90 } | 90 } |
| 91 | 91 |
| 92 Procedure newEmptySetter(String name) { | 92 Procedure newEmptySetter(String name, {bool abstract: false}) { |
| 93 var body = abstract ? null : new Block([]); | |
| 93 return new Procedure( | 94 return new Procedure( |
| 94 new Name(name), | 95 new Name(name), |
| 95 ProcedureKind.Setter, | 96 ProcedureKind.Setter, |
| 96 new FunctionNode(new Block([]), | 97 new FunctionNode(body, |
| 97 returnType: const VoidType(), | 98 returnType: const VoidType(), |
| 98 positionalParameters: [new VariableDeclaration('_')])); | 99 positionalParameters: [new VariableDeclaration('_')])); |
| 99 } | 100 } |
| 100 | 101 |
| 101 void setUp() { | 102 void setUp() { |
| 102 // Start with mock SDK libraries. | 103 // Start with mock SDK libraries. |
| 103 program = createMockSdkProgram(); | 104 program = createMockSdkProgram(); |
| 104 coreTypes = new CoreTypes(program); | 105 coreTypes = new CoreTypes(program); |
| 105 | 106 |
| 106 // Add the test library. | 107 // Add the test library. |
| 107 library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test'); | 108 library = new Library(Uri.parse('org-dartlang:///test.dart'), name: 'test'); |
| 108 library.parent = program; | 109 library.parent = program; |
| 109 program.libraries.add(library); | 110 program.libraries.add(library); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void test_forEachOverridePair_overrideSupertype() { | 113 /// 2. A non-abstract member is inherited from a superclass, and in the |
| 113 var aFoo = newEmptyMethod('foo'); | 114 /// context of this class, it overrides an abstract member inheritable through |
| 114 var aBar = newEmptyMethod('bar'); | 115 /// one of its superinterfaces. |
| 115 var bFoo = newEmptyMethod('foo'); | 116 void test_forEachOverridePair_supertypeOverridesInterface() { |
| 116 var cBar = newEmptyMethod('bar'); | 117 var a = addClass(new Class( |
| 117 var a = addClass( | 118 name: 'A', |
| 118 new Class(name: 'A', supertype: objectSuper, procedures: [aFoo, aBar])); | 119 supertype: objectSuper, |
| 119 var b = addClass( | 120 procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')])); |
| 120 new Class(name: 'B', supertype: a.asThisSupertype, procedures: [bFoo])); | 121 var b = addClass(new Class( |
| 121 var c = addClass( | 122 name: 'B', |
| 122 new Class(name: 'C', supertype: b.asThisSupertype, procedures: [cBar])); | 123 supertype: a.asThisSupertype, |
| 124 procedures: [newEmptyMethod('foo', abstract: true)])); | |
| 125 var c = addClass(new Class( | |
| 126 name: 'C', | |
| 127 supertype: a.asThisSupertype, | |
| 128 implementedTypes: [b.asThisSupertype])); | |
| 129 var d = addClass(new Class(name: 'D', supertype: objectSuper)); | |
| 130 var e = addClass(new Class( | |
| 131 name: 'E', | |
| 132 supertype: d.asThisSupertype, | |
| 133 mixedInType: a.asThisSupertype, | |
| 134 implementedTypes: [b.asThisSupertype])); | |
| 123 | 135 |
| 124 _assertTestLibraryText(''' | 136 _assertTestLibraryText(''' |
| 125 class A { | 137 class A { |
| 138 method foo() → void {} | |
| 139 method bar() → void {} | |
| 140 } | |
| 141 class B extends self::A { | |
| 142 method foo() → void; | |
| 143 } | |
| 144 class C extends self::A implements self::B {} | |
| 145 class D {} | |
| 146 class E = self::D with self::A implements self::B {} | |
| 147 '''); | |
| 148 | |
| 149 _assertOverridePairs(c, ['test::A::foo overrides test::B::foo']); | |
| 150 _assertOverridePairs(e, ['test::A::foo overrides test::B::foo']); | |
| 151 } | |
| 152 | |
| 153 /// 3. A non-abstract member is inherited from a superclass, and it overrides | |
| 154 /// an abstract member declared in this class. | |
| 155 /// TODO(scheglov): Implementation does not follow the documentation. | |
| 156 @failingTest | |
| 157 void test_forEachOverridePair_supertypeOverridesThisAbstract() { | |
| 158 var a = addClass(new Class( | |
| 159 name: 'A', | |
| 160 supertype: objectSuper, | |
| 161 procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')])); | |
| 162 var b = addClass(new Class( | |
| 163 name: 'B', | |
| 164 supertype: a.asThisSupertype, | |
| 165 procedures: [newEmptyMethod('foo', abstract: true)])); | |
| 166 | |
| 167 _assertTestLibraryText(''' | |
| 168 class A { | |
| 169 method foo() → void {} | |
| 170 method bar() → void {} | |
| 171 } | |
| 172 class B extends self::A { | |
| 173 method foo() → void; | |
| 174 } | |
| 175 '''); | |
| 176 | |
| 177 _assertOverridePairs(b, ['test::A::foo overrides test::B::foo']); | |
| 178 } | |
| 179 | |
| 180 /// 1. A member declared in the class overrides a member inheritable through | |
| 181 /// one of the supertypes of the class. | |
| 182 void test_forEachOverridePair_thisOverridesSupertype() { | |
| 183 var a = addClass(new Class( | |
| 184 name: 'A', | |
| 185 supertype: objectSuper, | |
| 186 procedures: [newEmptyMethod('foo'), newEmptyMethod('bar')])); | |
| 187 var b = addClass(new Class( | |
| 188 name: 'B', | |
| 189 supertype: a.asThisSupertype, | |
| 190 procedures: [newEmptyMethod('foo')])); | |
| 191 var c = addClass(new Class( | |
| 192 name: 'C', | |
| 193 supertype: b.asThisSupertype, | |
| 194 procedures: [newEmptyMethod('bar')])); | |
| 195 | |
| 196 _assertTestLibraryText(''' | |
| 197 class A { | |
| 126 method foo() → void {} | 198 method foo() → void {} |
| 127 method bar() → void {} | 199 method bar() → void {} |
| 128 } | 200 } |
| 129 class B extends self::A { | 201 class B extends self::A { |
| 130 method foo() → void {} | 202 method foo() → void {} |
| 131 } | 203 } |
| 132 class C extends self::B { | 204 class C extends self::B { |
| 133 method bar() → void {} | 205 method bar() → void {} |
| 134 } | 206 } |
| 135 '''); | 207 '''); |
| 136 | 208 |
| 137 _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']); | 209 _assertOverridePairs(b, ['test::B::foo overrides test::A::foo']); |
| 138 _assertOverridePairs(c, ['test::C::bar overrides test::A::bar']); | 210 _assertOverridePairs(c, ['test::C::bar overrides test::A::bar']); |
| 139 } | 211 } |
| 140 | 212 |
| 213 /// 1. A member declared in the class overrides a member inheritable through | |
| 214 /// one of the supertypes of the class. | |
| 215 void test_forEachOverridePair_thisOverridesSupertype_setter() { | |
| 216 var a = addClass(new Class( | |
| 217 name: 'A', | |
| 218 supertype: objectSuper, | |
| 219 procedures: [newEmptySetter('foo'), newEmptySetter('bar')])); | |
| 220 var b = addClass(new Class( | |
| 221 name: 'B', | |
| 222 supertype: a.asThisSupertype, | |
| 223 procedures: [newEmptySetter('foo')])); | |
| 224 var c = addClass(new Class( | |
| 225 name: 'C', | |
| 226 supertype: b.asThisSupertype, | |
| 227 procedures: [newEmptySetter('bar')])); | |
| 228 | |
| 229 _assertTestLibraryText(''' | |
| 230 class A { | |
| 231 set foo(dynamic _) → void {} | |
| 232 set bar(dynamic _) → void {} | |
| 233 } | |
| 234 class B extends self::A { | |
| 235 set foo(dynamic _) → void {} | |
| 236 } | |
| 237 class C extends self::B { | |
| 238 set bar(dynamic _) → void {} | |
| 239 } | |
| 240 '''); | |
| 241 | |
| 242 _assertOverridePairs(b, ['test::B::foo= overrides test::A::foo=']); | |
| 243 _assertOverridePairs(c, ['test::C::bar= overrides test::A::bar=']); | |
| 244 } | |
| 245 | |
| 141 void test_getClassAsInstanceOf_generic_extends() { | 246 void test_getClassAsInstanceOf_generic_extends() { |
| 142 var int = coreTypes.intClass.rawType; | 247 var int = coreTypes.intClass.rawType; |
| 143 var bool = coreTypes.boolClass.rawType; | 248 var bool = coreTypes.boolClass.rawType; |
| 144 | 249 |
| 145 var a = addGenericClass('A', ['T', 'U']); | 250 var a = addGenericClass('A', ['T', 'U']); |
| 146 | 251 |
| 147 var bT = new TypeParameter('T', objectClass.rawType); | 252 var bT = new TypeParameter('T', objectClass.rawType); |
| 148 var bTT = new TypeParameterType(bT); | 253 var bTT = new TypeParameterType(bT); |
| 149 var b = addClass(new Class( | 254 var b = addClass(new Class( |
| 150 name: 'B', | 255 name: 'B', |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 656 | 761 |
| 657 void test_rootClass() { | 762 void test_rootClass() { |
| 658 addClass(new Class(name: 'A', supertype: objectSuper)); | 763 addClass(new Class(name: 'A', supertype: objectSuper)); |
| 659 expect(hierarchy.rootClass, objectClass); | 764 expect(hierarchy.rootClass, objectClass); |
| 660 } | 765 } |
| 661 | 766 |
| 662 void _assertOverridePairs(Class class_, List<String> expected) { | 767 void _assertOverridePairs(Class class_, List<String> expected) { |
| 663 List<String> overrideDescriptions = []; | 768 List<String> overrideDescriptions = []; |
| 664 hierarchy.forEachOverridePair(class_, | 769 hierarchy.forEachOverridePair(class_, |
| 665 (Member declaredMember, Member interfaceMember, bool isSetter) { | 770 (Member declaredMember, Member interfaceMember, bool isSetter) { |
| 666 var desc = '$declaredMember overrides $interfaceMember'; | 771 String declaredName = '$declaredMember${isSetter ? '=': ''}'; |
| 772 String interfaceName = '$interfaceMember${isSetter ? '=': ''}'; | |
| 773 var desc = '$declaredName overrides $interfaceName'; | |
| 667 overrideDescriptions.add(desc); | 774 overrideDescriptions.add(desc); |
| 668 }); | 775 }); |
| 669 expect(overrideDescriptions, unorderedEquals(expected)); | 776 expect(overrideDescriptions, unorderedEquals(expected)); |
| 670 } | 777 } |
| 671 | 778 |
| 672 /// Assert that the test [library] has the [expectedText] presentation. | 779 /// Assert that the test [library] has the [expectedText] presentation. |
| 673 /// The presentation is close, but not identical to the normal Kernel one. | 780 /// The presentation is close, but not identical to the normal Kernel one. |
| 674 void _assertTestLibraryText(String expectedText) { | 781 void _assertTestLibraryText(String expectedText) { |
| 675 StringBuffer sb = new StringBuffer(); | 782 StringBuffer sb = new StringBuffer(); |
| 676 Printer printer = new Printer(sb); | 783 Printer printer = new Printer(sb); |
| 677 printer.writeLibraryFile(library); | 784 printer.writeLibraryFile(library); |
| 678 | 785 |
| 679 String actualText = sb.toString(); | 786 String actualText = sb.toString(); |
| 680 | 787 |
| 681 // Clean up the text a bit. | 788 // Clean up the text a bit. |
| 682 const oftenUsedPrefix = ''' | 789 const oftenUsedPrefix = ''' |
| 683 library test; | 790 library test; |
| 684 import self as self; | 791 import self as self; |
| 685 import "dart:core" as core; | 792 import "dart:core" as core; |
| 686 | 793 |
| 687 '''; | 794 '''; |
| 688 if (actualText.startsWith(oftenUsedPrefix)) { | 795 if (actualText.startsWith(oftenUsedPrefix)) { |
| 689 actualText = actualText.substring(oftenUsedPrefix.length); | 796 actualText = actualText.substring(oftenUsedPrefix.length); |
| 690 } | 797 } |
| 691 actualText = actualText.replaceAll('{\n}', '{}'); | 798 actualText = actualText.replaceAll('{\n}', '{}'); |
| 692 actualText = actualText.replaceAll(' extends core::Object', ''); | 799 actualText = actualText.replaceAll(' extends core::Object', ''); |
| 693 | 800 |
| 694 // if (actualText != expectedText) { | 801 if (actualText != expectedText) { |
|
Paul Berry
2017/06/01 21:43:46
Did you uncomment this on purpose?
scheglov
2017/06/01 21:45:24
No, forgot to comment out.
Fixed.
| |
| 695 // print('-------- Actual --------'); | 802 print('-------- Actual --------'); |
| 696 // print(actualText + '------------------------'); | 803 print(actualText + '------------------------'); |
| 697 // } | 804 } |
| 698 | 805 |
| 699 expect(actualText, expectedText); | 806 expect(actualText, expectedText); |
| 700 } | 807 } |
| 701 } | 808 } |
| OLD | NEW |