OLD | NEW |
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 import 'package:kernel/ast.dart'; | 4 import 'package:kernel/ast.dart'; |
5 import 'package:kernel/text/ast_to_text.dart'; | 5 import 'package:kernel/text/ast_to_text.dart'; |
6 import 'package:kernel/verifier.dart'; | 6 import 'package:kernel/verifier.dart'; |
7 import 'package:test/test.dart'; | 7 import 'package:test/test.dart'; |
8 | 8 |
9 /// Checks that the verifier correctly find errors in invalid programs. | 9 /// Checks that the verifier correctly find errors in invalid programs. |
10 /// | 10 /// |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 var class_ = new Class( | 192 var class_ = new Class( |
193 name: 'Test', | 193 name: 'Test', |
194 typeParameters: [test.makeTypeParameter()], | 194 typeParameters: [test.makeTypeParameter()], |
195 supertype: test.objectClass.asRawSupertype); | 195 supertype: test.objectClass.asRawSupertype); |
196 test.enclosingLibrary.addClass(class_); | 196 test.enclosingLibrary.addClass(class_); |
197 var constructor = new Constructor(new FunctionNode(new EmptyStatement()), | 197 var constructor = new Constructor(new FunctionNode(new EmptyStatement()), |
198 name: new Name('foo')); | 198 name: new Name('foo')); |
199 test.enclosingClass.addMember(constructor); | 199 test.enclosingClass.addMember(constructor); |
200 return new ConstructorInvocation(constructor, new Arguments.empty()); | 200 return new ConstructorInvocation(constructor, new Arguments.empty()); |
201 }); | 201 }); |
| 202 positiveTest('Valid typedef Foo = `(C) => void`', (TestHarness test) { |
| 203 var typedef_ = new Typedef( |
| 204 'Foo', new FunctionType([test.otherClass.rawType], const VoidType())); |
| 205 test.enclosingLibrary.addTypedef(typedef_); |
| 206 }); |
| 207 positiveTest('Valid typedef Foo = C<dynamic>', (TestHarness test) { |
| 208 var typedef_ = new Typedef( |
| 209 'Foo', new InterfaceType(test.otherClass, [const DynamicType()])); |
| 210 test.enclosingLibrary.addTypedef(typedef_); |
| 211 }); |
| 212 positiveTest('Valid typedefs Foo = Bar, Bar = C', (TestHarness test) { |
| 213 var foo = new Typedef('Foo', null); |
| 214 var bar = new Typedef('Bar', null); |
| 215 foo.type = new TypedefType(bar); |
| 216 bar.type = test.otherClass.rawType; |
| 217 test.enclosingLibrary.addTypedef(foo); |
| 218 test.enclosingLibrary.addTypedef(bar); |
| 219 }); |
| 220 positiveTest('Valid typedefs Foo = C<Bar>, Bar = C', (TestHarness test) { |
| 221 var foo = new Typedef('Foo', null); |
| 222 var bar = new Typedef('Bar', null); |
| 223 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]); |
| 224 bar.type = test.otherClass.rawType; |
| 225 test.enclosingLibrary.addTypedef(foo); |
| 226 test.enclosingLibrary.addTypedef(bar); |
| 227 }); |
| 228 positiveTest('Valid typedef type in field', (TestHarness test) { |
| 229 var typedef_ = new Typedef( |
| 230 'Foo', new FunctionType([test.otherClass.rawType], const VoidType())); |
| 231 var field = new Field(new Name('field'), type: new TypedefType(typedef_)); |
| 232 test.enclosingLibrary.addTypedef(typedef_); |
| 233 test.enclosingLibrary.addMember(field); |
| 234 }); |
| 235 negativeTest('Invalid typedef Foo = Foo', (TestHarness test) { |
| 236 var typedef_ = new Typedef('Foo', null); |
| 237 typedef_.type = new TypedefType(typedef_); |
| 238 test.enclosingLibrary.addTypedef(typedef_); |
| 239 }); |
| 240 negativeTest('Invalid typedef Foo = `(Foo) => void`', (TestHarness test) { |
| 241 var typedef_ = new Typedef('Foo', null); |
| 242 typedef_.type = |
| 243 new FunctionType([new TypedefType(typedef_)], const VoidType()); |
| 244 test.enclosingLibrary.addTypedef(typedef_); |
| 245 }); |
| 246 negativeTest('Invalid typedef Foo = `() => Foo`', (TestHarness test) { |
| 247 var typedef_ = new Typedef('Foo', null); |
| 248 typedef_.type = new FunctionType([], new TypedefType(typedef_)); |
| 249 test.enclosingLibrary.addTypedef(typedef_); |
| 250 }); |
| 251 negativeTest('Invalid typedef Foo = C<Foo>', (TestHarness test) { |
| 252 var typedef_ = new Typedef('Foo', null); |
| 253 typedef_.type = |
| 254 new InterfaceType(test.otherClass, [new TypedefType(typedef_)]); |
| 255 test.enclosingLibrary.addTypedef(typedef_); |
| 256 }); |
| 257 negativeTest('Invalid typedefs Foo = Bar, Bar = Foo', (TestHarness test) { |
| 258 var foo = new Typedef('Foo', null); |
| 259 var bar = new Typedef('Bar', null); |
| 260 foo.type = new TypedefType(bar); |
| 261 bar.type = new TypedefType(foo); |
| 262 test.enclosingLibrary.addTypedef(foo); |
| 263 test.enclosingLibrary.addTypedef(bar); |
| 264 }); |
| 265 negativeTest('Invalid typedefs Foo = Bar, Bar = C<Foo>', (TestHarness test) { |
| 266 var foo = new Typedef('Foo', null); |
| 267 var bar = new Typedef('Bar', null); |
| 268 foo.type = new TypedefType(bar); |
| 269 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]); |
| 270 test.enclosingLibrary.addTypedef(foo); |
| 271 test.enclosingLibrary.addTypedef(bar); |
| 272 }); |
| 273 negativeTest('Invalid typedefs Foo = C<Bar>, Bar = C<Foo>', |
| 274 (TestHarness test) { |
| 275 var foo = new Typedef('Foo', null); |
| 276 var bar = new Typedef('Bar', null); |
| 277 foo.type = new InterfaceType(test.otherClass, [new TypedefType(bar)]); |
| 278 bar.type = new InterfaceType(test.otherClass, [new TypedefType(foo)]); |
| 279 test.enclosingLibrary.addTypedef(foo); |
| 280 test.enclosingLibrary.addTypedef(bar); |
| 281 }); |
| 282 positiveTest('Valid long typedefs C20 = C19 = ... = C1 = C0 = dynamic', |
| 283 (TestHarness test) { |
| 284 var typedef_ = new Typedef('C0', const DynamicType()); |
| 285 test.enclosingLibrary.addTypedef(typedef_); |
| 286 for (int i = 1; i < 20; ++i) { |
| 287 typedef_ = new Typedef('C$i', new TypedefType(typedef_)); |
| 288 test.enclosingLibrary.addTypedef(typedef_); |
| 289 } |
| 290 }); |
| 291 negativeTest('Invalid long typedefs C20 = C19 = ... = C1 = C0 = C20', |
| 292 (TestHarness test) { |
| 293 var typedef_ = new Typedef('C0', null); |
| 294 test.enclosingLibrary.addTypedef(typedef_); |
| 295 var first = typedef_; |
| 296 for (int i = 1; i < 20; ++i) { |
| 297 typedef_ = new Typedef('C$i', new TypedefType(typedef_)); |
| 298 test.enclosingLibrary.addTypedef(typedef_); |
| 299 } |
| 300 first.type = new TypedefType(typedef_); |
| 301 }); |
| 302 positiveTest('Valid typedef Foo<T extends C> = C<T>', (TestHarness test) { |
| 303 var param = new TypeParameter('T', test.otherClass.rawType); |
| 304 var foo = new Typedef('Foo', |
| 305 new InterfaceType(test.otherClass, [new TypeParameterType(param)]), |
| 306 typeParameters: [param]); |
| 307 test.enclosingLibrary.addTypedef(foo); |
| 308 }); |
| 309 positiveTest('Valid typedef Foo<T extends C<T>> = C<T>', (TestHarness test) { |
| 310 var param = new TypeParameter('T', test.otherClass.rawType); |
| 311 param.bound = |
| 312 new InterfaceType(test.otherClass, [new TypeParameterType(param)]); |
| 313 var foo = new Typedef('Foo', |
| 314 new InterfaceType(test.otherClass, [new TypeParameterType(param)]), |
| 315 typeParameters: [param]); |
| 316 test.enclosingLibrary.addTypedef(foo); |
| 317 }); |
| 318 positiveTest('Valid typedef Foo<T> = dynamic, Bar<T extends Foo<T>> = C<T>', |
| 319 (TestHarness test) { |
| 320 var fooParam = test.makeTypeParameter('T'); |
| 321 var foo = |
| 322 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]); |
| 323 var barParam = new TypeParameter('T', null); |
| 324 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]); |
| 325 var bar = new Typedef('Bar', |
| 326 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]), |
| 327 typeParameters: [barParam]); |
| 328 test.enclosingLibrary.addTypedef(foo); |
| 329 test.enclosingLibrary.addTypedef(bar); |
| 330 }); |
| 331 negativeTest('Invalid typedefs Foo<T extends Bar<T>>, Bar<T extends Foo<T>>', |
| 332 (TestHarness test) { |
| 333 var fooParam = test.makeTypeParameter('T'); |
| 334 var foo = |
| 335 new Typedef('Foo', const DynamicType(), typeParameters: [fooParam]); |
| 336 var barParam = new TypeParameter('T', null); |
| 337 barParam.bound = new TypedefType(foo, [new TypeParameterType(barParam)]); |
| 338 var bar = new Typedef('Bar', |
| 339 new InterfaceType(test.otherClass, [new TypeParameterType(barParam)]), |
| 340 typeParameters: [barParam]); |
| 341 fooParam.bound = new TypedefType(bar, [new TypeParameterType(fooParam)]); |
| 342 test.enclosingLibrary.addTypedef(foo); |
| 343 test.enclosingLibrary.addTypedef(bar); |
| 344 }); |
| 345 negativeTest('Invalid typedef Foo<T extends Foo<dynamic> = C<T>', |
| 346 (TestHarness test) { |
| 347 var param = new TypeParameter('T', null); |
| 348 var foo = new Typedef('Foo', |
| 349 new InterfaceType(test.otherClass, [new TypeParameterType(param)]), |
| 350 typeParameters: [param]); |
| 351 param.bound = new TypedefType(foo, [const DynamicType()]); |
| 352 test.enclosingLibrary.addTypedef(foo); |
| 353 }); |
| 354 negativeTest('Typedef arity error', (TestHarness test) { |
| 355 var param = test.makeTypeParameter('T'); |
| 356 var foo = |
| 357 new Typedef('Foo', test.otherClass.rawType, typeParameters: [param]); |
| 358 var field = new Field(new Name('field'), type: new TypedefType(foo, [])); |
| 359 test.enclosingLibrary.addTypedef(foo); |
| 360 test.enclosingLibrary.addMember(field); |
| 361 }); |
| 362 negativeTest('Dangling typedef reference', (TestHarness test) { |
| 363 var foo = new Typedef('Foo', test.otherClass.rawType, typeParameters: []); |
| 364 var field = new Field(new Name('field'), type: new TypedefType(foo, [])); |
| 365 test.enclosingLibrary.addMember(field); |
| 366 }); |
202 } | 367 } |
203 | 368 |
204 checkHasError(Program program) { | 369 checkHasError(Program program) { |
205 bool passed = false; | 370 bool passed = false; |
206 try { | 371 try { |
207 verifyProgram(program); | 372 verifyProgram(program); |
208 passed = true; | 373 passed = true; |
209 } catch (e) {} | 374 } catch (e) {} |
210 if (passed) { | 375 if (passed) { |
211 fail('Failed to reject invalid program:\n${programToString(program)}'); | 376 fail('Failed to reject invalid program:\n${programToString(program)}'); |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 }); | 468 }); |
304 } | 469 } |
305 | 470 |
306 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) { | 471 positiveTest(String name, TreeNode makeTestCase(TestHarness test)) { |
307 test(name, () { | 472 test(name, () { |
308 var test = new TestHarness(); | 473 var test = new TestHarness(); |
309 test.addNode(makeTestCase(test)); | 474 test.addNode(makeTestCase(test)); |
310 verifyProgram(test.program); | 475 verifyProgram(test.program); |
311 }); | 476 }); |
312 } | 477 } |
OLD | NEW |