| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2015, 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 test.src.serialization.elements_test; |
| 6 |
| 7 import 'dart:typed_data'; |
| 8 |
| 9 import 'package:analyzer/src/generated/element.dart'; |
| 10 import 'package:analyzer/src/generated/source.dart'; |
| 11 import 'package:analyzer/src/summary/builder.dart'; |
| 12 import 'package:analyzer/src/summary/format.dart'; |
| 13 import 'package:analyzer/src/summary/summarize_elements.dart' |
| 14 as summarize_elements; |
| 15 import 'package:unittest/unittest.dart'; |
| 16 |
| 17 import '../../generated/resolver_test.dart'; |
| 18 import '../../reflective_tests.dart'; |
| 19 |
| 20 main() { |
| 21 groupSep = ' | '; |
| 22 runReflectiveTests(SummarizeElementsTest); |
| 23 } |
| 24 |
| 25 /** |
| 26 * Override of [SummaryTest] which creates summaries from the element model. |
| 27 */ |
| 28 @reflectiveTest |
| 29 class SummarizeElementsTest extends ResolverTestCase with SummaryTest { |
| 30 @override |
| 31 bool get checkAstDerivedData => false; |
| 32 |
| 33 /** |
| 34 * Serialize the library containing the given class [element], then |
| 35 * deserialize it and return the summary of the class. |
| 36 */ |
| 37 UnlinkedClass serializeClassElement(ClassElement element) { |
| 38 serializeLibraryElement(element.library); |
| 39 return findClass(element.name, failIfAbsent: true); |
| 40 } |
| 41 |
| 42 /** |
| 43 * Serialize the given [library] element, then deserialize it and store the |
| 44 * resulting summary in [lib]. |
| 45 */ |
| 46 void serializeLibraryElement(LibraryElement library) { |
| 47 BuilderContext builderContext = new BuilderContext(); |
| 48 Object serializedLib = summarize_elements.serializeLibrary( |
| 49 builderContext, library, typeProvider); |
| 50 List<int> encodedLib = builderContext.getBuffer(serializedLib); |
| 51 lib = new PrelinkedLibrary.fromBuffer(encodedLib); |
| 52 } |
| 53 |
| 54 @override |
| 55 void serializeLibraryText(String text, {bool allowErrors: false}) { |
| 56 Source source = addSource(text); |
| 57 LibraryElement library = resolve2(source); |
| 58 if (!allowErrors) { |
| 59 assertNoErrors(source); |
| 60 } |
| 61 serializeLibraryElement(library); |
| 62 expect(unlinked.imports.length, lib.importDependencies.length); |
| 63 expect(unlinked.references.length, lib.references.length); |
| 64 } |
| 65 |
| 66 test_class_no_superclass() { |
| 67 UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element); |
| 68 expect(cls.supertype, isNull); |
| 69 } |
| 70 } |
| 71 |
| 72 /** |
| 73 * Base class containing most summary tests. This allows summary tests to be |
| 74 * re-used to exercise all the different ways in which summaries can be |
| 75 * generated (e.g. direct from the AST, from the element model, from a |
| 76 * "relinking" process, etc.) |
| 77 */ |
| 78 abstract class SummaryTest { |
| 79 /** |
| 80 * The result of serializing and then deserializing the library under test. |
| 81 */ |
| 82 PrelinkedLibrary lib; |
| 83 |
| 84 /** |
| 85 * `true` if the summary was created directly from the AST (and hence |
| 86 * contains information that is not obtainable from the element model alone). |
| 87 * TODO(paulberry): modify the element model so that it contains all the data |
| 88 * that summaries need, so that this flag is no longer needed. |
| 89 */ |
| 90 bool get checkAstDerivedData; |
| 91 |
| 92 /** |
| 93 * Get access to the "unlinked" section of the summary. |
| 94 */ |
| 95 UnlinkedLibrary get unlinked => lib.unlinked; |
| 96 |
| 97 /** |
| 98 * Add the given source file so that it may be referenced by the file under |
| 99 * test. |
| 100 */ |
| 101 addNamedSource(String filePath, String contents); |
| 102 |
| 103 /** |
| 104 * Verify that the [combinatorName] correctly represents the given [expected] |
| 105 * name. |
| 106 */ |
| 107 void checkCombinatorName( |
| 108 UnlinkedCombinatorName combinatorName, String expected) { |
| 109 expect(combinatorName, new isInstanceOf<UnlinkedCombinatorName>()); |
| 110 expect(combinatorName.name, expected); |
| 111 } |
| 112 |
| 113 /** |
| 114 * Verify that the [dependency]th element of the dependency table represents |
| 115 * a file reachable via the given [absoluteUri] and [relativeUri]. |
| 116 */ |
| 117 void checkDependency(int dependency, String absoluteUri, String relativeUri) { |
| 118 if (!checkAstDerivedData) { |
| 119 // The element model doesn't (yet) store enough information to recover |
| 120 // relative URIs, so we have to use the absolute URI. |
| 121 // TODO(paulberry): fix this. |
| 122 relativeUri = absoluteUri; |
| 123 } |
| 124 expect(dependency, new isInstanceOf<int>()); |
| 125 expect(lib.dependencies[dependency].uri, relativeUri); |
| 126 } |
| 127 |
| 128 /** |
| 129 * Verify that the given [typeRef] represents the type `dynamic`. |
| 130 */ |
| 131 void checkDynamicTypeRef(UnlinkedTypeRef typeRef) { |
| 132 checkTypeRef(typeRef, null, null, null); |
| 133 } |
| 134 |
| 135 /** |
| 136 * Verify that the dependency table contains an entry for a file reachable |
| 137 * via the given [absoluteUri] and [relativeUri]. |
| 138 */ |
| 139 void checkHasDependency(String absoluteUri, String relativeUri) { |
| 140 if (!checkAstDerivedData) { |
| 141 // The element model doesn't (yet) store enough information to recover |
| 142 // relative URIs, so we have to use the absolute URI. |
| 143 // TODO(paulberry): fix this. |
| 144 relativeUri = absoluteUri; |
| 145 } |
| 146 for (PrelinkedDependency dep in lib.dependencies) { |
| 147 if (dep.uri == relativeUri) { |
| 148 return; |
| 149 } |
| 150 } |
| 151 fail('Did not find dependency $absoluteUri'); |
| 152 } |
| 153 |
| 154 /** |
| 155 * Verify that the dependency table *does not* contain any entries for a file |
| 156 * reachable via the given [absoluteUri] and [relativeUri]. |
| 157 */ |
| 158 void checkLacksDependency(String absoluteUri, String relativeUri) { |
| 159 if (!checkAstDerivedData) { |
| 160 // The element model doesn't (yet) store enough information to recover |
| 161 // relative URIs, so we have to use the absolute URI. |
| 162 // TODO(paulberry): fix this. |
| 163 relativeUri = absoluteUri; |
| 164 } |
| 165 for (PrelinkedDependency dep in lib.dependencies) { |
| 166 if (dep.uri == relativeUri) { |
| 167 fail('Unexpected dependency found: $relativeUri'); |
| 168 } |
| 169 } |
| 170 } |
| 171 |
| 172 /** |
| 173 * Verify that the given [typeRef] represents a reference to a type parameter |
| 174 * having the given [deBruijnIndex]. |
| 175 */ |
| 176 void checkParamTypeRef(UnlinkedTypeRef typeRef, int deBruijnIndex) { |
| 177 expect(typeRef, new isInstanceOf<UnlinkedTypeRef>()); |
| 178 expect(typeRef.reference, 0); |
| 179 expect(typeRef.typeArguments, isEmpty); |
| 180 expect(typeRef.paramReference, deBruijnIndex); |
| 181 } |
| 182 |
| 183 /** |
| 184 * Verify that the given [typeRef] represents a reference to a type declared |
| 185 * in a file reachable via [absoluteUri] and [relativeUri], having name |
| 186 * [expectedName]. If [expectedPrefix] is supplied, verify that the type is |
| 187 * reached via the given prefix. If [allowTypeParameters] is true, allow the |
| 188 * type reference to supply type parameters. [expectedKind] is the kind of |
| 189 * object referenced. |
| 190 */ |
| 191 void checkTypeRef(UnlinkedTypeRef typeRef, String absoluteUri, |
| 192 String relativeUri, String expectedName, |
| 193 {String expectedPrefix, |
| 194 bool allowTypeParameters: false, |
| 195 PrelinkedReferenceKind expectedKind: |
| 196 PrelinkedReferenceKind.classOrEnum}) { |
| 197 expect(typeRef, new isInstanceOf<UnlinkedTypeRef>()); |
| 198 expect(typeRef.paramReference, 0); |
| 199 int index = typeRef.reference; |
| 200 UnlinkedReference reference = unlinked.references[index]; |
| 201 PrelinkedReference referenceResolution = lib.references[index]; |
| 202 if (absoluteUri == null) { |
| 203 expect(referenceResolution.dependency, 0); |
| 204 } else { |
| 205 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); |
| 206 } |
| 207 if (!allowTypeParameters) { |
| 208 expect(typeRef.typeArguments, isEmpty); |
| 209 } |
| 210 if (expectedName == null) { |
| 211 expect(reference.name, isEmpty); |
| 212 } else { |
| 213 expect(reference.name, expectedName); |
| 214 } |
| 215 if (checkAstDerivedData) { |
| 216 if (expectedPrefix == null) { |
| 217 expect(reference.prefix, 0); |
| 218 expect(unlinked.prefixes[reference.prefix].name, isEmpty); |
| 219 } else { |
| 220 expect(reference.prefix, isNot(0)); |
| 221 expect(unlinked.prefixes[reference.prefix].name, expectedPrefix); |
| 222 } |
| 223 } |
| 224 expect(referenceResolution.kind, expectedKind); |
| 225 } |
| 226 |
| 227 /** |
| 228 * Verify that the given [typeRef] represents a reference to an unresolved |
| 229 * type. |
| 230 */ |
| 231 void checkUnresolvedTypeRef( |
| 232 UnlinkedTypeRef typeRef, String expectedPrefix, String expectedName) { |
| 233 // When serializing from the element model, unresolved type refs lose their |
| 234 // name. |
| 235 checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null, |
| 236 expectedPrefix: expectedPrefix, |
| 237 expectedKind: PrelinkedReferenceKind.unresolved); |
| 238 } |
| 239 |
| 240 fail_test_import_missing() { |
| 241 // TODO(paulberry): At the moment unresolved imports are not included in |
| 242 // the element model, so we can't pass this test. |
| 243 // Unresolved imports are included since this is necessary for proper |
| 244 // dependency tracking. |
| 245 serializeLibraryText('import "foo.dart";', allowErrors: true); |
| 246 // Second import is the implicit import of dart:core |
| 247 expect(unlinked.imports, hasLength(2)); |
| 248 checkDependency(lib.importDependencies[0], 'file:///foo.dart', 'foo.dart'); |
| 249 } |
| 250 |
| 251 /** |
| 252 * Find the class with the given [className] in the summary, and return its |
| 253 * [UnlinkedClass] data structure. |
| 254 */ |
| 255 UnlinkedClass findClass(String className, {bool failIfAbsent: false}) { |
| 256 UnlinkedClass result; |
| 257 for (UnlinkedClass cls in unlinked.classes) { |
| 258 if (cls.name == className) { |
| 259 if (result != null) { |
| 260 fail('Duplicate class $className'); |
| 261 } |
| 262 result = cls; |
| 263 } |
| 264 } |
| 265 if (result == null && failIfAbsent) { |
| 266 fail('Class $className not found in serialized output'); |
| 267 } |
| 268 return result; |
| 269 } |
| 270 |
| 271 /** |
| 272 * Find the enum with the given [enumName] in the summary, and return its |
| 273 * [UnlinkedEnum] data structure. |
| 274 */ |
| 275 UnlinkedEnum findEnum(String enumName, {bool failIfAbsent: false}) { |
| 276 UnlinkedEnum result; |
| 277 for (UnlinkedEnum e in unlinked.enums) { |
| 278 if (e.name == enumName) { |
| 279 if (result != null) { |
| 280 fail('Duplicate enum $enumName'); |
| 281 } |
| 282 result = e; |
| 283 } |
| 284 } |
| 285 if (result == null && failIfAbsent) { |
| 286 fail('Enum $enumName not found in serialized output'); |
| 287 } |
| 288 return result; |
| 289 } |
| 290 |
| 291 /** |
| 292 * Find the executable with the given [executableName] in the summary, and |
| 293 * return its [UnlinkedExecutable] data structure. |
| 294 */ |
| 295 UnlinkedExecutable findExecutable(String executableName, |
| 296 {UnlinkedClass cls, bool failIfAbsent: false}) { |
| 297 List<UnlinkedExecutable> executables; |
| 298 if (cls == null) { |
| 299 executables = unlinked.executables; |
| 300 } else { |
| 301 executables = cls.executables; |
| 302 } |
| 303 UnlinkedExecutable result; |
| 304 for (UnlinkedExecutable executable in executables) { |
| 305 if (executable.name == executableName) { |
| 306 if (result != null) { |
| 307 fail('Duplicate executable $executableName'); |
| 308 } |
| 309 result = executable; |
| 310 } |
| 311 } |
| 312 if (result == null && failIfAbsent) { |
| 313 fail('Executable $executableName not found in serialized output'); |
| 314 } |
| 315 return result; |
| 316 } |
| 317 |
| 318 /** |
| 319 * Find the typedef with the given [typedefName] in the summary, and return |
| 320 * its [UnlinkedTypedef] data structure. |
| 321 */ |
| 322 UnlinkedTypedef findTypedef(String typedefName, {bool failIfAbsent: false}) { |
| 323 UnlinkedTypedef result; |
| 324 for (UnlinkedTypedef type in unlinked.typedefs) { |
| 325 if (type.name == typedefName) { |
| 326 if (result != null) { |
| 327 fail('Duplicate typedef $typedefName'); |
| 328 } |
| 329 result = type; |
| 330 } |
| 331 } |
| 332 if (result == null && failIfAbsent) { |
| 333 fail('Typedef $typedefName not found in serialized output'); |
| 334 } |
| 335 return result; |
| 336 } |
| 337 |
| 338 /** |
| 339 * Find the top level variable with the given [variableName] in the summary, |
| 340 * and return its [UnlinkedVariable] data structure. |
| 341 */ |
| 342 UnlinkedVariable findVariable(String variableName, |
| 343 {UnlinkedClass cls, bool failIfAbsent: false}) { |
| 344 List<UnlinkedVariable> variables; |
| 345 if (cls == null) { |
| 346 variables = unlinked.variables; |
| 347 } else { |
| 348 variables = cls.fields; |
| 349 } |
| 350 UnlinkedVariable result; |
| 351 for (UnlinkedVariable variable in variables) { |
| 352 if (variable.name == variableName) { |
| 353 if (result != null) { |
| 354 fail('Duplicate variable $variableName'); |
| 355 } |
| 356 result = variable; |
| 357 } |
| 358 } |
| 359 if (result == null && failIfAbsent) { |
| 360 fail('Variable $variableName not found in serialized output'); |
| 361 } |
| 362 return result; |
| 363 } |
| 364 |
| 365 /** |
| 366 * Serialize the given library [text] and return the summary of the class |
| 367 * with the given [className]. |
| 368 */ |
| 369 UnlinkedClass serializeClassText(String text, [String className = 'C']) { |
| 370 serializeLibraryText(text); |
| 371 return findClass(className, failIfAbsent: true); |
| 372 } |
| 373 |
| 374 /** |
| 375 * Serialize the given library [text] and return the summary of the enum with |
| 376 * the given [enumName]. |
| 377 */ |
| 378 UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) { |
| 379 serializeLibraryText(text); |
| 380 return findEnum(enumName, failIfAbsent: true); |
| 381 } |
| 382 |
| 383 /** |
| 384 * Serialize the given library [text] and return the summary of the |
| 385 * executable with the given [executableName]. |
| 386 */ |
| 387 UnlinkedExecutable serializeExecutableText(String text, |
| 388 [String executableName = 'f']) { |
| 389 serializeLibraryText(text); |
| 390 return findExecutable(executableName, failIfAbsent: true); |
| 391 } |
| 392 |
| 393 /** |
| 394 * Serialize the given library [text], then deserialize it and store its |
| 395 * summary in [lib]. |
| 396 */ |
| 397 void serializeLibraryText(String text, {bool allowErrors: false}); |
| 398 |
| 399 /** |
| 400 * Serialize the given library [text] and return the summary of the typedef |
| 401 * with the given [typedefName]. |
| 402 */ |
| 403 UnlinkedTypedef serializeTypedefText(String text, |
| 404 [String typedefName = 'F']) { |
| 405 serializeLibraryText(text); |
| 406 return findTypedef(typedefName, failIfAbsent: true); |
| 407 } |
| 408 |
| 409 /** |
| 410 * Serialize a type declaration using the given [text] as a type name, and |
| 411 * return a summary of the corresponding [UnlinkedTypeRef]. If the type |
| 412 * declaration needs to refer to types that are not available in core, those |
| 413 * types may be declared in [otherDeclarations]. |
| 414 */ |
| 415 UnlinkedTypeRef serializeTypeText(String text, |
| 416 {String otherDeclarations: '', bool allowErrors: false}) { |
| 417 return serializeVariableText('$otherDeclarations\n$text v;', |
| 418 allowErrors: allowErrors).type; |
| 419 } |
| 420 |
| 421 /** |
| 422 * Serialize the given library [text] and return the summary of the variable |
| 423 * with the given [variableName]. |
| 424 */ |
| 425 UnlinkedVariable serializeVariableText(String text, |
| 426 {String variableName: 'v', bool allowErrors: false}) { |
| 427 serializeLibraryText(text, allowErrors: allowErrors); |
| 428 return findVariable(variableName, failIfAbsent: true); |
| 429 } |
| 430 |
| 431 test_class_abstract() { |
| 432 UnlinkedClass cls = serializeClassText('abstract class C {}'); |
| 433 expect(cls.isAbstract, true); |
| 434 } |
| 435 |
| 436 test_class_alias_abstract() { |
| 437 UnlinkedClass cls = serializeClassText( |
| 438 'abstract class C = D with E; class D {} class E {}'); |
| 439 expect(cls.isAbstract, true); |
| 440 } |
| 441 |
| 442 test_class_alias_concrete() { |
| 443 UnlinkedClass cls = |
| 444 serializeClassText('class C = D with E; class D {} class E {}'); |
| 445 expect(cls.isAbstract, false); |
| 446 } |
| 447 |
| 448 test_class_alias_flag() { |
| 449 UnlinkedClass cls = |
| 450 serializeClassText('class C = D with E; class D {} class E {}'); |
| 451 expect(cls.isMixinApplication, true); |
| 452 } |
| 453 |
| 454 test_class_alias_mixin_order() { |
| 455 UnlinkedClass cls = serializeClassText(''' |
| 456 class C = D with E, F; |
| 457 class D {} |
| 458 class E {} |
| 459 class F {} |
| 460 '''); |
| 461 expect(cls.mixins, hasLength(2)); |
| 462 checkTypeRef(cls.mixins[0], null, null, 'E'); |
| 463 checkTypeRef(cls.mixins[1], null, null, 'F'); |
| 464 } |
| 465 |
| 466 test_class_alias_no_implicit_constructors() { |
| 467 UnlinkedClass cls = serializeClassText(''' |
| 468 class C = D with E; |
| 469 class D { |
| 470 D.foo(); |
| 471 D.bar(); |
| 472 } |
| 473 class E {} |
| 474 '''); |
| 475 expect(cls.executables, isEmpty); |
| 476 } |
| 477 |
| 478 test_class_alias_supertype() { |
| 479 UnlinkedClass cls = |
| 480 serializeClassText('class C = D with E; class D {} class E {}'); |
| 481 checkTypeRef(cls.supertype, null, null, 'D'); |
| 482 } |
| 483 |
| 484 test_class_concrete() { |
| 485 UnlinkedClass cls = serializeClassText('class C {}'); |
| 486 expect(cls.isAbstract, false); |
| 487 } |
| 488 |
| 489 test_class_interface() { |
| 490 UnlinkedClass cls = serializeClassText(''' |
| 491 class C implements D {} |
| 492 class D {} |
| 493 '''); |
| 494 expect(cls.interfaces, hasLength(1)); |
| 495 checkTypeRef(cls.interfaces[0], null, null, 'D'); |
| 496 } |
| 497 |
| 498 test_class_interface_order() { |
| 499 UnlinkedClass cls = serializeClassText(''' |
| 500 class C implements D, E {} |
| 501 class D {} |
| 502 class E {} |
| 503 '''); |
| 504 expect(cls.interfaces, hasLength(2)); |
| 505 checkTypeRef(cls.interfaces[0], null, null, 'D'); |
| 506 checkTypeRef(cls.interfaces[1], null, null, 'E'); |
| 507 } |
| 508 |
| 509 test_class_mixin() { |
| 510 UnlinkedClass cls = serializeClassText(''' |
| 511 class C extends Object with D {} |
| 512 class D {} |
| 513 '''); |
| 514 expect(cls.mixins, hasLength(1)); |
| 515 checkTypeRef(cls.mixins[0], null, null, 'D'); |
| 516 } |
| 517 |
| 518 test_class_mixin_order() { |
| 519 UnlinkedClass cls = serializeClassText(''' |
| 520 class C extends Object with D, E {} |
| 521 class D {} |
| 522 class E {} |
| 523 '''); |
| 524 expect(cls.mixins, hasLength(2)); |
| 525 checkTypeRef(cls.mixins[0], null, null, 'D'); |
| 526 checkTypeRef(cls.mixins[1], null, null, 'E'); |
| 527 } |
| 528 |
| 529 test_class_name() { |
| 530 var classText = 'class C {}'; |
| 531 UnlinkedClass cls = serializeClassText(classText); |
| 532 expect(cls.name, 'C'); |
| 533 expect(cls.unit, 0); |
| 534 } |
| 535 |
| 536 test_class_no_flags() { |
| 537 UnlinkedClass cls = serializeClassText('class C {}'); |
| 538 expect(cls.isAbstract, false); |
| 539 expect(cls.isMixinApplication, false); |
| 540 } |
| 541 |
| 542 test_class_no_interface() { |
| 543 UnlinkedClass cls = serializeClassText('class C {}'); |
| 544 expect(cls.interfaces, isEmpty); |
| 545 } |
| 546 |
| 547 test_class_no_mixins() { |
| 548 UnlinkedClass cls = serializeClassText('class C {}'); |
| 549 expect(cls.mixins, isEmpty); |
| 550 } |
| 551 |
| 552 test_class_no_type_param() { |
| 553 UnlinkedClass cls = serializeClassText('class C {}'); |
| 554 expect(cls.typeParameters, isEmpty); |
| 555 } |
| 556 |
| 557 test_class_non_alias_flag() { |
| 558 UnlinkedClass cls = serializeClassText('class C {}'); |
| 559 expect(cls.isMixinApplication, false); |
| 560 } |
| 561 |
| 562 test_class_superclass() { |
| 563 UnlinkedClass cls = serializeClassText('class C {}'); |
| 564 expect(cls.supertype, isNull); |
| 565 } |
| 566 |
| 567 test_class_superclass_explicit() { |
| 568 UnlinkedClass cls = serializeClassText('class C extends D {} class D {}'); |
| 569 expect(cls.supertype, isNotNull); |
| 570 checkTypeRef(cls.supertype, null, null, 'D'); |
| 571 } |
| 572 |
| 573 test_class_type_param_bound() { |
| 574 UnlinkedClass cls = serializeClassText('class C<T extends List> {}'); |
| 575 expect(cls.typeParameters, hasLength(1)); |
| 576 expect(cls.typeParameters[0].name, 'T'); |
| 577 expect(cls.typeParameters[0].bound, isNotNull); |
| 578 checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List', |
| 579 allowTypeParameters: true); |
| 580 } |
| 581 |
| 582 test_class_type_param_f_bound() { |
| 583 UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}'); |
| 584 UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0]; |
| 585 checkParamTypeRef(typeArgument, 2); |
| 586 } |
| 587 |
| 588 test_class_type_param_f_bound_self_ref() { |
| 589 UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}'); |
| 590 UnlinkedTypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0]; |
| 591 checkParamTypeRef(typeArgument, 1); |
| 592 } |
| 593 |
| 594 test_class_type_param_no_bound() { |
| 595 UnlinkedClass cls = serializeClassText('class C<T> {}'); |
| 596 expect(cls.typeParameters, hasLength(1)); |
| 597 expect(cls.typeParameters[0].name, 'T'); |
| 598 expect(cls.typeParameters[0].bound, isNull); |
| 599 } |
| 600 |
| 601 test_constructor() { |
| 602 UnlinkedExecutable executable = |
| 603 findExecutable('', cls: serializeClassText('class C { C(); }')); |
| 604 expect(executable.kind, UnlinkedExecutableKind.constructor); |
| 605 } |
| 606 |
| 607 test_constructor_anonymous() { |
| 608 UnlinkedExecutable executable = |
| 609 findExecutable('', cls: serializeClassText('class C { C(); }')); |
| 610 expect(executable.name, isEmpty); |
| 611 } |
| 612 |
| 613 test_constructor_const() { |
| 614 UnlinkedExecutable executable = |
| 615 findExecutable('', cls: serializeClassText('class C { const C(); }')); |
| 616 expect(executable.isConst, isTrue); |
| 617 } |
| 618 |
| 619 test_constructor_factory() { |
| 620 UnlinkedExecutable executable = findExecutable('', |
| 621 cls: serializeClassText('class C { factory C() => null; }')); |
| 622 expect(executable.isFactory, isTrue); |
| 623 } |
| 624 |
| 625 test_constructor_implicit() { |
| 626 // Implicit constructors are not serialized. |
| 627 UnlinkedExecutable executable = findExecutable(null, |
| 628 cls: serializeClassText('class C { C(); }'), failIfAbsent: false); |
| 629 expect(executable, isNull); |
| 630 } |
| 631 |
| 632 test_constructor_initializing_formal() { |
| 633 UnlinkedExecutable executable = findExecutable('', |
| 634 cls: serializeClassText('class C { C(this.x); final x; }')); |
| 635 UnlinkedParam parameter = executable.parameters[0]; |
| 636 expect(parameter.isInitializingFormal, isTrue); |
| 637 } |
| 638 |
| 639 test_constructor_initializing_formal_explicit_type() { |
| 640 UnlinkedExecutable executable = findExecutable('', |
| 641 cls: serializeClassText('class C { C(int this.x); final x; }')); |
| 642 UnlinkedParam parameter = executable.parameters[0]; |
| 643 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int'); |
| 644 } |
| 645 |
| 646 test_constructor_initializing_formal_function_typed() { |
| 647 UnlinkedExecutable executable = findExecutable('', |
| 648 cls: serializeClassText('class C { C(this.x()); final x; }')); |
| 649 UnlinkedParam parameter = executable.parameters[0]; |
| 650 expect(parameter.isFunctionTyped, isTrue); |
| 651 } |
| 652 |
| 653 test_constructor_initializing_formal_function_typed_explicit_return_type() { |
| 654 UnlinkedExecutable executable = findExecutable('', |
| 655 cls: serializeClassText('class C { C(int this.x()); Function x; }')); |
| 656 UnlinkedParam parameter = executable.parameters[0]; |
| 657 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int'); |
| 658 } |
| 659 |
| 660 test_constructor_initializing_formal_function_typed_implicit_return_type() { |
| 661 UnlinkedExecutable executable = findExecutable('', |
| 662 cls: serializeClassText('class C { C(this.x()); Function x; }')); |
| 663 UnlinkedParam parameter = executable.parameters[0]; |
| 664 checkDynamicTypeRef(parameter.type); |
| 665 } |
| 666 |
| 667 test_constructor_initializing_formal_function_typed_no_prameters() { |
| 668 UnlinkedExecutable executable = findExecutable('', |
| 669 cls: serializeClassText('class C { C(this.x()); final x; }')); |
| 670 UnlinkedParam parameter = executable.parameters[0]; |
| 671 expect(parameter.parameters, isEmpty); |
| 672 } |
| 673 |
| 674 test_constructor_initializing_formal_function_typed_prameter() { |
| 675 UnlinkedExecutable executable = findExecutable('', |
| 676 cls: serializeClassText('class C { C(this.x(a)); final x; }')); |
| 677 UnlinkedParam parameter = executable.parameters[0]; |
| 678 expect(parameter.parameters, hasLength(1)); |
| 679 } |
| 680 |
| 681 test_constructor_initializing_formal_function_typed_prameter_order() { |
| 682 UnlinkedExecutable executable = findExecutable('', |
| 683 cls: serializeClassText('class C { C(this.x(a, b)); final x; }')); |
| 684 UnlinkedParam parameter = executable.parameters[0]; |
| 685 expect(parameter.parameters, hasLength(2)); |
| 686 expect(parameter.parameters[0].name, 'a'); |
| 687 expect(parameter.parameters[1].name, 'b'); |
| 688 } |
| 689 |
| 690 test_constructor_initializing_formal_implicit_type() { |
| 691 // Note: the implicit type of an initializing formal is the type of the |
| 692 // field. |
| 693 UnlinkedExecutable executable = findExecutable('', |
| 694 cls: serializeClassText('class C { C(this.x); int x; }')); |
| 695 UnlinkedParam parameter = executable.parameters[0]; |
| 696 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int'); |
| 697 } |
| 698 |
| 699 test_constructor_initializing_formal_name() { |
| 700 UnlinkedExecutable executable = findExecutable('', |
| 701 cls: serializeClassText('class C { C(this.x); final x; }')); |
| 702 UnlinkedParam parameter = executable.parameters[0]; |
| 703 expect(parameter.name, 'x'); |
| 704 } |
| 705 |
| 706 test_constructor_initializing_formal_named() { |
| 707 // TODO(paulberry): also test default value |
| 708 UnlinkedExecutable executable = findExecutable('', |
| 709 cls: serializeClassText('class C { C({this.x}); final x; }')); |
| 710 UnlinkedParam parameter = executable.parameters[0]; |
| 711 expect(parameter.kind, UnlinkedParamKind.named); |
| 712 } |
| 713 |
| 714 test_constructor_initializing_formal_non_function_typed() { |
| 715 UnlinkedExecutable executable = findExecutable('', |
| 716 cls: serializeClassText('class C { C(this.x); final x; }')); |
| 717 UnlinkedParam parameter = executable.parameters[0]; |
| 718 expect(parameter.isFunctionTyped, isFalse); |
| 719 } |
| 720 |
| 721 test_constructor_initializing_formal_positional() { |
| 722 // TODO(paulberry): also test default value |
| 723 UnlinkedExecutable executable = findExecutable('', |
| 724 cls: serializeClassText('class C { C([this.x]); final x; }')); |
| 725 UnlinkedParam parameter = executable.parameters[0]; |
| 726 expect(parameter.kind, UnlinkedParamKind.positional); |
| 727 } |
| 728 |
| 729 test_constructor_initializing_formal_required() { |
| 730 UnlinkedExecutable executable = findExecutable('', |
| 731 cls: serializeClassText('class C { C(this.x); final x; }')); |
| 732 UnlinkedParam parameter = executable.parameters[0]; |
| 733 expect(parameter.kind, UnlinkedParamKind.required); |
| 734 } |
| 735 |
| 736 test_constructor_named() { |
| 737 UnlinkedExecutable executable = |
| 738 findExecutable('foo', cls: serializeClassText('class C { C.foo(); }')); |
| 739 expect(executable.name, 'foo'); |
| 740 } |
| 741 |
| 742 test_constructor_non_const() { |
| 743 UnlinkedExecutable executable = |
| 744 findExecutable('', cls: serializeClassText('class C { C(); }')); |
| 745 expect(executable.isConst, isFalse); |
| 746 } |
| 747 |
| 748 test_constructor_non_factory() { |
| 749 UnlinkedExecutable executable = |
| 750 findExecutable('', cls: serializeClassText('class C { C(); }')); |
| 751 expect(executable.isFactory, isFalse); |
| 752 } |
| 753 |
| 754 test_constructor_return_type() { |
| 755 UnlinkedExecutable executable = |
| 756 findExecutable('', cls: serializeClassText('class C { C(); }')); |
| 757 checkTypeRef(executable.returnType, null, null, 'C'); |
| 758 } |
| 759 |
| 760 test_constructor_return_type_parameterized() { |
| 761 UnlinkedExecutable executable = |
| 762 findExecutable('', cls: serializeClassText('class C<T, U> { C(); }')); |
| 763 checkTypeRef(executable.returnType, null, null, 'C', |
| 764 allowTypeParameters: true); |
| 765 expect(executable.returnType.typeArguments, hasLength(2)); |
| 766 { |
| 767 UnlinkedTypeRef typeRef = executable.returnType.typeArguments[0]; |
| 768 checkParamTypeRef(typeRef, 2); |
| 769 } |
| 770 { |
| 771 UnlinkedTypeRef typeRef = executable.returnType.typeArguments[1]; |
| 772 checkParamTypeRef(typeRef, 1); |
| 773 } |
| 774 } |
| 775 |
| 776 test_dependencies_export_none() { |
| 777 // Exports are not listed as dependencies since no change to the exported |
| 778 // file can change the summary of the exporting file. |
| 779 addNamedSource('/a.dart', 'library a; export "b.dart";'); |
| 780 addNamedSource('/b.dart', 'library b;'); |
| 781 serializeLibraryText('export "a.dart";'); |
| 782 checkLacksDependency('file:///a.dart', 'a.dart'); |
| 783 checkLacksDependency('file:///b.dart', 'b.dart'); |
| 784 } |
| 785 |
| 786 test_dependencies_import_to_export() { |
| 787 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 788 addNamedSource('/b.dart', 'library b;'); |
| 789 serializeLibraryText('import "a.dart"; A a;'); |
| 790 checkHasDependency('file:///a.dart', 'a.dart'); |
| 791 // The main test library depends on b.dart, because names defined in |
| 792 // b.dart are exported by a.dart. |
| 793 checkHasDependency('file:///b.dart', 'b.dart'); |
| 794 } |
| 795 |
| 796 test_dependencies_import_to_export_in_subdirs_absolute_export() { |
| 797 addNamedSource('/a/a.dart', 'library a; export "/a/b/b.dart"; class A {}'); |
| 798 addNamedSource('/a/b/b.dart', 'library b;'); |
| 799 serializeLibraryText('import "a/a.dart"; A a;'); |
| 800 checkHasDependency('file:///a/a.dart', 'a/a.dart'); |
| 801 // The main test library depends on b.dart, because names defined in |
| 802 // b.dart are exported by a.dart. |
| 803 checkHasDependency('file:///a/b/b.dart', '/a/b/b.dart'); |
| 804 } |
| 805 |
| 806 test_dependencies_import_to_export_in_subdirs_absolute_import() { |
| 807 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 808 addNamedSource('/a/b/b.dart', 'library b;'); |
| 809 serializeLibraryText('import "/a/a.dart"; A a;'); |
| 810 checkHasDependency('file:///a/a.dart', '/a/a.dart'); |
| 811 // The main test library depends on b.dart, because names defined in |
| 812 // b.dart are exported by a.dart. |
| 813 checkHasDependency('file:///a/b/b.dart', '/a/b/b.dart'); |
| 814 } |
| 815 |
| 816 test_dependencies_import_to_export_in_subdirs_relative() { |
| 817 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 818 addNamedSource('/a/b/b.dart', 'library b;'); |
| 819 serializeLibraryText('import "a/a.dart"; A a;'); |
| 820 checkHasDependency('file:///a/a.dart', 'a/a.dart'); |
| 821 // The main test library depends on b.dart, because names defined in |
| 822 // b.dart are exported by a.dart. |
| 823 checkHasDependency('file:///a/b/b.dart', 'a/b/b.dart'); |
| 824 } |
| 825 |
| 826 test_dependencies_import_to_export_loop() { |
| 827 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 828 addNamedSource('/b.dart', 'library b; export "a.dart";'); |
| 829 serializeLibraryText('import "a.dart"; A a;'); |
| 830 checkHasDependency('file:///a.dart', 'a.dart'); |
| 831 // Serialization should have been able to walk the transitive export |
| 832 // dependencies to b.dart without going into an infinite loop. |
| 833 checkHasDependency('file:///b.dart', 'b.dart'); |
| 834 } |
| 835 |
| 836 test_dependencies_import_to_export_transitive_closure() { |
| 837 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 838 addNamedSource('/b.dart', 'library b; export "c.dart";'); |
| 839 addNamedSource('/c.dart', 'library c;'); |
| 840 serializeLibraryText('import "a.dart"; A a;'); |
| 841 checkHasDependency('file:///a.dart', 'a.dart'); |
| 842 // The main test library depends on c.dart, because names defined in |
| 843 // c.dart are exported by b.dart and then re-exported by a.dart. |
| 844 checkHasDependency('file:///c.dart', 'c.dart'); |
| 845 } |
| 846 |
| 847 test_dependencies_import_transitive_closure() { |
| 848 addNamedSource( |
| 849 '/a.dart', 'library a; import "b.dart"; class A extends B {}'); |
| 850 addNamedSource('/b.dart', 'library b; class B {}'); |
| 851 serializeLibraryText('import "a.dart"; A a;'); |
| 852 checkHasDependency('file:///a.dart', 'a.dart'); |
| 853 // The main test library doesn't depend on b.dart, because no change to |
| 854 // b.dart can possibly affect the serialized element model for it. |
| 855 checkLacksDependency('file:///b.dart', 'b.dart'); |
| 856 } |
| 857 |
| 858 test_elements_in_part() { |
| 859 addNamedSource( |
| 860 '/part1.dart', |
| 861 ''' |
| 862 part of my.lib; |
| 863 |
| 864 class C {} |
| 865 enum E { v } |
| 866 var v; |
| 867 f() {} |
| 868 typedef F(); |
| 869 '''); |
| 870 serializeLibraryText('library my.lib; part "part1.dart";'); |
| 871 expect(findClass('C', failIfAbsent: true).unit, 1); |
| 872 expect(findEnum('E', failIfAbsent: true).unit, 1); |
| 873 expect(findVariable('v', failIfAbsent: true).unit, 1); |
| 874 expect(findExecutable('f', failIfAbsent: true).unit, 1); |
| 875 expect(findTypedef('F', failIfAbsent: true).unit, 1); |
| 876 } |
| 877 |
| 878 test_enum() { |
| 879 UnlinkedEnum e = serializeEnumText('enum E { v1 }'); |
| 880 expect(e.name, 'E'); |
| 881 expect(e.values, hasLength(1)); |
| 882 expect(e.values[0].name, 'v1'); |
| 883 expect(e.unit, 0); |
| 884 } |
| 885 |
| 886 test_enum_order() { |
| 887 UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }'); |
| 888 expect(e.values, hasLength(2)); |
| 889 expect(e.values[0].name, 'v1'); |
| 890 expect(e.values[1].name, 'v2'); |
| 891 } |
| 892 |
| 893 test_executable_abstract() { |
| 894 UnlinkedExecutable executable = |
| 895 serializeClassText('abstract class C { f(); }').executables[0]; |
| 896 expect(executable.isAbstract, isTrue); |
| 897 } |
| 898 |
| 899 test_executable_concrete() { |
| 900 UnlinkedExecutable executable = |
| 901 serializeClassText('abstract class C { f() {} }').executables[0]; |
| 902 expect(executable.isAbstract, isFalse); |
| 903 } |
| 904 |
| 905 test_executable_function() { |
| 906 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 907 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 908 expect(executable.unit, 0); |
| 909 } |
| 910 |
| 911 test_executable_getter() { |
| 912 UnlinkedExecutable executable = serializeExecutableText('int get f => 1;'); |
| 913 expect(executable.kind, UnlinkedExecutableKind.getter); |
| 914 expect(findVariable('f'), isNull); |
| 915 expect(findExecutable('f='), isNull); |
| 916 } |
| 917 |
| 918 test_executable_getter_type() { |
| 919 UnlinkedExecutable executable = serializeExecutableText('int get f => 1;'); |
| 920 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int'); |
| 921 expect(executable.parameters, isEmpty); |
| 922 } |
| 923 |
| 924 test_executable_getter_type_implicit() { |
| 925 UnlinkedExecutable executable = serializeExecutableText('get f => 1;'); |
| 926 checkDynamicTypeRef(executable.returnType); |
| 927 expect(executable.parameters, isEmpty); |
| 928 } |
| 929 |
| 930 test_executable_member_function() { |
| 931 UnlinkedExecutable executable = |
| 932 findExecutable('f', cls: serializeClassText('class C { f() {} }')); |
| 933 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 934 } |
| 935 |
| 936 test_executable_member_getter() { |
| 937 UnlinkedClass cls = serializeClassText('class C { int get f => 1; }'); |
| 938 UnlinkedExecutable executable = |
| 939 findExecutable('f', cls: cls, failIfAbsent: true); |
| 940 expect(executable.kind, UnlinkedExecutableKind.getter); |
| 941 expect(findVariable('f', cls: cls), isNull); |
| 942 expect(findExecutable('f=', cls: cls), isNull); |
| 943 } |
| 944 |
| 945 test_executable_member_setter() { |
| 946 UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }'); |
| 947 UnlinkedExecutable executable = |
| 948 findExecutable('f=', cls: cls, failIfAbsent: true); |
| 949 expect(executable.kind, UnlinkedExecutableKind.setter); |
| 950 expect(findVariable('f', cls: cls), isNull); |
| 951 expect(findExecutable('f', cls: cls), isNull); |
| 952 } |
| 953 |
| 954 test_executable_name() { |
| 955 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 956 expect(executable.name, 'f'); |
| 957 } |
| 958 |
| 959 test_executable_no_flags() { |
| 960 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 961 expect(executable.isAbstract, isFalse); |
| 962 expect(executable.isConst, isFalse); |
| 963 expect(executable.isFactory, isFalse); |
| 964 expect(executable.isStatic, isFalse); |
| 965 } |
| 966 |
| 967 test_executable_non_static() { |
| 968 UnlinkedExecutable executable = |
| 969 serializeClassText('class C { f() {} }').executables[0]; |
| 970 expect(executable.isStatic, isFalse); |
| 971 } |
| 972 |
| 973 test_executable_non_static_top_level() { |
| 974 // Top level executables are considered non-static. |
| 975 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 976 expect(executable.isStatic, isFalse); |
| 977 } |
| 978 |
| 979 test_executable_param_function_typed() { |
| 980 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 981 expect(executable.parameters[0].isFunctionTyped, isTrue); |
| 982 } |
| 983 |
| 984 test_executable_param_function_typed_param() { |
| 985 UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}'); |
| 986 expect(executable.parameters[0].parameters, hasLength(1)); |
| 987 } |
| 988 |
| 989 test_executable_param_function_typed_param_none() { |
| 990 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 991 expect(executable.parameters[0].parameters, isEmpty); |
| 992 } |
| 993 |
| 994 test_executable_param_function_typed_param_order() { |
| 995 UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}'); |
| 996 expect(executable.parameters[0].parameters, hasLength(2)); |
| 997 expect(executable.parameters[0].parameters[0].name, 'x'); |
| 998 expect(executable.parameters[0].parameters[1].name, 'y'); |
| 999 } |
| 1000 |
| 1001 test_executable_param_function_typed_return_type() { |
| 1002 UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}'); |
| 1003 checkTypeRef( |
| 1004 executable.parameters[0].type, 'dart:core', 'dart:core', 'int'); |
| 1005 } |
| 1006 |
| 1007 test_executable_param_function_typed_return_type_implicit() { |
| 1008 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 1009 checkDynamicTypeRef(executable.parameters[0].type); |
| 1010 } |
| 1011 |
| 1012 test_executable_param_function_typed_return_type_void() { |
| 1013 UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}'); |
| 1014 expect(executable.parameters[0].type, isNull); |
| 1015 } |
| 1016 |
| 1017 test_executable_param_kind_named() { |
| 1018 UnlinkedExecutable executable = serializeExecutableText('f({x}) {}'); |
| 1019 expect(executable.parameters[0].kind, UnlinkedParamKind.named); |
| 1020 } |
| 1021 |
| 1022 test_executable_param_kind_positional() { |
| 1023 UnlinkedExecutable executable = serializeExecutableText('f([x]) {}'); |
| 1024 expect(executable.parameters[0].kind, UnlinkedParamKind.positional); |
| 1025 } |
| 1026 |
| 1027 test_executable_param_kind_required() { |
| 1028 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 1029 expect(executable.parameters[0].kind, UnlinkedParamKind.required); |
| 1030 } |
| 1031 |
| 1032 test_executable_param_name() { |
| 1033 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 1034 expect(executable.parameters, hasLength(1)); |
| 1035 expect(executable.parameters[0].name, 'x'); |
| 1036 } |
| 1037 |
| 1038 test_executable_param_no_flags() { |
| 1039 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 1040 expect(executable.parameters[0].isFunctionTyped, isFalse); |
| 1041 expect(executable.parameters[0].isInitializingFormal, isFalse); |
| 1042 } |
| 1043 |
| 1044 test_executable_param_non_function_typed() { |
| 1045 UnlinkedExecutable executable = serializeExecutableText('f(g) {}'); |
| 1046 expect(executable.parameters[0].isFunctionTyped, isFalse); |
| 1047 } |
| 1048 |
| 1049 test_executable_param_none() { |
| 1050 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 1051 expect(executable.parameters, isEmpty); |
| 1052 } |
| 1053 |
| 1054 test_executable_param_order() { |
| 1055 UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}'); |
| 1056 expect(executable.parameters, hasLength(2)); |
| 1057 expect(executable.parameters[0].name, 'x'); |
| 1058 expect(executable.parameters[1].name, 'y'); |
| 1059 } |
| 1060 |
| 1061 test_executable_param_type_implicit() { |
| 1062 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 1063 checkDynamicTypeRef(executable.parameters[0].type); |
| 1064 } |
| 1065 |
| 1066 test_executable_return_type() { |
| 1067 UnlinkedExecutable executable = serializeExecutableText('int f() => 1;'); |
| 1068 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int'); |
| 1069 } |
| 1070 |
| 1071 test_executable_return_type_implicit() { |
| 1072 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 1073 checkDynamicTypeRef(executable.returnType); |
| 1074 } |
| 1075 |
| 1076 test_executable_return_type_void() { |
| 1077 UnlinkedExecutable executable = serializeExecutableText('void f() {}'); |
| 1078 expect(executable.returnType, isNull); |
| 1079 } |
| 1080 |
| 1081 test_executable_setter() { |
| 1082 UnlinkedExecutable executable = |
| 1083 serializeExecutableText('void set f(value) {}', 'f='); |
| 1084 expect(executable.kind, UnlinkedExecutableKind.setter); |
| 1085 expect(findVariable('f'), isNull); |
| 1086 expect(findExecutable('f'), isNull); |
| 1087 } |
| 1088 |
| 1089 test_executable_setter_type() { |
| 1090 UnlinkedExecutable executable = |
| 1091 serializeExecutableText('void set f(int value) {}', 'f='); |
| 1092 expect(executable.returnType, isNull); |
| 1093 expect(executable.parameters, hasLength(1)); |
| 1094 expect(executable.parameters[0].name, 'value'); |
| 1095 checkTypeRef( |
| 1096 executable.parameters[0].type, 'dart:core', 'dart:core', 'int'); |
| 1097 } |
| 1098 |
| 1099 test_executable_static() { |
| 1100 UnlinkedExecutable executable = |
| 1101 serializeClassText('class C { static f() {} }').executables[0]; |
| 1102 expect(executable.isStatic, isTrue); |
| 1103 } |
| 1104 |
| 1105 test_export_hide_order() { |
| 1106 serializeLibraryText('export "dart:async" hide Future, Stream;'); |
| 1107 expect(unlinked.exports, hasLength(1)); |
| 1108 expect(unlinked.exports[0].combinators, hasLength(1)); |
| 1109 expect(unlinked.exports[0].combinators[0].shows, isEmpty); |
| 1110 expect(unlinked.exports[0].combinators[0].hides, hasLength(2)); |
| 1111 checkCombinatorName(unlinked.exports[0].combinators[0].hides[0], 'Future'); |
| 1112 checkCombinatorName(unlinked.exports[0].combinators[0].hides[1], 'Stream'); |
| 1113 } |
| 1114 |
| 1115 test_export_no_combinators() { |
| 1116 serializeLibraryText('export "dart:async";'); |
| 1117 expect(unlinked.exports, hasLength(1)); |
| 1118 expect(unlinked.exports[0].combinators, isEmpty); |
| 1119 } |
| 1120 |
| 1121 test_export_show_order() { |
| 1122 serializeLibraryText('export "dart:async" show Future, Stream;'); |
| 1123 expect(unlinked.exports, hasLength(1)); |
| 1124 expect(unlinked.exports[0].combinators, hasLength(1)); |
| 1125 expect(unlinked.exports[0].combinators[0].shows, hasLength(2)); |
| 1126 expect(unlinked.exports[0].combinators[0].hides, isEmpty); |
| 1127 checkCombinatorName(unlinked.exports[0].combinators[0].shows[0], 'Future'); |
| 1128 checkCombinatorName(unlinked.exports[0].combinators[0].shows[1], 'Stream'); |
| 1129 } |
| 1130 |
| 1131 test_export_uri() { |
| 1132 addNamedSource('/a.dart', 'library my.lib;'); |
| 1133 String uriString = '"a.dart"'; |
| 1134 String libraryText = 'export $uriString;'; |
| 1135 serializeLibraryText(libraryText); |
| 1136 expect(unlinked.exports, hasLength(1)); |
| 1137 expect(unlinked.exports[0].uri, 'a.dart'); |
| 1138 } |
| 1139 |
| 1140 test_field() { |
| 1141 UnlinkedClass cls = serializeClassText('class C { int i; }'); |
| 1142 expect(findVariable('i', cls: cls), isNotNull); |
| 1143 expect(findExecutable('i', cls: cls), isNull); |
| 1144 expect(findExecutable('i=', cls: cls), isNull); |
| 1145 } |
| 1146 |
| 1147 test_field_final() { |
| 1148 UnlinkedVariable variable = |
| 1149 serializeClassText('class C { final int i = 0; }').fields[0]; |
| 1150 expect(variable.isFinal, isTrue); |
| 1151 } |
| 1152 |
| 1153 test_field_non_final() { |
| 1154 UnlinkedVariable variable = |
| 1155 serializeClassText('class C { int i; }').fields[0]; |
| 1156 expect(variable.isFinal, isFalse); |
| 1157 } |
| 1158 |
| 1159 test_import_deferred() { |
| 1160 serializeLibraryText( |
| 1161 'import "dart:async" deferred as a; main() { print(a.Future); }'); |
| 1162 expect(unlinked.imports[0].isDeferred, isTrue); |
| 1163 } |
| 1164 |
| 1165 test_import_dependency() { |
| 1166 serializeLibraryText('import "dart:async"; Future x;'); |
| 1167 // Second import is the implicit import of dart:core |
| 1168 expect(unlinked.imports, hasLength(2)); |
| 1169 checkDependency(lib.importDependencies[0], 'dart:async', 'dart:async'); |
| 1170 } |
| 1171 |
| 1172 test_import_explicit() { |
| 1173 serializeLibraryText('import "dart:core"; int i;'); |
| 1174 expect(unlinked.imports, hasLength(1)); |
| 1175 expect(unlinked.imports[0].isImplicit, isFalse); |
| 1176 } |
| 1177 |
| 1178 test_import_hide_order() { |
| 1179 serializeLibraryText( |
| 1180 'import "dart:async" hide Future, Stream; Completer c;'); |
| 1181 // Second import is the implicit import of dart:core |
| 1182 expect(unlinked.imports, hasLength(2)); |
| 1183 expect(unlinked.imports[0].combinators, hasLength(1)); |
| 1184 expect(unlinked.imports[0].combinators[0].shows, isEmpty); |
| 1185 expect(unlinked.imports[0].combinators[0].hides, hasLength(2)); |
| 1186 checkCombinatorName(unlinked.imports[0].combinators[0].hides[0], 'Future'); |
| 1187 checkCombinatorName(unlinked.imports[0].combinators[0].hides[1], 'Stream'); |
| 1188 } |
| 1189 |
| 1190 test_import_implicit() { |
| 1191 // The implicit import of dart:core is represented in the model. |
| 1192 serializeLibraryText(''); |
| 1193 expect(unlinked.imports, hasLength(1)); |
| 1194 checkDependency(lib.importDependencies[0], 'dart:core', 'dart:core'); |
| 1195 expect(unlinked.imports[0].uri, isEmpty); |
| 1196 expect(unlinked.imports[0].prefix, 0); |
| 1197 expect(unlinked.imports[0].combinators, isEmpty); |
| 1198 expect(unlinked.imports[0].isImplicit, isTrue); |
| 1199 } |
| 1200 |
| 1201 test_import_no_combinators() { |
| 1202 serializeLibraryText('import "dart:async"; Future x;'); |
| 1203 // Second import is the implicit import of dart:core |
| 1204 expect(unlinked.imports, hasLength(2)); |
| 1205 expect(unlinked.imports[0].combinators, isEmpty); |
| 1206 } |
| 1207 |
| 1208 test_import_no_flags() { |
| 1209 serializeLibraryText('import "dart:async"; Future x;'); |
| 1210 expect(unlinked.imports[0].isImplicit, isFalse); |
| 1211 expect(unlinked.imports[0].isDeferred, isFalse); |
| 1212 } |
| 1213 |
| 1214 test_import_non_deferred() { |
| 1215 serializeLibraryText( |
| 1216 'import "dart:async" as a; main() { print(a.Future); }'); |
| 1217 expect(unlinked.imports[0].isDeferred, isFalse); |
| 1218 } |
| 1219 |
| 1220 test_import_of_file_with_missing_part() { |
| 1221 // Other references in foo.dart should be resolved even though foo.dart's |
| 1222 // part declaration for bar.dart refers to a non-existent file. |
| 1223 addNamedSource('/foo.dart', 'part "bar.dart"; class C {}'); |
| 1224 serializeLibraryText('import "foo.dart"; C x;'); |
| 1225 checkTypeRef(findVariable('x').type, 'file:///foo.dart', 'foo.dart', 'C'); |
| 1226 } |
| 1227 |
| 1228 test_import_of_missing_export() { |
| 1229 // Other references in foo.dart should be resolved even though foo.dart's |
| 1230 // re-export of bar.dart refers to a non-existent file. |
| 1231 addNamedSource('/foo.dart', 'export "bar.dart"; class C {}'); |
| 1232 serializeLibraryText('import "foo.dart"; C x;'); |
| 1233 checkTypeRef(findVariable('x').type, 'file:///foo.dart', 'foo.dart', 'C'); |
| 1234 } |
| 1235 |
| 1236 test_import_offset() { |
| 1237 String libraryText = ' import "dart:async"; Future x;'; |
| 1238 serializeLibraryText(libraryText); |
| 1239 expect(unlinked.imports[0].offset, libraryText.indexOf('import')); |
| 1240 } |
| 1241 |
| 1242 test_import_prefix_name() { |
| 1243 String libraryText = 'import "dart:async" as a; a.Future x;'; |
| 1244 serializeLibraryText(libraryText); |
| 1245 // Second import is the implicit import of dart:core |
| 1246 expect(unlinked.imports, hasLength(2)); |
| 1247 expect(unlinked.imports[0].prefix, isNot(0)); |
| 1248 expect(unlinked.prefixes[unlinked.imports[0].prefix].name, 'a'); |
| 1249 } |
| 1250 |
| 1251 test_import_prefix_none() { |
| 1252 serializeLibraryText('import "dart:async"; Future x;'); |
| 1253 // Second import is the implicit import of dart:core |
| 1254 expect(unlinked.imports, hasLength(2)); |
| 1255 expect(unlinked.imports[0].prefix, 0); |
| 1256 expect(unlinked.prefixes[unlinked.imports[0].prefix].name, isEmpty); |
| 1257 } |
| 1258 |
| 1259 test_import_prefix_reference() { |
| 1260 UnlinkedVariable variable = |
| 1261 serializeVariableText('import "dart:async" as a; a.Future v;'); |
| 1262 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', |
| 1263 expectedPrefix: 'a'); |
| 1264 } |
| 1265 |
| 1266 test_import_reference() { |
| 1267 UnlinkedVariable variable = |
| 1268 serializeVariableText('import "dart:async"; Future v;'); |
| 1269 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future'); |
| 1270 } |
| 1271 |
| 1272 test_import_reference_merged_no_prefix() { |
| 1273 serializeLibraryText(''' |
| 1274 import "dart:async" show Future; |
| 1275 import "dart:async" show Stream; |
| 1276 |
| 1277 Future f; |
| 1278 Stream s; |
| 1279 '''); |
| 1280 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future'); |
| 1281 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream'); |
| 1282 } |
| 1283 |
| 1284 test_import_reference_merged_prefixed() { |
| 1285 serializeLibraryText(''' |
| 1286 import "dart:async" as a show Future; |
| 1287 import "dart:async" as a show Stream; |
| 1288 |
| 1289 a.Future f; |
| 1290 a.Stream s; |
| 1291 '''); |
| 1292 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future', |
| 1293 expectedPrefix: 'a'); |
| 1294 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream', |
| 1295 expectedPrefix: 'a'); |
| 1296 } |
| 1297 |
| 1298 test_import_show_order() { |
| 1299 // TODO(paulberry): test cascaded shows/hides. |
| 1300 String libraryText = |
| 1301 'import "dart:async" show Future, Stream; Future x; Stream y;'; |
| 1302 serializeLibraryText(libraryText); |
| 1303 // Second import is the implicit import of dart:core |
| 1304 expect(unlinked.imports, hasLength(2)); |
| 1305 expect(unlinked.imports[0].combinators, hasLength(1)); |
| 1306 expect(unlinked.imports[0].combinators[0].shows, hasLength(2)); |
| 1307 expect(unlinked.imports[0].combinators[0].hides, isEmpty); |
| 1308 checkCombinatorName(unlinked.imports[0].combinators[0].shows[0], 'Future'); |
| 1309 checkCombinatorName(unlinked.imports[0].combinators[0].shows[1], 'Stream'); |
| 1310 } |
| 1311 |
| 1312 test_import_uri() { |
| 1313 String uriString = '"dart:async"'; |
| 1314 String libraryText = 'import $uriString; Future x;'; |
| 1315 serializeLibraryText(libraryText); |
| 1316 // Second import is the implicit import of dart:core |
| 1317 expect(unlinked.imports, hasLength(2)); |
| 1318 expect(unlinked.imports[0].uri, 'dart:async'); |
| 1319 } |
| 1320 |
| 1321 test_library_named() { |
| 1322 String text = 'library foo.bar;'; |
| 1323 serializeLibraryText(text); |
| 1324 expect(unlinked.name, 'foo.bar'); |
| 1325 } |
| 1326 |
| 1327 test_library_unnamed() { |
| 1328 serializeLibraryText(''); |
| 1329 expect(unlinked.name, isEmpty); |
| 1330 } |
| 1331 |
| 1332 test_nested_elements_have_no_part() { |
| 1333 addNamedSource( |
| 1334 '/part1.dart', |
| 1335 ''' |
| 1336 part of my.lib; |
| 1337 |
| 1338 class C { |
| 1339 var v; |
| 1340 f() {} |
| 1341 } |
| 1342 '''); |
| 1343 serializeLibraryText('library my.lib; part "part1.dart";'); |
| 1344 UnlinkedClass cls = findClass('C'); |
| 1345 expect(findVariable('v', cls: cls).unit, 0); |
| 1346 expect(findExecutable('f', cls: cls).unit, 0); |
| 1347 } |
| 1348 |
| 1349 test_parts_defining_compilation_unit() { |
| 1350 serializeLibraryText(''); |
| 1351 expect(unlinked.units, hasLength(1)); |
| 1352 expect(unlinked.units[0].uri, isEmpty); |
| 1353 } |
| 1354 |
| 1355 test_parts_included() { |
| 1356 addNamedSource('/part1.dart', 'part of my.lib;'); |
| 1357 String partString = '"part1.dart"'; |
| 1358 String libraryText = 'library my.lib; part $partString;'; |
| 1359 serializeLibraryText(libraryText); |
| 1360 expect(unlinked.units, hasLength(2)); |
| 1361 expect(unlinked.units[1].uri, 'part1.dart'); |
| 1362 } |
| 1363 |
| 1364 test_type_arguments_explicit() { |
| 1365 UnlinkedTypeRef typeRef = serializeTypeText('List<int>'); |
| 1366 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 1367 allowTypeParameters: true); |
| 1368 expect(typeRef.typeArguments, hasLength(1)); |
| 1369 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1370 } |
| 1371 |
| 1372 test_type_arguments_explicit_dynamic() { |
| 1373 UnlinkedTypeRef typeRef = serializeTypeText('List<dynamic>'); |
| 1374 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 1375 allowTypeParameters: true); |
| 1376 expect(typeRef.typeArguments, isEmpty); |
| 1377 } |
| 1378 |
| 1379 test_type_arguments_explicit_dynamic_typedef() { |
| 1380 UnlinkedTypeRef typeRef = |
| 1381 serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();'); |
| 1382 checkTypeRef(typeRef, null, null, 'F', |
| 1383 allowTypeParameters: true, |
| 1384 expectedKind: PrelinkedReferenceKind.typedef); |
| 1385 expect(typeRef.typeArguments, isEmpty); |
| 1386 } |
| 1387 |
| 1388 test_type_arguments_explicit_typedef() { |
| 1389 UnlinkedTypeRef typeRef = |
| 1390 serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();'); |
| 1391 checkTypeRef(typeRef, null, null, 'F', |
| 1392 allowTypeParameters: true, |
| 1393 expectedKind: PrelinkedReferenceKind.typedef); |
| 1394 expect(typeRef.typeArguments, hasLength(1)); |
| 1395 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1396 } |
| 1397 |
| 1398 test_type_arguments_implicit() { |
| 1399 UnlinkedTypeRef typeRef = serializeTypeText('List'); |
| 1400 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 1401 allowTypeParameters: true); |
| 1402 expect(typeRef.typeArguments, isEmpty); |
| 1403 } |
| 1404 |
| 1405 test_type_arguments_implicit_typedef() { |
| 1406 UnlinkedTypeRef typeRef = |
| 1407 serializeTypeText('F', otherDeclarations: 'typedef T F<T>();'); |
| 1408 checkTypeRef(typeRef, null, null, 'F', |
| 1409 allowTypeParameters: true, |
| 1410 expectedKind: PrelinkedReferenceKind.typedef); |
| 1411 expect(typeRef.typeArguments, isEmpty); |
| 1412 } |
| 1413 |
| 1414 test_type_arguments_order() { |
| 1415 UnlinkedTypeRef typeRef = serializeTypeText('Map<int, Object>'); |
| 1416 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 1417 allowTypeParameters: true); |
| 1418 expect(typeRef.typeArguments, hasLength(2)); |
| 1419 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1420 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object'); |
| 1421 } |
| 1422 |
| 1423 test_type_dynamic() { |
| 1424 checkDynamicTypeRef(serializeTypeText('dynamic')); |
| 1425 } |
| 1426 |
| 1427 test_type_reference_to_class_argument() { |
| 1428 UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }'); |
| 1429 { |
| 1430 UnlinkedTypeRef typeRef = |
| 1431 findVariable('t', cls: cls, failIfAbsent: true).type; |
| 1432 checkParamTypeRef(typeRef, 2); |
| 1433 } |
| 1434 { |
| 1435 UnlinkedTypeRef typeRef = |
| 1436 findVariable('u', cls: cls, failIfAbsent: true).type; |
| 1437 checkParamTypeRef(typeRef, 1); |
| 1438 } |
| 1439 } |
| 1440 |
| 1441 test_type_reference_to_import_of_export() { |
| 1442 addNamedSource('/a.dart', 'library a; export "b.dart";'); |
| 1443 addNamedSource('/b.dart', 'library b; class C {}'); |
| 1444 checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'), |
| 1445 'file:///b.dart', 'b.dart', 'C'); |
| 1446 } |
| 1447 |
| 1448 test_type_reference_to_import_of_export_via_prefix() { |
| 1449 addNamedSource('/a.dart', 'library a; export "b.dart";'); |
| 1450 addNamedSource('/b.dart', 'library b; class C {}'); |
| 1451 checkTypeRef( |
| 1452 serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'), |
| 1453 'file:///b.dart', |
| 1454 'b.dart', |
| 1455 'C', |
| 1456 expectedPrefix: 'p'); |
| 1457 } |
| 1458 |
| 1459 test_type_reference_to_imported_part() { |
| 1460 addNamedSource('/a.dart', 'library my.lib; part "b.dart";'); |
| 1461 addNamedSource('/b.dart', 'part of my.lib; class C {}'); |
| 1462 checkTypeRef( |
| 1463 serializeTypeText('C', |
| 1464 otherDeclarations: 'library my.lib; import "a.dart";'), |
| 1465 'file:///a.dart', |
| 1466 'a.dart', |
| 1467 'C'); |
| 1468 } |
| 1469 |
| 1470 test_type_reference_to_imported_part_with_prefix() { |
| 1471 addNamedSource('/a.dart', 'library my.lib; part "b.dart";'); |
| 1472 addNamedSource('/b.dart', 'part of my.lib; class C {}'); |
| 1473 checkTypeRef( |
| 1474 serializeTypeText('p.C', |
| 1475 otherDeclarations: 'library my.lib; import "a.dart" as p;'), |
| 1476 'file:///a.dart', |
| 1477 'a.dart', |
| 1478 'C', |
| 1479 expectedPrefix: 'p'); |
| 1480 } |
| 1481 |
| 1482 test_type_reference_to_internal_class() { |
| 1483 checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null, |
| 1484 null, 'C'); |
| 1485 } |
| 1486 |
| 1487 test_type_reference_to_internal_class_alias() { |
| 1488 checkTypeRef( |
| 1489 serializeTypeText('C', |
| 1490 otherDeclarations: 'class C = D with E; class D {} class E {}'), |
| 1491 null, |
| 1492 null, |
| 1493 'C'); |
| 1494 } |
| 1495 |
| 1496 test_type_reference_to_internal_enum() { |
| 1497 checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'), |
| 1498 null, null, 'E'); |
| 1499 } |
| 1500 |
| 1501 test_type_reference_to_local_part() { |
| 1502 addNamedSource('/a.dart', 'part of my.lib; class C {}'); |
| 1503 checkTypeRef( |
| 1504 serializeTypeText('C', |
| 1505 otherDeclarations: 'library my.lib; part "a.dart";'), |
| 1506 null, |
| 1507 null, |
| 1508 'C'); |
| 1509 } |
| 1510 |
| 1511 test_type_reference_to_nonexistent_file_via_prefix() { |
| 1512 UnlinkedTypeRef typeRef = serializeTypeText('p.C', |
| 1513 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); |
| 1514 checkUnresolvedTypeRef(typeRef, 'p', 'C'); |
| 1515 } |
| 1516 |
| 1517 test_type_reference_to_typedef() { |
| 1518 checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'), |
| 1519 null, null, 'F', |
| 1520 expectedKind: PrelinkedReferenceKind.typedef); |
| 1521 } |
| 1522 |
| 1523 test_type_unit_counts_unreferenced_units() { |
| 1524 addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";'); |
| 1525 addNamedSource('/b.dart', 'part of a;'); |
| 1526 addNamedSource('/c.dart', 'part of a; class C {}'); |
| 1527 UnlinkedTypeRef typeRef = |
| 1528 serializeTypeText('C', otherDeclarations: 'import "a.dart";'); |
| 1529 // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is |
| 1530 // b.dart. a.dart and b.dart are counted even though nothing is imported |
| 1531 // from them. |
| 1532 checkTypeRef(typeRef, 'file:///a.dart', 'a.dart', 'C'); |
| 1533 } |
| 1534 |
| 1535 test_type_unresolved() { |
| 1536 UnlinkedTypeRef typeRef = serializeTypeText('Foo', allowErrors: true); |
| 1537 checkUnresolvedTypeRef(typeRef, null, 'Foo'); |
| 1538 } |
| 1539 |
| 1540 test_typedef_name() { |
| 1541 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 1542 expect(type.name, 'F'); |
| 1543 expect(type.unit, 0); |
| 1544 } |
| 1545 |
| 1546 test_typedef_param_none() { |
| 1547 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 1548 expect(type.parameters, isEmpty); |
| 1549 } |
| 1550 |
| 1551 test_typedef_param_order() { |
| 1552 UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);'); |
| 1553 expect(type.parameters, hasLength(2)); |
| 1554 expect(type.parameters[0].name, 'x'); |
| 1555 expect(type.parameters[1].name, 'y'); |
| 1556 } |
| 1557 |
| 1558 test_typedef_return_type_explicit() { |
| 1559 UnlinkedTypedef type = serializeTypedefText('typedef int F();'); |
| 1560 checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int'); |
| 1561 } |
| 1562 |
| 1563 test_typedef_type_param_in_parameter() { |
| 1564 UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);'); |
| 1565 checkParamTypeRef(type.parameters[0].type, 1); |
| 1566 } |
| 1567 |
| 1568 test_typedef_type_param_in_return_type() { |
| 1569 UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();'); |
| 1570 checkParamTypeRef(type.returnType, 1); |
| 1571 } |
| 1572 |
| 1573 test_typedef_type_param_none() { |
| 1574 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 1575 expect(type.typeParameters, isEmpty); |
| 1576 } |
| 1577 |
| 1578 test_typedef_type_param_order() { |
| 1579 UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();'); |
| 1580 expect(type.typeParameters, hasLength(2)); |
| 1581 expect(type.typeParameters[0].name, 'T'); |
| 1582 expect(type.typeParameters[1].name, 'U'); |
| 1583 } |
| 1584 |
| 1585 test_variable() { |
| 1586 serializeVariableText('int i;', variableName: 'i'); |
| 1587 expect(findExecutable('i'), isNull); |
| 1588 expect(findExecutable('i='), isNull); |
| 1589 } |
| 1590 |
| 1591 test_variable_const() { |
| 1592 UnlinkedVariable variable = |
| 1593 serializeVariableText('const int i = 0;', variableName: 'i'); |
| 1594 expect(variable.isConst, isTrue); |
| 1595 } |
| 1596 |
| 1597 test_variable_final_top_level() { |
| 1598 UnlinkedVariable variable = |
| 1599 serializeVariableText('final int i = 0;', variableName: 'i'); |
| 1600 expect(variable.isFinal, isTrue); |
| 1601 } |
| 1602 |
| 1603 test_variable_implicit_dynamic() { |
| 1604 UnlinkedVariable variable = serializeVariableText('var v;'); |
| 1605 checkDynamicTypeRef(variable.type); |
| 1606 } |
| 1607 |
| 1608 test_variable_name() { |
| 1609 UnlinkedVariable variable = |
| 1610 serializeVariableText('int i;', variableName: 'i'); |
| 1611 expect(variable.name, 'i'); |
| 1612 expect(variable.unit, 0); |
| 1613 } |
| 1614 |
| 1615 test_variable_no_flags() { |
| 1616 UnlinkedVariable variable = |
| 1617 serializeVariableText('int i;', variableName: 'i'); |
| 1618 expect(variable.isStatic, isFalse); |
| 1619 expect(variable.isConst, isFalse); |
| 1620 expect(variable.isFinal, isFalse); |
| 1621 } |
| 1622 |
| 1623 test_variable_non_const() { |
| 1624 UnlinkedVariable variable = |
| 1625 serializeVariableText('int i = 0;', variableName: 'i'); |
| 1626 expect(variable.isConst, isFalse); |
| 1627 } |
| 1628 |
| 1629 test_variable_non_final() { |
| 1630 UnlinkedVariable variable = |
| 1631 serializeVariableText('int i;', variableName: 'i'); |
| 1632 expect(variable.isFinal, isFalse); |
| 1633 } |
| 1634 |
| 1635 test_variable_non_static() { |
| 1636 UnlinkedVariable variable = |
| 1637 serializeClassText('class C { int i; }').fields[0]; |
| 1638 expect(variable.isStatic, isFalse); |
| 1639 } |
| 1640 |
| 1641 test_variable_non_static_top_level() { |
| 1642 // Top level variables are considered non-static. |
| 1643 UnlinkedVariable variable = |
| 1644 serializeVariableText('int i;', variableName: 'i'); |
| 1645 expect(variable.isStatic, isFalse); |
| 1646 } |
| 1647 |
| 1648 test_variable_static() { |
| 1649 UnlinkedVariable variable = |
| 1650 serializeClassText('class C { static int i; }').fields[0]; |
| 1651 expect(variable.isStatic, isTrue); |
| 1652 } |
| 1653 |
| 1654 test_variable_type() { |
| 1655 UnlinkedVariable variable = |
| 1656 serializeVariableText('int i;', variableName: 'i'); |
| 1657 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); |
| 1658 } |
| 1659 } |
| OLD | NEW |