| 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 analyzer.test.src.summary.summary_common; |
| 6 |
| 7 import 'package:analyzer/analyzer.dart'; |
| 8 import 'package:analyzer/dart/ast/ast.dart'; |
| 9 import 'package:analyzer/error/listener.dart'; |
| 10 import 'package:analyzer/src/dart/scanner/reader.dart'; |
| 11 import 'package:analyzer/src/dart/scanner/scanner.dart'; |
| 12 import 'package:analyzer/src/generated/parser.dart'; |
| 13 import 'package:analyzer/src/generated/source.dart'; |
| 14 import 'package:analyzer/src/generated/source_io.dart'; |
| 15 import 'package:analyzer/src/summary/base.dart'; |
| 16 import 'package:analyzer/src/summary/idl.dart'; |
| 17 import 'package:analyzer/src/summary/public_namespace_computer.dart' |
| 18 as public_namespace; |
| 19 import 'package:path/path.dart' show posix; |
| 20 import 'package:unittest/unittest.dart'; |
| 21 |
| 22 import '../context/mock_sdk.dart'; |
| 23 |
| 24 /** |
| 25 * Convert the given Posix style file [path] to the corresponding absolute URI. |
| 26 */ |
| 27 String absUri(String path) { |
| 28 String absolutePath = posix.absolute(path); |
| 29 return posix.toUri(absolutePath).toString(); |
| 30 } |
| 31 |
| 32 /** |
| 33 * Convert a summary object (or a portion of one) into a canonical form that |
| 34 * can be easily compared using [expect]. If [orderByName] is true, and the |
| 35 * object is a [List], it is sorted by the `name` field of its elements. |
| 36 */ |
| 37 Object canonicalize(Object obj, {bool orderByName: false}) { |
| 38 if (obj is SummaryClass) { |
| 39 Map<String, Object> result = <String, Object>{}; |
| 40 obj.toMap().forEach((String key, Object value) { |
| 41 bool orderByName = false; |
| 42 if (obj is UnlinkedPublicNamespace && key == 'names' || |
| 43 obj is UnlinkedPublicName && key == 'members') { |
| 44 orderByName = true; |
| 45 } |
| 46 result[key] = canonicalize(value, orderByName: orderByName); |
| 47 }); |
| 48 return result; |
| 49 } else if (obj is List) { |
| 50 List<Object> result = <Object>[]; |
| 51 for (Object item in obj) { |
| 52 result.add(canonicalize(item)); |
| 53 } |
| 54 if (orderByName) { |
| 55 result.sort((Object a, Object b) { |
| 56 if (a is Map && b is Map) { |
| 57 return Comparable.compare(a['name'], b['name']); |
| 58 } else { |
| 59 return 0; |
| 60 } |
| 61 }); |
| 62 } |
| 63 return result; |
| 64 } else if (obj is String || obj is num || obj is bool) { |
| 65 return obj; |
| 66 } else { |
| 67 return obj.toString(); |
| 68 } |
| 69 } |
| 70 |
| 71 UnlinkedPublicNamespace computePublicNamespaceFromText( |
| 72 String text, Source source) { |
| 73 CharacterReader reader = new CharSequenceReader(text); |
| 74 Scanner scanner = |
| 75 new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER); |
| 76 Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER); |
| 77 parser.parseGenericMethods = true; |
| 78 CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize()); |
| 79 UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer( |
| 80 public_namespace.computePublicNamespace(unit).toBuffer()); |
| 81 return namespace; |
| 82 } |
| 83 |
| 84 /** |
| 85 * Type of a function that validates an [EntityRef]. |
| 86 */ |
| 87 typedef void _EntityRefValidator(EntityRef entityRef); |
| 88 |
| 89 /** |
| 90 * [SerializedMockSdk] is a singleton class representing the result of |
| 91 * serializing the mock SDK to summaries. It is computed once and then shared |
| 92 * among test invocations so that we don't bog down the tests. |
| 93 * |
| 94 * Note: should an exception occur during computation of [instance], it will |
| 95 * silently be set to null to allow other tests to complete quickly. |
| 96 */ |
| 97 class SerializedMockSdk { |
| 98 static final SerializedMockSdk instance = _serializeMockSdk(); |
| 99 |
| 100 final Map<String, UnlinkedUnit> uriToUnlinkedUnit; |
| 101 |
| 102 final Map<String, LinkedLibrary> uriToLinkedLibrary; |
| 103 SerializedMockSdk._(this.uriToUnlinkedUnit, this.uriToLinkedLibrary); |
| 104 |
| 105 static SerializedMockSdk _serializeMockSdk() { |
| 106 try { |
| 107 Map<String, UnlinkedUnit> uriToUnlinkedUnit = <String, UnlinkedUnit>{}; |
| 108 Map<String, LinkedLibrary> uriToLinkedLibrary = <String, LinkedLibrary>{}; |
| 109 PackageBundle bundle = new MockSdk().getLinkedBundle(); |
| 110 for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) { |
| 111 String uri = bundle.unlinkedUnitUris[i]; |
| 112 uriToUnlinkedUnit[uri] = bundle.unlinkedUnits[i]; |
| 113 } |
| 114 for (int i = 0; i < bundle.linkedLibraryUris.length; i++) { |
| 115 String uri = bundle.linkedLibraryUris[i]; |
| 116 uriToLinkedLibrary[uri] = bundle.linkedLibraries[i]; |
| 117 } |
| 118 return new SerializedMockSdk._(uriToUnlinkedUnit, uriToLinkedLibrary); |
| 119 } catch (_) { |
| 120 return null; |
| 121 } |
| 122 } |
| 123 } |
| 124 |
| 125 /** |
| 126 * Base class containing most summary tests. This allows summary tests to be |
| 127 * re-used to exercise all the different ways in which summaries can be |
| 128 * generated (e.g. direct from the AST, from the element model, from a |
| 129 * "relinking" process, etc.) |
| 130 */ |
| 131 abstract class SummaryTest { |
| 132 /** |
| 133 * A test will set this to `true` if it contains `import`, `export`, or |
| 134 * `part` declarations that deliberately refer to non-existent files. |
| 135 */ |
| 136 bool allowMissingFiles = false; |
| 137 |
| 138 /** |
| 139 * Get access to the linked defining compilation unit. |
| 140 */ |
| 141 LinkedUnit get definingUnit => linked.units[0]; |
| 142 |
| 143 /** |
| 144 * Get access to the linked summary that results from serializing and |
| 145 * then deserializing the library under test. |
| 146 */ |
| 147 LinkedLibrary get linked; |
| 148 |
| 149 /** |
| 150 * `true` if the linked portion of the summary only contains prelinked data. |
| 151 * This happens because we don't yet have a full linker; only a prelinker. |
| 152 */ |
| 153 bool get skipFullyLinkedData; |
| 154 |
| 155 /** |
| 156 * `true` if non-const variable initializers are not serialized. |
| 157 */ |
| 158 bool get skipNonConstInitializers; |
| 159 |
| 160 /** |
| 161 * `true` if the linked portion of the summary contains the result of strong |
| 162 * mode analysis. |
| 163 */ |
| 164 bool get strongMode; |
| 165 |
| 166 /** |
| 167 * Get access to the unlinked compilation unit summaries that result from |
| 168 * serializing and deserializing the library under test. |
| 169 */ |
| 170 List<UnlinkedUnit> get unlinkedUnits; |
| 171 |
| 172 /** |
| 173 * Add the given source file so that it may be referenced by the file under |
| 174 * test. |
| 175 */ |
| 176 Source addNamedSource(String filePath, String contents); |
| 177 |
| 178 /** |
| 179 * Check that [annotations] contains a single entry which is a reference to |
| 180 * a top level variable called `a` in the current library. |
| 181 */ |
| 182 void checkAnnotationA(List<UnlinkedConst> annotations) { |
| 183 expect(annotations, hasLength(1)); |
| 184 _assertUnlinkedConst(annotations[0], operators: [ |
| 185 UnlinkedConstOperation.pushReference |
| 186 ], referenceValidators: [ |
| 187 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 188 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 189 ]); |
| 190 } |
| 191 |
| 192 void checkConstCycle(String className, |
| 193 {String name: '', bool hasCycle: true}) { |
| 194 UnlinkedClass cls = findClass(className); |
| 195 int constCycleSlot = |
| 196 findExecutable(name, executables: cls.executables).constCycleSlot; |
| 197 expect(constCycleSlot, isNot(0)); |
| 198 if (!skipFullyLinkedData) { |
| 199 expect( |
| 200 definingUnit.constCycles, |
| 201 hasCycle |
| 202 ? contains(constCycleSlot) |
| 203 : isNot(contains(constCycleSlot))); |
| 204 } |
| 205 } |
| 206 |
| 207 /** |
| 208 * Verify that the [dependency]th element of the dependency table represents |
| 209 * a file reachable via the given [absoluteUri] and [relativeUri]. |
| 210 */ |
| 211 void checkDependency(int dependency, String absoluteUri, String relativeUri) { |
| 212 expect(dependency, new isInstanceOf<int>()); |
| 213 if (dependency >= linked.numPrelinkedDependencies) { |
| 214 // Fully-linked dependencies are always absolute URIs. |
| 215 expect(linked.dependencies[dependency].uri, absoluteUri); |
| 216 } else { |
| 217 expect(linked.dependencies[dependency].uri, relativeUri); |
| 218 } |
| 219 } |
| 220 |
| 221 /** |
| 222 * Verify that the given [dependency] lists the given |
| 223 * [relativeUris] as its parts. |
| 224 */ |
| 225 void checkDependencyParts( |
| 226 LinkedDependency dependency, List<String> relativeUris) { |
| 227 expect(dependency.parts, relativeUris); |
| 228 } |
| 229 |
| 230 /** |
| 231 * Check that the given [documentationComment] matches the first |
| 232 * Javadoc-style comment found in [text]. |
| 233 * |
| 234 * Note that the algorithm for finding the Javadoc-style comment in [text] is |
| 235 * a simple-minded text search; it is easily confused by corner cases such as |
| 236 * strings containing comments, nested comments, etc. |
| 237 */ |
| 238 void checkDocumentationComment( |
| 239 UnlinkedDocumentationComment documentationComment, String text) { |
| 240 expect(documentationComment, isNotNull); |
| 241 int commentStart = text.indexOf('/*'); |
| 242 expect(commentStart, isNot(-1)); |
| 243 int commentEnd = text.indexOf('*/'); |
| 244 expect(commentEnd, isNot(-1)); |
| 245 commentEnd += 2; |
| 246 String expectedCommentText = |
| 247 text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n'); |
| 248 expect(documentationComment.text, expectedCommentText); |
| 249 } |
| 250 |
| 251 /** |
| 252 * Verify that the given [typeRef] represents the type `dynamic`. |
| 253 */ |
| 254 void checkDynamicTypeRef(EntityRef typeRef) { |
| 255 checkTypeRef(typeRef, null, null, 'dynamic'); |
| 256 } |
| 257 |
| 258 /** |
| 259 * Verify that the given [exportName] represents a reference to an entity |
| 260 * declared in a file reachable via [absoluteUri] and [relativeUri], having |
| 261 * name [expectedName]. [expectedKind] is the kind of object referenced. |
| 262 * [expectedTargetUnit] is the index of the compilation unit in which the |
| 263 * target of the [exportName] is expected to appear; if not specified it is |
| 264 * assumed to be the defining compilation unit. |
| 265 */ |
| 266 void checkExportName(LinkedExportName exportName, String absoluteUri, |
| 267 String relativeUri, String expectedName, ReferenceKind expectedKind, |
| 268 {int expectedTargetUnit: 0}) { |
| 269 expect(exportName, new isInstanceOf<LinkedExportName>()); |
| 270 // Exported names must come from other libraries. |
| 271 expect(exportName.dependency, isNot(0)); |
| 272 checkDependency(exportName.dependency, absoluteUri, relativeUri); |
| 273 expect(exportName.name, expectedName); |
| 274 expect(exportName.kind, expectedKind); |
| 275 expect(exportName.unit, expectedTargetUnit); |
| 276 } |
| 277 |
| 278 /** |
| 279 * Verify that the dependency table contains an entry for a file reachable |
| 280 * via the given [relativeUri]. If [fullyLinked] is |
| 281 * `true`, then the dependency should be a fully-linked dependency; otherwise |
| 282 * it should be a prelinked dependency. |
| 283 * |
| 284 * The index of the [LinkedDependency] is returned. |
| 285 */ |
| 286 int checkHasDependency(String relativeUri, {bool fullyLinked: false}) { |
| 287 List<String> found = <String>[]; |
| 288 for (int i = 0; i < linked.dependencies.length; i++) { |
| 289 LinkedDependency dep = linked.dependencies[i]; |
| 290 if (dep.uri == relativeUri) { |
| 291 if (fullyLinked) { |
| 292 expect(i, greaterThanOrEqualTo(linked.numPrelinkedDependencies)); |
| 293 } else { |
| 294 expect(i, lessThan(linked.numPrelinkedDependencies)); |
| 295 } |
| 296 return i; |
| 297 } |
| 298 found.add(dep.uri); |
| 299 } |
| 300 fail('Did not find dependency $relativeUri. Found: $found'); |
| 301 return null; |
| 302 } |
| 303 |
| 304 /** |
| 305 * Test an inferred type. If [onlyInStrongMode] is `true` (the default) and |
| 306 * strong mode is disabled, verify that the given [slotId] exists and has no |
| 307 * associated type. Otherwise, behave as in [checkLinkedTypeSlot]. |
| 308 */ |
| 309 void checkInferredTypeSlot( |
| 310 int slotId, String absoluteUri, String relativeUri, String expectedName, |
| 311 {int numTypeArguments: 0, |
| 312 ReferenceKind expectedKind: ReferenceKind.classOrEnum, |
| 313 int expectedTargetUnit: 0, |
| 314 LinkedUnit linkedSourceUnit, |
| 315 UnlinkedUnit unlinkedSourceUnit, |
| 316 int numTypeParameters: 0, |
| 317 bool onlyInStrongMode: true}) { |
| 318 if (strongMode || !onlyInStrongMode) { |
| 319 checkLinkedTypeSlot(slotId, absoluteUri, relativeUri, expectedName, |
| 320 numTypeArguments: numTypeArguments, |
| 321 expectedKind: expectedKind, |
| 322 expectedTargetUnit: expectedTargetUnit, |
| 323 linkedSourceUnit: linkedSourceUnit, |
| 324 unlinkedSourceUnit: unlinkedSourceUnit, |
| 325 numTypeParameters: numTypeParameters); |
| 326 } else { |
| 327 // A slot id should have been assigned but it should not be associated |
| 328 // with any type. |
| 329 expect(slotId, isNot(0)); |
| 330 expect(getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit), |
| 331 isNull); |
| 332 } |
| 333 } |
| 334 |
| 335 /** |
| 336 * Verify that the dependency table *does not* contain any entries for a file |
| 337 * reachable via the given [relativeUri]. |
| 338 */ |
| 339 void checkLacksDependency(String relativeUri) { |
| 340 for (LinkedDependency dep in linked.dependencies) { |
| 341 if (dep.uri == relativeUri) { |
| 342 fail('Unexpected dependency found: $relativeUri'); |
| 343 } |
| 344 } |
| 345 } |
| 346 |
| 347 /** |
| 348 * Verify that the given [typeRef] represents the type `dynamic`. |
| 349 */ |
| 350 void checkLinkedDynamicTypeRef(EntityRef typeRef) { |
| 351 checkLinkedTypeRef(typeRef, null, null, 'dynamic'); |
| 352 } |
| 353 |
| 354 /** |
| 355 * Verify that the given [typeRef] represents a reference to a type declared |
| 356 * in a file reachable via [absoluteUri] and [relativeUri], having name |
| 357 * [expectedName]. Verify that the number of type arguments |
| 358 * is equal to [numTypeArguments]. [expectedKind] is the kind of object |
| 359 * referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the |
| 360 * compilation unit within which the [typeRef] appears; if not specified they |
| 361 * are assumed to refer to the defining compilation unit. |
| 362 * [expectedTargetUnit] is the index of the compilation unit in which the |
| 363 * target of the [typeRef] is expected to appear; if not specified it is |
| 364 * assumed to be the defining compilation unit. [numTypeParameters] is the |
| 365 * number of type parameters of the thing being referred to. |
| 366 */ |
| 367 void checkLinkedTypeRef(EntityRef typeRef, String absoluteUri, |
| 368 String relativeUri, String expectedName, |
| 369 {int numTypeArguments: 0, |
| 370 ReferenceKind expectedKind: ReferenceKind.classOrEnum, |
| 371 int expectedTargetUnit: 0, |
| 372 LinkedUnit linkedSourceUnit, |
| 373 UnlinkedUnit unlinkedSourceUnit, |
| 374 int numTypeParameters: 0}) { |
| 375 linkedSourceUnit ??= definingUnit; |
| 376 expect(typeRef, isNotNull, |
| 377 reason: 'No entry in linkedSourceUnit.types matching slotId'); |
| 378 expect(typeRef.paramReference, 0); |
| 379 int index = typeRef.reference; |
| 380 expect(typeRef.typeArguments, hasLength(numTypeArguments)); |
| 381 checkReferenceIndex(index, absoluteUri, relativeUri, expectedName, |
| 382 expectedKind: expectedKind, |
| 383 expectedTargetUnit: expectedTargetUnit, |
| 384 linkedSourceUnit: linkedSourceUnit, |
| 385 unlinkedSourceUnit: unlinkedSourceUnit, |
| 386 numTypeParameters: numTypeParameters); |
| 387 } |
| 388 |
| 389 /** |
| 390 * Verify that the given [slotId] represents a reference to a type declared |
| 391 * in a file reachable via [absoluteUri] and [relativeUri], having name |
| 392 * [expectedName]. Verify that the number of type arguments |
| 393 * is equal to [numTypeArguments]. [expectedKind] is the kind of object |
| 394 * referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the |
| 395 * compilation unit within which the [typeRef] appears; if not specified they |
| 396 * are assumed to refer to the defining compilation unit. |
| 397 * [expectedTargetUnit] is the index of the compilation unit in which the |
| 398 * target of the [typeRef] is expected to appear; if not specified it is |
| 399 * assumed to be the defining compilation unit. [numTypeParameters] is the |
| 400 * number of type parameters of the thing being referred to. |
| 401 */ |
| 402 void checkLinkedTypeSlot( |
| 403 int slotId, String absoluteUri, String relativeUri, String expectedName, |
| 404 {int numTypeArguments: 0, |
| 405 ReferenceKind expectedKind: ReferenceKind.classOrEnum, |
| 406 int expectedTargetUnit: 0, |
| 407 LinkedUnit linkedSourceUnit, |
| 408 UnlinkedUnit unlinkedSourceUnit, |
| 409 int numTypeParameters: 0}) { |
| 410 // Slot ids should be nonzero, since zero means "no associated slot". |
| 411 expect(slotId, isNot(0)); |
| 412 if (skipFullyLinkedData) { |
| 413 return; |
| 414 } |
| 415 linkedSourceUnit ??= definingUnit; |
| 416 checkLinkedTypeRef( |
| 417 getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit), |
| 418 absoluteUri, |
| 419 relativeUri, |
| 420 expectedName, |
| 421 numTypeArguments: numTypeArguments, |
| 422 expectedKind: expectedKind, |
| 423 expectedTargetUnit: expectedTargetUnit, |
| 424 linkedSourceUnit: linkedSourceUnit, |
| 425 unlinkedSourceUnit: unlinkedSourceUnit, |
| 426 numTypeParameters: numTypeParameters); |
| 427 } |
| 428 |
| 429 /** |
| 430 * Verify that the given [typeRef] represents a reference to a type parameter |
| 431 * having the given [deBruijnIndex]. |
| 432 */ |
| 433 void checkParamTypeRef(EntityRef typeRef, int deBruijnIndex) { |
| 434 expect(typeRef, new isInstanceOf<EntityRef>()); |
| 435 expect(typeRef.reference, 0); |
| 436 expect(typeRef.typeArguments, isEmpty); |
| 437 expect(typeRef.paramReference, deBruijnIndex); |
| 438 } |
| 439 |
| 440 /** |
| 441 * Verify that [prefixReference] is a valid reference to a prefix having the |
| 442 * given [name]. |
| 443 */ |
| 444 void checkPrefix(int prefixReference, String name) { |
| 445 expect(prefixReference, isNot(0)); |
| 446 expect(unlinkedUnits[0].references[prefixReference].prefixReference, 0); |
| 447 expect(unlinkedUnits[0].references[prefixReference].name, name); |
| 448 expect(definingUnit.references[prefixReference].dependency, 0); |
| 449 expect(definingUnit.references[prefixReference].kind, ReferenceKind.prefix); |
| 450 expect(definingUnit.references[prefixReference].unit, 0); |
| 451 } |
| 452 |
| 453 /** |
| 454 * Check the data structures that are reachable from an index in the |
| 455 * references table.. If the reference in question is an explicit |
| 456 * reference, return the [UnlinkedReference] that is used to make the |
| 457 * explicit reference. If the type reference in question is an implicit |
| 458 * reference, return `null`. |
| 459 */ |
| 460 UnlinkedReference checkReferenceIndex(int referenceIndex, String absoluteUri, |
| 461 String relativeUri, String expectedName, |
| 462 {ReferenceKind expectedKind: ReferenceKind.classOrEnum, |
| 463 int expectedTargetUnit: 0, |
| 464 LinkedUnit linkedSourceUnit, |
| 465 UnlinkedUnit unlinkedSourceUnit, |
| 466 int numTypeParameters: 0, |
| 467 int localIndex: 0, |
| 468 bool unresolvedHasName: false}) { |
| 469 linkedSourceUnit ??= definingUnit; |
| 470 unlinkedSourceUnit ??= unlinkedUnits[0]; |
| 471 LinkedReference referenceResolution = |
| 472 linkedSourceUnit.references[referenceIndex]; |
| 473 String name; |
| 474 UnlinkedReference reference; |
| 475 if (referenceIndex < unlinkedSourceUnit.references.length) { |
| 476 // This is an explicit reference, so its name and prefix should be in |
| 477 // [UnlinkedUnit.references]. |
| 478 expect(referenceResolution.name, isEmpty); |
| 479 reference = unlinkedSourceUnit.references[referenceIndex]; |
| 480 name = reference.name; |
| 481 if (reference.prefixReference != 0) { |
| 482 // Prefixes should appear in the references table before any reference |
| 483 // that uses them. |
| 484 expect(reference.prefixReference, lessThan(referenceIndex)); |
| 485 } |
| 486 } else { |
| 487 // This is an implicit reference, so its name should be in |
| 488 // [LinkedUnit.references]. |
| 489 name = referenceResolution.name; |
| 490 } |
| 491 // Index 0 is reserved. |
| 492 expect(referenceIndex, isNot(0)); |
| 493 if (absoluteUri == null) { |
| 494 expect(referenceResolution.dependency, 0); |
| 495 } else { |
| 496 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri); |
| 497 } |
| 498 if (expectedName == null) { |
| 499 expect(name, isEmpty); |
| 500 } else { |
| 501 expect(name, expectedName); |
| 502 } |
| 503 expect(referenceResolution.kind, expectedKind); |
| 504 expect(referenceResolution.unit, expectedTargetUnit); |
| 505 expect(referenceResolution.numTypeParameters, numTypeParameters); |
| 506 expect(referenceResolution.localIndex, localIndex); |
| 507 return reference; |
| 508 } |
| 509 |
| 510 /** |
| 511 * Verify that the given [typeRef] represents a reference to a type declared |
| 512 * in a file reachable via [absoluteUri] and [relativeUri], having name |
| 513 * [expectedName]. If [expectedPrefix] is supplied, verify that the type is |
| 514 * reached via the given prefix. Verify that the number of type arguments |
| 515 * is equal to [numTypeArguments]. [expectedKind] is the kind of |
| 516 * object referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer |
| 517 * to the compilation unit within which the [typeRef] appears; if not |
| 518 * specified they are assumed to refer to the defining compilation unit. |
| 519 * [expectedTargetUnit] is the index of the compilation unit in which the |
| 520 * target of the [typeRef] is expected to appear; if not specified it is |
| 521 * assumed to be the defining compilation unit. [numTypeParameters] is the |
| 522 * number of type parameters of the thing being referred to. |
| 523 */ |
| 524 void checkTypeRef(EntityRef typeRef, String absoluteUri, String relativeUri, |
| 525 String expectedName, |
| 526 {String expectedPrefix, |
| 527 List<_PrefixExpectation> prefixExpectations, |
| 528 int numTypeArguments: 0, |
| 529 ReferenceKind expectedKind: ReferenceKind.classOrEnum, |
| 530 int expectedTargetUnit: 0, |
| 531 LinkedUnit linkedSourceUnit, |
| 532 UnlinkedUnit unlinkedSourceUnit, |
| 533 int numTypeParameters: 0, |
| 534 bool unresolvedHasName: false}) { |
| 535 linkedSourceUnit ??= definingUnit; |
| 536 expect(typeRef, new isInstanceOf<EntityRef>()); |
| 537 expect(typeRef.paramReference, 0); |
| 538 int index = typeRef.reference; |
| 539 expect(typeRef.typeArguments, hasLength(numTypeArguments)); |
| 540 UnlinkedReference reference = checkReferenceIndex( |
| 541 index, absoluteUri, relativeUri, expectedName, |
| 542 expectedKind: expectedKind, |
| 543 expectedTargetUnit: expectedTargetUnit, |
| 544 linkedSourceUnit: linkedSourceUnit, |
| 545 unlinkedSourceUnit: unlinkedSourceUnit, |
| 546 numTypeParameters: numTypeParameters, |
| 547 unresolvedHasName: unresolvedHasName); |
| 548 expect(reference, isNotNull, |
| 549 reason: 'Unlinked type refs must refer to an explicit reference'); |
| 550 if (expectedPrefix != null) { |
| 551 checkPrefix(reference.prefixReference, expectedPrefix); |
| 552 } else if (prefixExpectations != null) { |
| 553 for (_PrefixExpectation expectation in prefixExpectations) { |
| 554 expect(reference.prefixReference, isNot(0)); |
| 555 reference = checkReferenceIndex(reference.prefixReference, |
| 556 expectation.absoluteUri, expectation.relativeUri, expectation.name, |
| 557 expectedKind: expectation.kind, |
| 558 expectedTargetUnit: expectedTargetUnit, |
| 559 linkedSourceUnit: linkedSourceUnit, |
| 560 unlinkedSourceUnit: unlinkedSourceUnit, |
| 561 numTypeParameters: expectation.numTypeParameters); |
| 562 } |
| 563 expect(reference.prefixReference, 0); |
| 564 } else { |
| 565 expect(reference.prefixReference, 0); |
| 566 } |
| 567 } |
| 568 |
| 569 /** |
| 570 * Verify that the given [typeRef] represents a reference to an unresolved |
| 571 * type. |
| 572 */ |
| 573 void checkUnresolvedTypeRef( |
| 574 EntityRef typeRef, String expectedPrefix, String expectedName, |
| 575 {LinkedUnit linkedSourceUnit, UnlinkedUnit unlinkedSourceUnit}) { |
| 576 // When serializing from the element model, unresolved type refs lose their |
| 577 // name. |
| 578 checkTypeRef(typeRef, null, null, expectedName, |
| 579 expectedPrefix: expectedPrefix, |
| 580 expectedKind: ReferenceKind.unresolved, |
| 581 linkedSourceUnit: linkedSourceUnit, |
| 582 unlinkedSourceUnit: unlinkedSourceUnit); |
| 583 } |
| 584 |
| 585 /** |
| 586 * Verify that the given [typeRef] represents the type `void`. |
| 587 */ |
| 588 void checkVoidTypeRef(EntityRef typeRef) { |
| 589 checkTypeRef(typeRef, null, null, 'void'); |
| 590 } |
| 591 |
| 592 fail_invalid_prefix_dynamic() { |
| 593 // if (checkAstDerivedData) { |
| 594 // // TODO(paulberry): get this to work properly. |
| 595 // return; |
| 596 // } |
| 597 var t = serializeTypeText('dynamic.T', allowErrors: true); |
| 598 checkUnresolvedTypeRef(t, 'dynamic', 'T'); |
| 599 } |
| 600 |
| 601 fail_invalid_prefix_type_parameter() { |
| 602 // if (checkAstDerivedData) { |
| 603 // // TODO(paulberry): get this to work properly. |
| 604 // return; |
| 605 // } |
| 606 checkUnresolvedTypeRef( |
| 607 serializeClassText('class C<T> { T.U x; }', allowErrors: true) |
| 608 .fields[0] |
| 609 .type, |
| 610 'T', |
| 611 'U'); |
| 612 } |
| 613 |
| 614 fail_invalid_prefix_void() { |
| 615 // if (checkAstDerivedData) { |
| 616 // // TODO(paulberry): get this to work properly. |
| 617 // return; |
| 618 // } |
| 619 checkUnresolvedTypeRef( |
| 620 serializeTypeText('void.T', allowErrors: true), 'void', 'T'); |
| 621 } |
| 622 |
| 623 /** |
| 624 * Find the class with the given [className] in the summary, and return its |
| 625 * [UnlinkedClass] data structure. If [unit] is not given, the class is |
| 626 * looked for in the defining compilation unit. |
| 627 */ |
| 628 UnlinkedClass findClass(String className, |
| 629 {bool failIfAbsent: false, UnlinkedUnit unit}) { |
| 630 unit ??= unlinkedUnits[0]; |
| 631 UnlinkedClass result; |
| 632 for (UnlinkedClass cls in unit.classes) { |
| 633 if (cls.name == className) { |
| 634 if (result != null) { |
| 635 fail('Duplicate class $className'); |
| 636 } |
| 637 result = cls; |
| 638 } |
| 639 } |
| 640 if (result == null && failIfAbsent) { |
| 641 fail('Class $className not found in serialized output'); |
| 642 } |
| 643 return result; |
| 644 } |
| 645 |
| 646 /** |
| 647 * Find the enum with the given [enumName] in the summary, and return its |
| 648 * [UnlinkedEnum] data structure. If [unit] is not given, the enum is looked |
| 649 * for in the defining compilation unit. |
| 650 */ |
| 651 UnlinkedEnum findEnum(String enumName, |
| 652 {bool failIfAbsent: false, UnlinkedUnit unit}) { |
| 653 unit ??= unlinkedUnits[0]; |
| 654 UnlinkedEnum result; |
| 655 for (UnlinkedEnum e in unit.enums) { |
| 656 if (e.name == enumName) { |
| 657 if (result != null) { |
| 658 fail('Duplicate enum $enumName'); |
| 659 } |
| 660 result = e; |
| 661 } |
| 662 } |
| 663 if (result == null && failIfAbsent) { |
| 664 fail('Enum $enumName not found in serialized output'); |
| 665 } |
| 666 return result; |
| 667 } |
| 668 |
| 669 /** |
| 670 * Find the executable with the given [executableName] in the summary, and |
| 671 * return its [UnlinkedExecutable] data structure. If [executables] is not |
| 672 * given, then the executable is searched for in the defining compilation |
| 673 * unit. |
| 674 */ |
| 675 UnlinkedExecutable findExecutable(String executableName, |
| 676 {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) { |
| 677 executables ??= unlinkedUnits[0].executables; |
| 678 UnlinkedExecutable result; |
| 679 for (UnlinkedExecutable executable in executables) { |
| 680 if (executable.name == executableName) { |
| 681 if (result != null) { |
| 682 fail('Duplicate executable $executableName'); |
| 683 } |
| 684 result = executable; |
| 685 } |
| 686 } |
| 687 if (result == null && failIfAbsent) { |
| 688 fail('Executable $executableName not found in serialized output'); |
| 689 } |
| 690 return result; |
| 691 } |
| 692 |
| 693 /** |
| 694 * Find the typedef with the given [typedefName] in the summary, and return |
| 695 * its [UnlinkedTypedef] data structure. If [unit] is not given, the typedef |
| 696 * is looked for in the defining compilation unit. |
| 697 */ |
| 698 UnlinkedTypedef findTypedef(String typedefName, |
| 699 {bool failIfAbsent: false, UnlinkedUnit unit}) { |
| 700 unit ??= unlinkedUnits[0]; |
| 701 UnlinkedTypedef result; |
| 702 for (UnlinkedTypedef type in unit.typedefs) { |
| 703 if (type.name == typedefName) { |
| 704 if (result != null) { |
| 705 fail('Duplicate typedef $typedefName'); |
| 706 } |
| 707 result = type; |
| 708 } |
| 709 } |
| 710 if (result == null && failIfAbsent) { |
| 711 fail('Typedef $typedefName not found in serialized output'); |
| 712 } |
| 713 return result; |
| 714 } |
| 715 |
| 716 /** |
| 717 * Find the top level variable with the given [variableName] in the summary, |
| 718 * and return its [UnlinkedVariable] data structure. If [variables] is not |
| 719 * specified, the variable is looked for in the defining compilation unit. |
| 720 */ |
| 721 UnlinkedVariable findVariable(String variableName, |
| 722 {List<UnlinkedVariable> variables, bool failIfAbsent: false}) { |
| 723 variables ??= unlinkedUnits[0].variables; |
| 724 UnlinkedVariable result; |
| 725 for (UnlinkedVariable variable in variables) { |
| 726 if (variable.name == variableName) { |
| 727 if (result != null) { |
| 728 fail('Duplicate variable $variableName'); |
| 729 } |
| 730 result = variable; |
| 731 } |
| 732 } |
| 733 if (result == null && failIfAbsent) { |
| 734 fail('Variable $variableName not found in serialized output'); |
| 735 } |
| 736 return result; |
| 737 } |
| 738 |
| 739 /** |
| 740 * Find the entry in [linkedSourceUnit.types] matching [slotId]. |
| 741 */ |
| 742 EntityRef getTypeRefForSlot(int slotId, {LinkedUnit linkedSourceUnit}) { |
| 743 linkedSourceUnit ??= definingUnit; |
| 744 for (EntityRef typeRef in linkedSourceUnit.types) { |
| 745 if (typeRef.slot == slotId) { |
| 746 return typeRef; |
| 747 } |
| 748 } |
| 749 return null; |
| 750 } |
| 751 |
| 752 /** |
| 753 * Serialize the given library [text] and return the summary of the class |
| 754 * with the given [className]. |
| 755 */ |
| 756 UnlinkedClass serializeClassText(String text, |
| 757 {String className: 'C', bool allowErrors: false}) { |
| 758 serializeLibraryText(text, allowErrors: allowErrors); |
| 759 return findClass(className, failIfAbsent: true); |
| 760 } |
| 761 |
| 762 /** |
| 763 * Serialize the given library [text] and return the summary of the enum with |
| 764 * the given [enumName]. |
| 765 */ |
| 766 UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) { |
| 767 serializeLibraryText(text); |
| 768 return findEnum(enumName, failIfAbsent: true); |
| 769 } |
| 770 |
| 771 /** |
| 772 * Serialize the given library [text] and return the summary of the |
| 773 * executable with the given [executableName]. |
| 774 */ |
| 775 UnlinkedExecutable serializeExecutableText(String text, |
| 776 {String executableName: 'f', bool allowErrors: false}) { |
| 777 serializeLibraryText(text, allowErrors: allowErrors); |
| 778 return findExecutable(executableName, failIfAbsent: true); |
| 779 } |
| 780 |
| 781 /** |
| 782 * Serialize the given library [text], then deserialize it and store its |
| 783 * summary in [lib]. |
| 784 */ |
| 785 void serializeLibraryText(String text, {bool allowErrors: false}); |
| 786 |
| 787 /** |
| 788 * Serialize the given method [text] and return the summary of the executable |
| 789 * with the given [executableName]. |
| 790 */ |
| 791 UnlinkedExecutable serializeMethodText(String text, |
| 792 [String executableName = 'f']) { |
| 793 serializeLibraryText('class C { $text }'); |
| 794 return findExecutable(executableName, |
| 795 executables: findClass('C', failIfAbsent: true).executables, |
| 796 failIfAbsent: true); |
| 797 } |
| 798 |
| 799 /** |
| 800 * Serialize the given library [text] and return the summary of the typedef |
| 801 * with the given [typedefName]. |
| 802 */ |
| 803 UnlinkedTypedef serializeTypedefText(String text, |
| 804 [String typedefName = 'F']) { |
| 805 serializeLibraryText(text); |
| 806 return findTypedef(typedefName, failIfAbsent: true); |
| 807 } |
| 808 |
| 809 /** |
| 810 * Serialize a type declaration using the given [text] as a type name, and |
| 811 * return a summary of the corresponding [EntityRef]. If the type |
| 812 * declaration needs to refer to types that are not available in core, those |
| 813 * types may be declared in [otherDeclarations]. |
| 814 */ |
| 815 EntityRef serializeTypeText(String text, |
| 816 {String otherDeclarations: '', bool allowErrors: false}) { |
| 817 return serializeVariableText('$otherDeclarations\n$text v;', |
| 818 allowErrors: allowErrors) |
| 819 .type; |
| 820 } |
| 821 |
| 822 /** |
| 823 * Serialize the given library [text] and return the summary of the variable |
| 824 * with the given [variableName]. |
| 825 */ |
| 826 UnlinkedVariable serializeVariableText(String text, |
| 827 {String variableName: 'v', bool allowErrors: false}) { |
| 828 serializeLibraryText(text, allowErrors: allowErrors); |
| 829 return findVariable(variableName, failIfAbsent: true); |
| 830 } |
| 831 |
| 832 test_bottom_reference_shared() { |
| 833 if (skipFullyLinkedData) { |
| 834 return; |
| 835 } |
| 836 // The synthetic executables for both `x` and `y` have type `() => `Bottom`. |
| 837 // Verify that they both use the same reference to `Bottom`. |
| 838 serializeLibraryText('int x = null; int y = null;'); |
| 839 EntityRef xInitializerReturnType = |
| 840 getTypeRefForSlot(findVariable('x').initializer.inferredReturnTypeSlot); |
| 841 EntityRef yInitializerReturnType = |
| 842 getTypeRefForSlot(findVariable('y').initializer.inferredReturnTypeSlot); |
| 843 expect(xInitializerReturnType.reference, yInitializerReturnType.reference); |
| 844 } |
| 845 |
| 846 test_cascaded_export_hide_hide() { |
| 847 addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;'); |
| 848 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}'); |
| 849 serializeLibraryText( |
| 850 ''' |
| 851 import 'lib1.dart'; |
| 852 A a; |
| 853 B b; |
| 854 C c; |
| 855 ''', |
| 856 allowErrors: true); |
| 857 checkTypeRef( |
| 858 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A'); |
| 859 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 860 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 861 } |
| 862 |
| 863 test_cascaded_export_hide_show() { |
| 864 addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;'); |
| 865 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}'); |
| 866 serializeLibraryText( |
| 867 ''' |
| 868 import 'lib1.dart'; |
| 869 A a; |
| 870 B b; |
| 871 C c; |
| 872 ''', |
| 873 allowErrors: true); |
| 874 checkTypeRef( |
| 875 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A'); |
| 876 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 877 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 878 } |
| 879 |
| 880 test_cascaded_export_show_hide() { |
| 881 addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;'); |
| 882 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}'); |
| 883 serializeLibraryText( |
| 884 ''' |
| 885 import 'lib1.dart'; |
| 886 A a; |
| 887 B b; |
| 888 C c; |
| 889 ''', |
| 890 allowErrors: true); |
| 891 checkTypeRef( |
| 892 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A'); |
| 893 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 894 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 895 } |
| 896 |
| 897 test_cascaded_export_show_show() { |
| 898 addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;'); |
| 899 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}'); |
| 900 serializeLibraryText( |
| 901 ''' |
| 902 import 'lib1.dart'; |
| 903 A a; |
| 904 B b; |
| 905 C c; |
| 906 ''', |
| 907 allowErrors: true); |
| 908 checkTypeRef( |
| 909 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A'); |
| 910 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 911 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 912 } |
| 913 |
| 914 test_cascaded_import_hide_hide() { |
| 915 addNamedSource('/lib.dart', 'class A {} class B {} class C {}'); |
| 916 serializeLibraryText( |
| 917 ''' |
| 918 import 'lib.dart' hide C hide B, C; |
| 919 A a; |
| 920 B b; |
| 921 C c; |
| 922 ''', |
| 923 allowErrors: true); |
| 924 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A'); |
| 925 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 926 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 927 } |
| 928 |
| 929 test_cascaded_import_hide_show() { |
| 930 addNamedSource('/lib.dart', 'class A {} class B {} class C {}'); |
| 931 serializeLibraryText( |
| 932 ''' |
| 933 import 'lib.dart' hide C show A, C; |
| 934 A a; |
| 935 B b; |
| 936 C c; |
| 937 ''', |
| 938 allowErrors: true); |
| 939 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A'); |
| 940 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 941 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 942 } |
| 943 |
| 944 test_cascaded_import_show_hide() { |
| 945 addNamedSource('/lib.dart', 'class A {} class B {} class C {}'); |
| 946 serializeLibraryText( |
| 947 ''' |
| 948 import 'lib.dart' show A, B hide B, C; |
| 949 A a; |
| 950 B b; |
| 951 C c; |
| 952 ''', |
| 953 allowErrors: true); |
| 954 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A'); |
| 955 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 956 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 957 } |
| 958 |
| 959 test_cascaded_import_show_show() { |
| 960 addNamedSource('/lib.dart', 'class A {} class B {} class C {}'); |
| 961 serializeLibraryText( |
| 962 ''' |
| 963 import 'lib.dart' show A, B show A, C; |
| 964 A a; |
| 965 B b; |
| 966 C c; |
| 967 ''', |
| 968 allowErrors: true); |
| 969 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A'); |
| 970 checkUnresolvedTypeRef(findVariable('b').type, null, 'B'); |
| 971 checkUnresolvedTypeRef(findVariable('c').type, null, 'C'); |
| 972 } |
| 973 |
| 974 test_class_abstract() { |
| 975 UnlinkedClass cls = serializeClassText('abstract class C {}'); |
| 976 expect(cls.isAbstract, true); |
| 977 } |
| 978 |
| 979 test_class_alias_abstract() { |
| 980 UnlinkedClass cls = serializeClassText( |
| 981 'abstract class C = D with E; class D {} class E {}'); |
| 982 expect(cls.isAbstract, true); |
| 983 } |
| 984 |
| 985 test_class_alias_concrete() { |
| 986 UnlinkedClass cls = |
| 987 serializeClassText('class C = _D with _E; class _D {} class _E {}'); |
| 988 expect(cls.isAbstract, false); |
| 989 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 990 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 991 ReferenceKind.classOrEnum); |
| 992 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 993 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 994 } |
| 995 |
| 996 test_class_alias_documented() { |
| 997 String text = ''' |
| 998 // Extra comment so doc comment offset != 0 |
| 999 /** |
| 1000 * Docs |
| 1001 */ |
| 1002 class C = D with E; |
| 1003 |
| 1004 class D {} |
| 1005 class E {}'''; |
| 1006 UnlinkedClass cls = serializeClassText(text); |
| 1007 expect(cls.documentationComment, isNotNull); |
| 1008 checkDocumentationComment(cls.documentationComment, text); |
| 1009 } |
| 1010 |
| 1011 test_class_alias_flag() { |
| 1012 UnlinkedClass cls = |
| 1013 serializeClassText('class C = D with E; class D {} class E {}'); |
| 1014 expect(cls.isMixinApplication, true); |
| 1015 } |
| 1016 |
| 1017 test_class_alias_generic() { |
| 1018 serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}'); |
| 1019 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2); |
| 1020 } |
| 1021 |
| 1022 test_class_alias_mixin_order() { |
| 1023 UnlinkedClass cls = serializeClassText(''' |
| 1024 class C = D with E, F; |
| 1025 class D {} |
| 1026 class E {} |
| 1027 class F {} |
| 1028 '''); |
| 1029 expect(cls.mixins, hasLength(2)); |
| 1030 checkTypeRef(cls.mixins[0], null, null, 'E'); |
| 1031 checkTypeRef(cls.mixins[1], null, null, 'F'); |
| 1032 } |
| 1033 |
| 1034 test_class_alias_no_implicit_constructors() { |
| 1035 UnlinkedClass cls = serializeClassText(''' |
| 1036 class C = D with E; |
| 1037 class D { |
| 1038 D.foo(); |
| 1039 D.bar(); |
| 1040 } |
| 1041 class E {} |
| 1042 '''); |
| 1043 expect(cls.executables, isEmpty); |
| 1044 } |
| 1045 |
| 1046 test_class_alias_private() { |
| 1047 serializeClassText('class _C = _D with _E; class _D {} class _E {}', |
| 1048 className: '_C'); |
| 1049 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 1050 } |
| 1051 |
| 1052 test_class_alias_reference_generic() { |
| 1053 EntityRef typeRef = serializeTypeText('C', |
| 1054 otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}'); |
| 1055 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); |
| 1056 } |
| 1057 |
| 1058 test_class_alias_reference_generic_imported() { |
| 1059 addNamedSource( |
| 1060 '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}'); |
| 1061 EntityRef typeRef = |
| 1062 serializeTypeText('C', otherDeclarations: 'import "lib.dart";'); |
| 1063 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C', |
| 1064 numTypeParameters: 2); |
| 1065 } |
| 1066 |
| 1067 test_class_alias_supertype() { |
| 1068 UnlinkedClass cls = |
| 1069 serializeClassText('class C = D with E; class D {} class E {}'); |
| 1070 checkTypeRef(cls.supertype, null, null, 'D'); |
| 1071 expect(cls.hasNoSupertype, isFalse); |
| 1072 } |
| 1073 |
| 1074 test_class_codeRange() { |
| 1075 UnlinkedClass cls = serializeClassText(' class C {}'); |
| 1076 _assertCodeRange(cls.codeRange, 1, 10); |
| 1077 } |
| 1078 |
| 1079 test_class_concrete() { |
| 1080 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1081 expect(cls.isAbstract, false); |
| 1082 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 1083 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 1084 ReferenceKind.classOrEnum); |
| 1085 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 1086 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 1087 } |
| 1088 |
| 1089 test_class_constMembers() { |
| 1090 UnlinkedClass cls = serializeClassText(''' |
| 1091 class C { |
| 1092 int fieldInstance = 0; |
| 1093 final int fieldInstanceFinal = 0; |
| 1094 static int fieldStatic = 0; |
| 1095 static final int fieldStaticFinal = 0; |
| 1096 static const int fieldStaticConst = 0; |
| 1097 static const int _fieldStaticConstPrivate = 0; |
| 1098 static void methodStaticPublic() {} |
| 1099 static void _methodStaticPrivate() {} |
| 1100 void methodInstancePublic() {} |
| 1101 C operator+(C c) => null; |
| 1102 } |
| 1103 '''); |
| 1104 expect(cls.isAbstract, false); |
| 1105 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 1106 UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0]; |
| 1107 expect(className.kind, ReferenceKind.classOrEnum); |
| 1108 expect(className.name, 'C'); |
| 1109 expect(className.numTypeParameters, 0); |
| 1110 // executables |
| 1111 Map<String, UnlinkedPublicName> executablesMap = |
| 1112 <String, UnlinkedPublicName>{}; |
| 1113 className.members.forEach((e) => executablesMap[e.name] = e); |
| 1114 expect(executablesMap, hasLength(4)); |
| 1115 Map<String, ReferenceKind> expectedExecutableKinds = |
| 1116 <String, ReferenceKind>{ |
| 1117 'fieldStaticConst': ReferenceKind.propertyAccessor, |
| 1118 'fieldStaticFinal': ReferenceKind.propertyAccessor, |
| 1119 'fieldStatic': ReferenceKind.propertyAccessor, |
| 1120 'methodStaticPublic': ReferenceKind.method, |
| 1121 }; |
| 1122 expectedExecutableKinds.forEach((String name, ReferenceKind expectedKind) { |
| 1123 UnlinkedPublicName executable = executablesMap[name]; |
| 1124 expect(executable.kind, expectedKind); |
| 1125 expect(executable.members, isEmpty); |
| 1126 }); |
| 1127 } |
| 1128 |
| 1129 test_class_constMembers_constructors() { |
| 1130 UnlinkedClass cls = serializeClassText(''' |
| 1131 class C { |
| 1132 const C(); |
| 1133 const C.constructorNamedPublicConst(); |
| 1134 C.constructorNamedPublic(); |
| 1135 C._constructorNamedPrivate(); |
| 1136 } |
| 1137 '''); |
| 1138 expect(cls.isAbstract, false); |
| 1139 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 1140 UnlinkedPublicName className = unlinkedUnits[0].publicNamespace.names[0]; |
| 1141 expect(className.kind, ReferenceKind.classOrEnum); |
| 1142 expect(className.name, 'C'); |
| 1143 expect(className.numTypeParameters, 0); |
| 1144 // executables |
| 1145 Map<String, UnlinkedPublicName> executablesMap = |
| 1146 <String, UnlinkedPublicName>{}; |
| 1147 className.members.forEach((e) => executablesMap[e.name] = e); |
| 1148 expect(executablesMap, hasLength(2)); |
| 1149 { |
| 1150 UnlinkedPublicName executable = |
| 1151 executablesMap['constructorNamedPublicConst']; |
| 1152 expect(executable.kind, ReferenceKind.constructor); |
| 1153 expect(executable.members, isEmpty); |
| 1154 } |
| 1155 { |
| 1156 UnlinkedPublicName executable = executablesMap['constructorNamedPublic']; |
| 1157 expect(executable.kind, ReferenceKind.constructor); |
| 1158 expect(executable.members, isEmpty); |
| 1159 } |
| 1160 } |
| 1161 |
| 1162 test_class_documented() { |
| 1163 String text = ''' |
| 1164 // Extra comment so doc comment offset != 0 |
| 1165 /** |
| 1166 * Docs |
| 1167 */ |
| 1168 class C {}'''; |
| 1169 UnlinkedClass cls = serializeClassText(text); |
| 1170 expect(cls.documentationComment, isNotNull); |
| 1171 checkDocumentationComment(cls.documentationComment, text); |
| 1172 } |
| 1173 |
| 1174 test_class_documented_with_references() { |
| 1175 String text = ''' |
| 1176 // Extra comment so doc comment offset != 0 |
| 1177 /** |
| 1178 * Docs referring to [D] and [E] |
| 1179 */ |
| 1180 class C {} |
| 1181 |
| 1182 class D {} |
| 1183 class E {}'''; |
| 1184 UnlinkedClass cls = serializeClassText(text); |
| 1185 expect(cls.documentationComment, isNotNull); |
| 1186 checkDocumentationComment(cls.documentationComment, text); |
| 1187 } |
| 1188 |
| 1189 test_class_documented_with_with_windows_line_endings() { |
| 1190 String text = '/**\r\n * Docs\r\n */\r\nclass C {}'; |
| 1191 UnlinkedClass cls = serializeClassText(text); |
| 1192 expect(cls.documentationComment, isNotNull); |
| 1193 checkDocumentationComment(cls.documentationComment, text); |
| 1194 } |
| 1195 |
| 1196 test_class_interface() { |
| 1197 UnlinkedClass cls = serializeClassText(''' |
| 1198 class C implements D {} |
| 1199 class D {} |
| 1200 '''); |
| 1201 expect(cls.interfaces, hasLength(1)); |
| 1202 checkTypeRef(cls.interfaces[0], null, null, 'D'); |
| 1203 } |
| 1204 |
| 1205 test_class_interface_order() { |
| 1206 UnlinkedClass cls = serializeClassText(''' |
| 1207 class C implements D, E {} |
| 1208 class D {} |
| 1209 class E {} |
| 1210 '''); |
| 1211 expect(cls.interfaces, hasLength(2)); |
| 1212 checkTypeRef(cls.interfaces[0], null, null, 'D'); |
| 1213 checkTypeRef(cls.interfaces[1], null, null, 'E'); |
| 1214 } |
| 1215 |
| 1216 test_class_mixin() { |
| 1217 UnlinkedClass cls = serializeClassText(''' |
| 1218 class C extends Object with D {} |
| 1219 class D {} |
| 1220 '''); |
| 1221 expect(cls.mixins, hasLength(1)); |
| 1222 checkTypeRef(cls.mixins[0], null, null, 'D'); |
| 1223 } |
| 1224 |
| 1225 test_class_mixin_order() { |
| 1226 UnlinkedClass cls = serializeClassText(''' |
| 1227 class C extends Object with D, E {} |
| 1228 class D {} |
| 1229 class E {} |
| 1230 '''); |
| 1231 expect(cls.mixins, hasLength(2)); |
| 1232 checkTypeRef(cls.mixins[0], null, null, 'D'); |
| 1233 checkTypeRef(cls.mixins[1], null, null, 'E'); |
| 1234 } |
| 1235 |
| 1236 test_class_name() { |
| 1237 var classText = 'class C {}'; |
| 1238 UnlinkedClass cls = serializeClassText(classText); |
| 1239 expect(cls.name, 'C'); |
| 1240 expect(cls.nameOffset, classText.indexOf('C')); |
| 1241 } |
| 1242 |
| 1243 test_class_no_flags() { |
| 1244 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1245 expect(cls.isAbstract, false); |
| 1246 expect(cls.isMixinApplication, false); |
| 1247 } |
| 1248 |
| 1249 test_class_no_interface() { |
| 1250 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1251 expect(cls.interfaces, isEmpty); |
| 1252 } |
| 1253 |
| 1254 test_class_no_mixins() { |
| 1255 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1256 expect(cls.mixins, isEmpty); |
| 1257 } |
| 1258 |
| 1259 test_class_no_type_param() { |
| 1260 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1261 expect(cls.typeParameters, isEmpty); |
| 1262 } |
| 1263 |
| 1264 test_class_non_alias_flag() { |
| 1265 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1266 expect(cls.isMixinApplication, false); |
| 1267 } |
| 1268 |
| 1269 test_class_private() { |
| 1270 serializeClassText('class _C {}', className: '_C'); |
| 1271 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 1272 } |
| 1273 |
| 1274 test_class_reference_generic() { |
| 1275 EntityRef typeRef = |
| 1276 serializeTypeText('C', otherDeclarations: 'class C<D, E> {}'); |
| 1277 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2); |
| 1278 } |
| 1279 |
| 1280 test_class_reference_generic_imported() { |
| 1281 addNamedSource('/lib.dart', 'class C<D, E> {}'); |
| 1282 EntityRef typeRef = |
| 1283 serializeTypeText('C', otherDeclarations: 'import "lib.dart";'); |
| 1284 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C', |
| 1285 numTypeParameters: 2); |
| 1286 } |
| 1287 |
| 1288 test_class_superclass() { |
| 1289 UnlinkedClass cls = serializeClassText('class C {}'); |
| 1290 expect(cls.supertype, isNull); |
| 1291 expect(cls.hasNoSupertype, isFalse); |
| 1292 } |
| 1293 |
| 1294 test_class_superclass_explicit() { |
| 1295 UnlinkedClass cls = serializeClassText('class C extends D {} class D {}'); |
| 1296 expect(cls.supertype, isNotNull); |
| 1297 checkTypeRef(cls.supertype, null, null, 'D'); |
| 1298 expect(cls.hasNoSupertype, isFalse); |
| 1299 } |
| 1300 |
| 1301 test_class_type_param_bound() { |
| 1302 UnlinkedClass cls = serializeClassText('class C<T extends List> {}'); |
| 1303 expect(cls.typeParameters, hasLength(1)); |
| 1304 { |
| 1305 UnlinkedTypeParam typeParameter = cls.typeParameters[0]; |
| 1306 expect(typeParameter.name, 'T'); |
| 1307 expect(typeParameter.bound, isNotNull); |
| 1308 checkTypeRef(typeParameter.bound, 'dart:core', 'dart:core', 'List', |
| 1309 numTypeParameters: 1); |
| 1310 } |
| 1311 } |
| 1312 |
| 1313 test_class_type_param_f_bound() { |
| 1314 UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}'); |
| 1315 EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0]; |
| 1316 checkParamTypeRef(typeArgument, 2); |
| 1317 } |
| 1318 |
| 1319 test_class_type_param_f_bound_self_ref() { |
| 1320 UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}'); |
| 1321 EntityRef typeArgument = cls.typeParameters[1].bound.typeArguments[0]; |
| 1322 checkParamTypeRef(typeArgument, 1); |
| 1323 } |
| 1324 |
| 1325 test_class_type_param_no_bound() { |
| 1326 String text = 'class C<T> {}'; |
| 1327 UnlinkedClass cls = serializeClassText(text); |
| 1328 expect(cls.typeParameters, hasLength(1)); |
| 1329 expect(cls.typeParameters[0].name, 'T'); |
| 1330 expect(cls.typeParameters[0].nameOffset, text.indexOf('T')); |
| 1331 expect(cls.typeParameters[0].bound, isNull); |
| 1332 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1); |
| 1333 } |
| 1334 |
| 1335 test_closure_executable_with_bottom_return_type() { |
| 1336 UnlinkedExecutable executable = |
| 1337 serializeExecutableText('f() { print((() => null)()); }'); |
| 1338 expect(executable.localFunctions, hasLength(1)); |
| 1339 expect(executable.localFunctions[0].returnType, isNull); |
| 1340 if (strongMode) { |
| 1341 // Strong mode infers a type for the closure of `() => dynamic`, so the |
| 1342 // inferred return type slot should be empty. |
| 1343 expect( |
| 1344 getTypeRefForSlot( |
| 1345 executable.localFunctions[0].inferredReturnTypeSlot), |
| 1346 isNull); |
| 1347 } else { |
| 1348 // Spec mode infers a type for the closure of `() => Bottom`. |
| 1349 checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot, |
| 1350 null, null, '*bottom*', |
| 1351 onlyInStrongMode: false); |
| 1352 } |
| 1353 } |
| 1354 |
| 1355 test_closure_executable_with_imported_return_type() { |
| 1356 addNamedSource('/a.dart', 'class C { D d; } class D {}'); |
| 1357 // The closure has type `() => D`; `D` is defined in a library that is |
| 1358 // imported. |
| 1359 UnlinkedExecutable executable = serializeExecutableText( |
| 1360 'import "a.dart"; f() { print((() => new C().d)()); }'); |
| 1361 expect(executable.localFunctions, hasLength(1)); |
| 1362 expect(executable.localFunctions[0].returnType, isNull); |
| 1363 checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot, |
| 1364 absUri('/a.dart'), 'a.dart', 'D', |
| 1365 onlyInStrongMode: false); |
| 1366 checkHasDependency('a.dart', fullyLinked: false); |
| 1367 } |
| 1368 |
| 1369 test_closure_executable_with_return_type_from_closure() { |
| 1370 if (skipFullyLinkedData) { |
| 1371 return; |
| 1372 } |
| 1373 // The closure has type `() => () => int`, where the `() => int` part refers |
| 1374 // to the nested closure. |
| 1375 UnlinkedExecutable executable = serializeExecutableText(''' |
| 1376 f() { |
| 1377 print(() {}); // force the closure below to have index 1 |
| 1378 print(() => () => 0); |
| 1379 } |
| 1380 '''); |
| 1381 expect(executable.localFunctions, hasLength(2)); |
| 1382 EntityRef closureType = |
| 1383 getTypeRefForSlot(executable.localFunctions[1].inferredReturnTypeSlot); |
| 1384 checkLinkedTypeRef(closureType, null, null, '', |
| 1385 expectedKind: ReferenceKind.function); |
| 1386 int outerClosureIndex = |
| 1387 definingUnit.references[closureType.reference].containingReference; |
| 1388 checkReferenceIndex(outerClosureIndex, null, null, '', |
| 1389 expectedKind: ReferenceKind.function, localIndex: 1); |
| 1390 int topLevelFunctionIndex = |
| 1391 definingUnit.references[outerClosureIndex].containingReference; |
| 1392 checkReferenceIndex(topLevelFunctionIndex, null, null, 'f', |
| 1393 expectedKind: ReferenceKind.topLevelFunction); |
| 1394 expect( |
| 1395 definingUnit.references[topLevelFunctionIndex].containingReference, 0); |
| 1396 } |
| 1397 |
| 1398 test_closure_executable_with_unimported_return_type() { |
| 1399 addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }'); |
| 1400 addNamedSource('/b.dart', 'class D {}'); |
| 1401 // The closure has type `() => D`; `D` is defined in a library that is not |
| 1402 // imported. |
| 1403 UnlinkedExecutable executable = serializeExecutableText( |
| 1404 'import "a.dart"; f() { print((() => new C().d)()); }'); |
| 1405 expect(executable.localFunctions, hasLength(1)); |
| 1406 expect(executable.localFunctions[0].returnType, isNull); |
| 1407 checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot, |
| 1408 absUri('/b.dart'), 'b.dart', 'D', |
| 1409 onlyInStrongMode: false); |
| 1410 if (!skipFullyLinkedData) { |
| 1411 checkHasDependency('b.dart', fullyLinked: true); |
| 1412 } |
| 1413 } |
| 1414 |
| 1415 test_constExpr_binary_add() { |
| 1416 UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;'); |
| 1417 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1418 UnlinkedConstOperation.pushInt, |
| 1419 UnlinkedConstOperation.pushInt, |
| 1420 UnlinkedConstOperation.add |
| 1421 ], ints: [ |
| 1422 1, |
| 1423 2 |
| 1424 ]); |
| 1425 } |
| 1426 |
| 1427 test_constExpr_binary_and() { |
| 1428 UnlinkedVariable variable = |
| 1429 serializeVariableText('const v = true && false;'); |
| 1430 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1431 UnlinkedConstOperation.pushTrue, |
| 1432 UnlinkedConstOperation.pushFalse, |
| 1433 UnlinkedConstOperation.and |
| 1434 ]); |
| 1435 } |
| 1436 |
| 1437 test_constExpr_binary_bitAnd() { |
| 1438 UnlinkedVariable variable = serializeVariableText('const v = 1 & 2;'); |
| 1439 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1440 UnlinkedConstOperation.pushInt, |
| 1441 UnlinkedConstOperation.pushInt, |
| 1442 UnlinkedConstOperation.bitAnd |
| 1443 ], ints: [ |
| 1444 1, |
| 1445 2 |
| 1446 ]); |
| 1447 } |
| 1448 |
| 1449 test_constExpr_binary_bitOr() { |
| 1450 UnlinkedVariable variable = serializeVariableText('const v = 1 | 2;'); |
| 1451 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1452 UnlinkedConstOperation.pushInt, |
| 1453 UnlinkedConstOperation.pushInt, |
| 1454 UnlinkedConstOperation.bitOr |
| 1455 ], ints: [ |
| 1456 1, |
| 1457 2 |
| 1458 ]); |
| 1459 } |
| 1460 |
| 1461 test_constExpr_binary_bitShiftLeft() { |
| 1462 UnlinkedVariable variable = serializeVariableText('const v = 1 << 2;'); |
| 1463 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1464 UnlinkedConstOperation.pushInt, |
| 1465 UnlinkedConstOperation.pushInt, |
| 1466 UnlinkedConstOperation.bitShiftLeft |
| 1467 ], ints: [ |
| 1468 1, |
| 1469 2 |
| 1470 ]); |
| 1471 } |
| 1472 |
| 1473 test_constExpr_binary_bitShiftRight() { |
| 1474 UnlinkedVariable variable = serializeVariableText('const v = 1 >> 2;'); |
| 1475 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1476 UnlinkedConstOperation.pushInt, |
| 1477 UnlinkedConstOperation.pushInt, |
| 1478 UnlinkedConstOperation.bitShiftRight |
| 1479 ], ints: [ |
| 1480 1, |
| 1481 2 |
| 1482 ]); |
| 1483 } |
| 1484 |
| 1485 test_constExpr_binary_bitXor() { |
| 1486 UnlinkedVariable variable = serializeVariableText('const v = 1 ^ 2;'); |
| 1487 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1488 UnlinkedConstOperation.pushInt, |
| 1489 UnlinkedConstOperation.pushInt, |
| 1490 UnlinkedConstOperation.bitXor |
| 1491 ], ints: [ |
| 1492 1, |
| 1493 2 |
| 1494 ]); |
| 1495 } |
| 1496 |
| 1497 test_constExpr_binary_divide() { |
| 1498 UnlinkedVariable variable = serializeVariableText('const v = 1 / 2;'); |
| 1499 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1500 UnlinkedConstOperation.pushInt, |
| 1501 UnlinkedConstOperation.pushInt, |
| 1502 UnlinkedConstOperation.divide |
| 1503 ], ints: [ |
| 1504 1, |
| 1505 2 |
| 1506 ]); |
| 1507 } |
| 1508 |
| 1509 test_constExpr_binary_equal() { |
| 1510 UnlinkedVariable variable = serializeVariableText('const v = 1 == 2;'); |
| 1511 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1512 UnlinkedConstOperation.pushInt, |
| 1513 UnlinkedConstOperation.pushInt, |
| 1514 UnlinkedConstOperation.equal |
| 1515 ], ints: [ |
| 1516 1, |
| 1517 2 |
| 1518 ]); |
| 1519 } |
| 1520 |
| 1521 test_constExpr_binary_equal_not() { |
| 1522 UnlinkedVariable variable = serializeVariableText('const v = 1 != 2;'); |
| 1523 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1524 UnlinkedConstOperation.pushInt, |
| 1525 UnlinkedConstOperation.pushInt, |
| 1526 UnlinkedConstOperation.notEqual |
| 1527 ], ints: [ |
| 1528 1, |
| 1529 2 |
| 1530 ]); |
| 1531 } |
| 1532 |
| 1533 test_constExpr_binary_floorDivide() { |
| 1534 UnlinkedVariable variable = serializeVariableText('const v = 1 ~/ 2;'); |
| 1535 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1536 UnlinkedConstOperation.pushInt, |
| 1537 UnlinkedConstOperation.pushInt, |
| 1538 UnlinkedConstOperation.floorDivide |
| 1539 ], ints: [ |
| 1540 1, |
| 1541 2 |
| 1542 ]); |
| 1543 } |
| 1544 |
| 1545 test_constExpr_binary_greater() { |
| 1546 UnlinkedVariable variable = serializeVariableText('const v = 1 > 2;'); |
| 1547 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1548 UnlinkedConstOperation.pushInt, |
| 1549 UnlinkedConstOperation.pushInt, |
| 1550 UnlinkedConstOperation.greater |
| 1551 ], ints: [ |
| 1552 1, |
| 1553 2 |
| 1554 ]); |
| 1555 } |
| 1556 |
| 1557 test_constExpr_binary_greaterEqual() { |
| 1558 UnlinkedVariable variable = serializeVariableText('const v = 1 >= 2;'); |
| 1559 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1560 UnlinkedConstOperation.pushInt, |
| 1561 UnlinkedConstOperation.pushInt, |
| 1562 UnlinkedConstOperation.greaterEqual |
| 1563 ], ints: [ |
| 1564 1, |
| 1565 2 |
| 1566 ]); |
| 1567 } |
| 1568 |
| 1569 test_constExpr_binary_less() { |
| 1570 UnlinkedVariable variable = serializeVariableText('const v = 1 < 2;'); |
| 1571 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1572 UnlinkedConstOperation.pushInt, |
| 1573 UnlinkedConstOperation.pushInt, |
| 1574 UnlinkedConstOperation.less |
| 1575 ], ints: [ |
| 1576 1, |
| 1577 2 |
| 1578 ]); |
| 1579 } |
| 1580 |
| 1581 test_constExpr_binary_lessEqual() { |
| 1582 UnlinkedVariable variable = serializeVariableText('const v = 1 <= 2;'); |
| 1583 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1584 UnlinkedConstOperation.pushInt, |
| 1585 UnlinkedConstOperation.pushInt, |
| 1586 UnlinkedConstOperation.lessEqual |
| 1587 ], ints: [ |
| 1588 1, |
| 1589 2 |
| 1590 ]); |
| 1591 } |
| 1592 |
| 1593 test_constExpr_binary_modulo() { |
| 1594 UnlinkedVariable variable = serializeVariableText('const v = 1 % 2;'); |
| 1595 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1596 UnlinkedConstOperation.pushInt, |
| 1597 UnlinkedConstOperation.pushInt, |
| 1598 UnlinkedConstOperation.modulo |
| 1599 ], ints: [ |
| 1600 1, |
| 1601 2 |
| 1602 ]); |
| 1603 } |
| 1604 |
| 1605 test_constExpr_binary_multiply() { |
| 1606 UnlinkedVariable variable = serializeVariableText('const v = 1 * 2;'); |
| 1607 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1608 UnlinkedConstOperation.pushInt, |
| 1609 UnlinkedConstOperation.pushInt, |
| 1610 UnlinkedConstOperation.multiply |
| 1611 ], ints: [ |
| 1612 1, |
| 1613 2 |
| 1614 ]); |
| 1615 } |
| 1616 |
| 1617 test_constExpr_binary_or() { |
| 1618 UnlinkedVariable variable = |
| 1619 serializeVariableText('const v = false || true;'); |
| 1620 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1621 UnlinkedConstOperation.pushFalse, |
| 1622 UnlinkedConstOperation.pushTrue, |
| 1623 UnlinkedConstOperation.or |
| 1624 ]); |
| 1625 } |
| 1626 |
| 1627 test_constExpr_binary_subtract() { |
| 1628 UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;'); |
| 1629 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1630 UnlinkedConstOperation.pushInt, |
| 1631 UnlinkedConstOperation.pushInt, |
| 1632 UnlinkedConstOperation.subtract |
| 1633 ], ints: [ |
| 1634 1, |
| 1635 2 |
| 1636 ]); |
| 1637 } |
| 1638 |
| 1639 test_constExpr_classMember_shadows_typeParam() { |
| 1640 // Although it is an error for a class member to have the same name as a |
| 1641 // type parameter, the spec makes it clear that the class member scope is |
| 1642 // nested inside the type parameter scope. So go ahead and verify that |
| 1643 // the class member shadows the type parameter. |
| 1644 String text = ''' |
| 1645 class C<T> { |
| 1646 static const T = null; |
| 1647 final x; |
| 1648 const C() : x = T; |
| 1649 } |
| 1650 '''; |
| 1651 UnlinkedClass cls = serializeClassText(text, allowErrors: true); |
| 1652 _assertUnlinkedConst(cls.executables[0].constantInitializers[0].expression, |
| 1653 operators: [ |
| 1654 UnlinkedConstOperation.pushReference |
| 1655 ], |
| 1656 referenceValidators: [ |
| 1657 (EntityRef r) => checkTypeRef(r, null, null, 'T', |
| 1658 expectedKind: ReferenceKind.propertyAccessor, |
| 1659 prefixExpectations: [ |
| 1660 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 1661 numTypeParameters: 1) |
| 1662 ]) |
| 1663 ]); |
| 1664 } |
| 1665 |
| 1666 test_constExpr_conditional() { |
| 1667 UnlinkedVariable variable = |
| 1668 serializeVariableText('const v = true ? 1 : 2;', allowErrors: true); |
| 1669 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1670 UnlinkedConstOperation.pushTrue, |
| 1671 UnlinkedConstOperation.pushInt, |
| 1672 UnlinkedConstOperation.pushInt, |
| 1673 UnlinkedConstOperation.conditional |
| 1674 ], ints: [ |
| 1675 1, |
| 1676 2 |
| 1677 ]); |
| 1678 } |
| 1679 |
| 1680 test_constExpr_constructorParam_shadows_classMember() { |
| 1681 UnlinkedClass cls = serializeClassText(''' |
| 1682 class C { |
| 1683 static const a = null; |
| 1684 final b; |
| 1685 const C(a) : b = a; |
| 1686 } |
| 1687 '''); |
| 1688 _assertUnlinkedConst(cls.executables[0].constantInitializers[0].expression, |
| 1689 operators: [UnlinkedConstOperation.pushParameter], strings: ['a']); |
| 1690 } |
| 1691 |
| 1692 test_constExpr_constructorParam_shadows_typeParam() { |
| 1693 UnlinkedClass cls = serializeClassText(''' |
| 1694 class C<T> { |
| 1695 final x; |
| 1696 const C(T) : x = T; |
| 1697 } |
| 1698 '''); |
| 1699 _assertUnlinkedConst(cls.executables[0].constantInitializers[0].expression, |
| 1700 operators: [UnlinkedConstOperation.pushParameter], strings: ['T']); |
| 1701 } |
| 1702 |
| 1703 test_constExpr_functionExpression_asArgument() { |
| 1704 // Even though function expressions are not allowed in constant |
| 1705 // declarations, they might occur due to erroneous code, so make sure they |
| 1706 // function correctly. |
| 1707 UnlinkedVariable variable = serializeVariableText(''' |
| 1708 const v = foo(5, () => 42); |
| 1709 foo(a, b) {} |
| 1710 '''); |
| 1711 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 1712 isValidConst: false, |
| 1713 operators: [ |
| 1714 UnlinkedConstOperation.pushInt, |
| 1715 UnlinkedConstOperation.pushLocalFunctionReference, |
| 1716 UnlinkedConstOperation.invokeMethodRef |
| 1717 ], |
| 1718 ints: [ |
| 1719 5, |
| 1720 0, |
| 1721 0, |
| 1722 0, |
| 1723 2, |
| 1724 0 |
| 1725 ], |
| 1726 referenceValidators: [ |
| 1727 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 1728 expectedKind: ReferenceKind.topLevelFunction) |
| 1729 ]); |
| 1730 } |
| 1731 |
| 1732 test_constExpr_functionExpression_asArgument_multiple() { |
| 1733 // Even though function expressions are not allowed in constant |
| 1734 // declarations, they might occur due to erroneous code, so make sure they |
| 1735 // function correctly. |
| 1736 UnlinkedVariable variable = serializeVariableText(''' |
| 1737 const v = foo(5, () => 42, () => 43); |
| 1738 foo(a, b, c) {} |
| 1739 '''); |
| 1740 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 1741 isValidConst: false, |
| 1742 operators: [ |
| 1743 UnlinkedConstOperation.pushInt, |
| 1744 UnlinkedConstOperation.pushLocalFunctionReference, |
| 1745 UnlinkedConstOperation.pushLocalFunctionReference, |
| 1746 UnlinkedConstOperation.invokeMethodRef |
| 1747 ], |
| 1748 ints: [ |
| 1749 5, |
| 1750 0, |
| 1751 0, |
| 1752 0, |
| 1753 1, |
| 1754 0, |
| 1755 3, |
| 1756 0 |
| 1757 ], |
| 1758 referenceValidators: [ |
| 1759 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 1760 expectedKind: ReferenceKind.topLevelFunction) |
| 1761 ]); |
| 1762 } |
| 1763 |
| 1764 test_constExpr_functionExpression_inConstructorInitializers() { |
| 1765 // Even though function expressions are not allowed in constant |
| 1766 // declarations, they might occur due to erroneous code, so make sure they |
| 1767 // function correctly. |
| 1768 UnlinkedExecutable executable = serializeClassText(''' |
| 1769 class C { |
| 1770 final x, y; |
| 1771 const C() : x = (() => 42), y = (() => 43); |
| 1772 } |
| 1773 ''').executables[0]; |
| 1774 expect(executable.localFunctions, hasLength(2)); |
| 1775 _assertUnlinkedConst(executable.constantInitializers[0].expression, |
| 1776 isValidConst: false, |
| 1777 operators: [UnlinkedConstOperation.pushLocalFunctionReference], |
| 1778 ints: [0, 0]); |
| 1779 _assertUnlinkedConst(executable.constantInitializers[1].expression, |
| 1780 isValidConst: false, |
| 1781 operators: [UnlinkedConstOperation.pushLocalFunctionReference], |
| 1782 ints: [0, 1]); |
| 1783 } |
| 1784 |
| 1785 test_constExpr_invokeConstructor_generic_named() { |
| 1786 UnlinkedVariable variable = serializeVariableText(''' |
| 1787 class C<K, V> { |
| 1788 const C.named(); |
| 1789 } |
| 1790 const v = const C<int, String>.named(); |
| 1791 '''); |
| 1792 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1793 UnlinkedConstOperation.invokeConstructor, |
| 1794 ], ints: [ |
| 1795 0, |
| 1796 0 |
| 1797 ], referenceValidators: [ |
| 1798 (EntityRef r) { |
| 1799 checkTypeRef(r, null, null, 'named', |
| 1800 expectedKind: ReferenceKind.constructor, |
| 1801 prefixExpectations: [ |
| 1802 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 1803 numTypeParameters: 2) |
| 1804 ], |
| 1805 numTypeArguments: 2); |
| 1806 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1807 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1808 } |
| 1809 ]); |
| 1810 } |
| 1811 |
| 1812 test_constExpr_invokeConstructor_generic_named_imported() { |
| 1813 addNamedSource( |
| 1814 '/a.dart', |
| 1815 ''' |
| 1816 class C<K, V> { |
| 1817 const C.named(); |
| 1818 } |
| 1819 '''); |
| 1820 UnlinkedVariable variable = serializeVariableText(''' |
| 1821 import 'a.dart'; |
| 1822 const v = const C<int, String>.named(); |
| 1823 '''); |
| 1824 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1825 UnlinkedConstOperation.invokeConstructor, |
| 1826 ], ints: [ |
| 1827 0, |
| 1828 0 |
| 1829 ], referenceValidators: [ |
| 1830 (EntityRef r) { |
| 1831 checkTypeRef(r, null, null, 'named', |
| 1832 expectedKind: ReferenceKind.constructor, |
| 1833 prefixExpectations: [ |
| 1834 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 1835 absoluteUri: absUri('/a.dart'), |
| 1836 relativeUri: 'a.dart', |
| 1837 numTypeParameters: 2) |
| 1838 ], |
| 1839 numTypeArguments: 2); |
| 1840 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1841 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1842 } |
| 1843 ]); |
| 1844 } |
| 1845 |
| 1846 test_constExpr_invokeConstructor_generic_named_imported_withPrefix() { |
| 1847 addNamedSource( |
| 1848 '/a.dart', |
| 1849 ''' |
| 1850 class C<K, V> { |
| 1851 const C.named(); |
| 1852 } |
| 1853 '''); |
| 1854 UnlinkedVariable variable = serializeVariableText(''' |
| 1855 import 'a.dart' as p; |
| 1856 const v = const p.C<int, String>.named(); |
| 1857 '''); |
| 1858 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1859 UnlinkedConstOperation.invokeConstructor, |
| 1860 ], ints: [ |
| 1861 0, |
| 1862 0 |
| 1863 ], referenceValidators: [ |
| 1864 (EntityRef r) { |
| 1865 checkTypeRef(r, null, null, 'named', |
| 1866 expectedKind: ReferenceKind.constructor, |
| 1867 prefixExpectations: [ |
| 1868 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 1869 absoluteUri: absUri('/a.dart'), |
| 1870 relativeUri: 'a.dart', |
| 1871 numTypeParameters: 2), |
| 1872 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 1873 ], |
| 1874 numTypeArguments: 2); |
| 1875 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1876 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1877 } |
| 1878 ]); |
| 1879 } |
| 1880 |
| 1881 test_constExpr_invokeConstructor_generic_unnamed() { |
| 1882 UnlinkedVariable variable = serializeVariableText(''' |
| 1883 class C<K, V> { |
| 1884 const C(); |
| 1885 } |
| 1886 const v = const C<int, String>(); |
| 1887 '''); |
| 1888 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1889 UnlinkedConstOperation.invokeConstructor, |
| 1890 ], ints: [ |
| 1891 0, |
| 1892 0 |
| 1893 ], referenceValidators: [ |
| 1894 (EntityRef r) { |
| 1895 checkTypeRef(r, null, null, 'C', |
| 1896 expectedKind: ReferenceKind.classOrEnum, |
| 1897 numTypeParameters: 2, |
| 1898 numTypeArguments: 2); |
| 1899 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1900 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1901 } |
| 1902 ]); |
| 1903 } |
| 1904 |
| 1905 test_constExpr_invokeConstructor_generic_unnamed_imported() { |
| 1906 addNamedSource( |
| 1907 '/a.dart', |
| 1908 ''' |
| 1909 class C<K, V> { |
| 1910 const C(); |
| 1911 } |
| 1912 '''); |
| 1913 UnlinkedVariable variable = serializeVariableText(''' |
| 1914 import 'a.dart'; |
| 1915 const v = const C<int, String>(); |
| 1916 '''); |
| 1917 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1918 UnlinkedConstOperation.invokeConstructor, |
| 1919 ], ints: [ |
| 1920 0, |
| 1921 0 |
| 1922 ], referenceValidators: [ |
| 1923 (EntityRef r) { |
| 1924 checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C', |
| 1925 expectedKind: ReferenceKind.classOrEnum, |
| 1926 numTypeParameters: 2, |
| 1927 numTypeArguments: 2); |
| 1928 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1929 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1930 } |
| 1931 ]); |
| 1932 } |
| 1933 |
| 1934 test_constExpr_invokeConstructor_generic_unnamed_imported_withPrefix() { |
| 1935 addNamedSource( |
| 1936 '/a.dart', |
| 1937 ''' |
| 1938 class C<K, V> { |
| 1939 const C(); |
| 1940 } |
| 1941 '''); |
| 1942 UnlinkedVariable variable = serializeVariableText(''' |
| 1943 import 'a.dart' as p; |
| 1944 const v = const p.C<int, String>(); |
| 1945 '''); |
| 1946 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1947 UnlinkedConstOperation.invokeConstructor, |
| 1948 ], ints: [ |
| 1949 0, |
| 1950 0 |
| 1951 ], referenceValidators: [ |
| 1952 (EntityRef r) { |
| 1953 checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C', |
| 1954 expectedKind: ReferenceKind.classOrEnum, |
| 1955 numTypeParameters: 2, |
| 1956 numTypeArguments: 2, |
| 1957 prefixExpectations: [ |
| 1958 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 1959 ]); |
| 1960 checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 1961 checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String'); |
| 1962 } |
| 1963 ]); |
| 1964 } |
| 1965 |
| 1966 test_constExpr_invokeConstructor_named() { |
| 1967 UnlinkedVariable variable = serializeVariableText(''' |
| 1968 class C { |
| 1969 const C.named(); |
| 1970 } |
| 1971 const v = const C.named(); |
| 1972 '''); |
| 1973 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 1974 UnlinkedConstOperation.invokeConstructor, |
| 1975 ], ints: [ |
| 1976 0, |
| 1977 0 |
| 1978 ], referenceValidators: [ |
| 1979 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 1980 expectedKind: ReferenceKind.constructor, |
| 1981 prefixExpectations: [ |
| 1982 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 1983 ]) |
| 1984 ]); |
| 1985 } |
| 1986 |
| 1987 test_constExpr_invokeConstructor_named_imported() { |
| 1988 addNamedSource( |
| 1989 '/a.dart', |
| 1990 ''' |
| 1991 class C { |
| 1992 const C.named(); |
| 1993 } |
| 1994 '''); |
| 1995 UnlinkedVariable variable = serializeVariableText(''' |
| 1996 import 'a.dart'; |
| 1997 const v = const C.named(); |
| 1998 '''); |
| 1999 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2000 UnlinkedConstOperation.invokeConstructor, |
| 2001 ], ints: [ |
| 2002 0, |
| 2003 0 |
| 2004 ], referenceValidators: [ |
| 2005 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 2006 expectedKind: ReferenceKind.constructor, |
| 2007 prefixExpectations: [ |
| 2008 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2009 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2010 ]) |
| 2011 ]); |
| 2012 } |
| 2013 |
| 2014 test_constExpr_invokeConstructor_named_imported_withPrefix() { |
| 2015 addNamedSource( |
| 2016 '/a.dart', |
| 2017 ''' |
| 2018 class C { |
| 2019 const C.named(); |
| 2020 } |
| 2021 '''); |
| 2022 UnlinkedVariable variable = serializeVariableText(''' |
| 2023 import 'a.dart' as p; |
| 2024 const v = const p.C.named(); |
| 2025 '''); |
| 2026 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2027 UnlinkedConstOperation.invokeConstructor, |
| 2028 ], ints: [ |
| 2029 0, |
| 2030 0 |
| 2031 ], referenceValidators: [ |
| 2032 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 2033 expectedKind: ReferenceKind.constructor, |
| 2034 prefixExpectations: [ |
| 2035 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2036 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2037 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2038 ]) |
| 2039 ]); |
| 2040 } |
| 2041 |
| 2042 test_constExpr_invokeConstructor_unnamed() { |
| 2043 UnlinkedVariable variable = serializeVariableText(''' |
| 2044 class C { |
| 2045 const C(a, b, c, d, {e, f, g}); |
| 2046 } |
| 2047 const v = const C(11, 22, 3.3, '444', e: 55, g: '777', f: 66); |
| 2048 '''); |
| 2049 // Stack: 11 22 3.3 '444' 55 '777' 66 ^head |
| 2050 // Ints: ^pointer 3 4 |
| 2051 // Doubles: ^pointer |
| 2052 // Strings: ^pointer 'e' 'g' 'f' '' |
| 2053 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2054 UnlinkedConstOperation.pushInt, |
| 2055 UnlinkedConstOperation.pushInt, |
| 2056 UnlinkedConstOperation.pushDouble, |
| 2057 UnlinkedConstOperation.pushString, |
| 2058 UnlinkedConstOperation.pushInt, |
| 2059 UnlinkedConstOperation.pushString, |
| 2060 UnlinkedConstOperation.pushInt, |
| 2061 UnlinkedConstOperation.invokeConstructor, |
| 2062 ], ints: [ |
| 2063 11, |
| 2064 22, |
| 2065 55, |
| 2066 66, |
| 2067 3, |
| 2068 4, |
| 2069 ], doubles: [ |
| 2070 3.3 |
| 2071 ], strings: [ |
| 2072 '444', |
| 2073 '777', |
| 2074 'e', |
| 2075 'g', |
| 2076 'f' |
| 2077 ], referenceValidators: [ |
| 2078 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 2079 expectedKind: ReferenceKind.classOrEnum) |
| 2080 ]); |
| 2081 } |
| 2082 |
| 2083 test_constExpr_invokeConstructor_unnamed_imported() { |
| 2084 addNamedSource( |
| 2085 '/a.dart', |
| 2086 ''' |
| 2087 class C { |
| 2088 const C(); |
| 2089 } |
| 2090 '''); |
| 2091 UnlinkedVariable variable = serializeVariableText(''' |
| 2092 import 'a.dart'; |
| 2093 const v = const C(); |
| 2094 '''); |
| 2095 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2096 UnlinkedConstOperation.invokeConstructor, |
| 2097 ], ints: [ |
| 2098 0, |
| 2099 0 |
| 2100 ], referenceValidators: [ |
| 2101 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C', |
| 2102 expectedKind: ReferenceKind.classOrEnum) |
| 2103 ]); |
| 2104 } |
| 2105 |
| 2106 test_constExpr_invokeConstructor_unnamed_imported_withPrefix() { |
| 2107 addNamedSource( |
| 2108 '/a.dart', |
| 2109 ''' |
| 2110 class C { |
| 2111 const C(); |
| 2112 } |
| 2113 '''); |
| 2114 UnlinkedVariable variable = serializeVariableText(''' |
| 2115 import 'a.dart' as p; |
| 2116 const v = const p.C(); |
| 2117 '''); |
| 2118 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2119 UnlinkedConstOperation.invokeConstructor, |
| 2120 ], ints: [ |
| 2121 0, |
| 2122 0 |
| 2123 ], referenceValidators: [ |
| 2124 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C', |
| 2125 expectedKind: ReferenceKind.classOrEnum, |
| 2126 prefixExpectations: [ |
| 2127 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2128 ]) |
| 2129 ]); |
| 2130 } |
| 2131 |
| 2132 test_constExpr_invokeConstructor_unresolved_named() { |
| 2133 UnlinkedVariable variable = serializeVariableText( |
| 2134 ''' |
| 2135 class C {} |
| 2136 const v = const C.foo(); |
| 2137 ''', |
| 2138 allowErrors: true); |
| 2139 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2140 UnlinkedConstOperation.invokeConstructor, |
| 2141 ], ints: [ |
| 2142 0, |
| 2143 0 |
| 2144 ], referenceValidators: [ |
| 2145 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 2146 expectedKind: ReferenceKind.unresolved, |
| 2147 prefixExpectations: [ |
| 2148 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2149 ]) |
| 2150 ]); |
| 2151 } |
| 2152 |
| 2153 test_constExpr_invokeConstructor_unresolved_named2() { |
| 2154 UnlinkedVariable variable = serializeVariableText( |
| 2155 ''' |
| 2156 const v = const C.foo(); |
| 2157 ''', |
| 2158 allowErrors: true); |
| 2159 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2160 UnlinkedConstOperation.invokeConstructor, |
| 2161 ], ints: [ |
| 2162 0, |
| 2163 0 |
| 2164 ], referenceValidators: [ |
| 2165 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 2166 expectedKind: ReferenceKind.unresolved, |
| 2167 prefixExpectations: [ |
| 2168 new _PrefixExpectation(ReferenceKind.unresolved, 'C') |
| 2169 ]) |
| 2170 ]); |
| 2171 } |
| 2172 |
| 2173 test_constExpr_invokeConstructor_unresolved_named_prefixed() { |
| 2174 addNamedSource( |
| 2175 '/a.dart', |
| 2176 ''' |
| 2177 class C { |
| 2178 } |
| 2179 '''); |
| 2180 UnlinkedVariable variable = serializeVariableText( |
| 2181 ''' |
| 2182 import 'a.dart' as p; |
| 2183 const v = const p.C.foo(); |
| 2184 ''', |
| 2185 allowErrors: true); |
| 2186 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2187 UnlinkedConstOperation.invokeConstructor, |
| 2188 ], ints: [ |
| 2189 0, |
| 2190 0 |
| 2191 ], referenceValidators: [ |
| 2192 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 2193 expectedKind: ReferenceKind.unresolved, |
| 2194 prefixExpectations: [ |
| 2195 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2196 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2197 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2198 ]) |
| 2199 ]); |
| 2200 } |
| 2201 |
| 2202 test_constExpr_invokeConstructor_unresolved_named_prefixed2() { |
| 2203 addNamedSource('/a.dart', ''); |
| 2204 UnlinkedVariable variable = serializeVariableText( |
| 2205 ''' |
| 2206 import 'a.dart' as p; |
| 2207 const v = const p.C.foo(); |
| 2208 ''', |
| 2209 allowErrors: true); |
| 2210 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2211 UnlinkedConstOperation.invokeConstructor, |
| 2212 ], ints: [ |
| 2213 0, |
| 2214 0 |
| 2215 ], referenceValidators: [ |
| 2216 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 2217 expectedKind: ReferenceKind.unresolved, |
| 2218 prefixExpectations: [ |
| 2219 new _PrefixExpectation(ReferenceKind.unresolved, 'C'), |
| 2220 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2221 ]) |
| 2222 ]); |
| 2223 } |
| 2224 |
| 2225 test_constExpr_invokeConstructor_unresolved_unnamed() { |
| 2226 UnlinkedVariable variable = serializeVariableText( |
| 2227 ''' |
| 2228 const v = const Foo(); |
| 2229 ''', |
| 2230 allowErrors: true); |
| 2231 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2232 UnlinkedConstOperation.invokeConstructor, |
| 2233 ], ints: [ |
| 2234 0, |
| 2235 0 |
| 2236 ], referenceValidators: [ |
| 2237 (EntityRef r) => checkTypeRef(r, null, null, 'Foo', |
| 2238 expectedKind: ReferenceKind.unresolved) |
| 2239 ]); |
| 2240 } |
| 2241 |
| 2242 test_constExpr_invokeMethodRef_identical() { |
| 2243 UnlinkedVariable variable = |
| 2244 serializeVariableText('const v = identical(42, null);'); |
| 2245 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2246 UnlinkedConstOperation.pushInt, |
| 2247 UnlinkedConstOperation.pushNull, |
| 2248 UnlinkedConstOperation.invokeMethodRef |
| 2249 ], ints: [ |
| 2250 42, |
| 2251 0, |
| 2252 2, |
| 2253 0 |
| 2254 ], referenceValidators: [ |
| 2255 (EntityRef r) { |
| 2256 checkTypeRef(r, 'dart:core', 'dart:core', 'identical', |
| 2257 expectedKind: ReferenceKind.topLevelFunction); |
| 2258 } |
| 2259 ]); |
| 2260 } |
| 2261 |
| 2262 test_constExpr_length_classConstField() { |
| 2263 UnlinkedVariable variable = serializeVariableText(''' |
| 2264 class C { |
| 2265 static const int length = 0; |
| 2266 } |
| 2267 const int v = C.length; |
| 2268 '''); |
| 2269 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2270 UnlinkedConstOperation.pushReference |
| 2271 ], referenceValidators: [ |
| 2272 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2273 expectedKind: ReferenceKind.propertyAccessor, |
| 2274 prefixExpectations: [ |
| 2275 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2276 ]) |
| 2277 ]); |
| 2278 } |
| 2279 |
| 2280 test_constExpr_length_classConstField_imported_withPrefix() { |
| 2281 addNamedSource( |
| 2282 '/a.dart', |
| 2283 ''' |
| 2284 class C { |
| 2285 static const int length = 0; |
| 2286 } |
| 2287 '''); |
| 2288 UnlinkedVariable variable = serializeVariableText(''' |
| 2289 import 'a.dart' as p; |
| 2290 const int v = p.C.length; |
| 2291 '''); |
| 2292 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2293 UnlinkedConstOperation.pushReference |
| 2294 ], referenceValidators: [ |
| 2295 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2296 expectedKind: ReferenceKind.propertyAccessor, |
| 2297 prefixExpectations: [ |
| 2298 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2299 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2300 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2301 ]) |
| 2302 ]); |
| 2303 } |
| 2304 |
| 2305 test_constExpr_length_identifierTarget() { |
| 2306 UnlinkedVariable variable = serializeVariableText(''' |
| 2307 const String a = 'aaa'; |
| 2308 const int v = a.length; |
| 2309 '''); |
| 2310 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2311 UnlinkedConstOperation.pushReference |
| 2312 ], referenceValidators: [ |
| 2313 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2314 expectedKind: ReferenceKind.unresolved, |
| 2315 unresolvedHasName: true, |
| 2316 prefixExpectations: [ |
| 2317 new _PrefixExpectation( |
| 2318 ReferenceKind.topLevelPropertyAccessor, 'a') |
| 2319 ]) |
| 2320 ]); |
| 2321 } |
| 2322 |
| 2323 test_constExpr_length_identifierTarget_classConstField() { |
| 2324 UnlinkedVariable variable = serializeVariableText(''' |
| 2325 class C { |
| 2326 static const String F = ''; |
| 2327 } |
| 2328 const int v = C.F.length; |
| 2329 '''); |
| 2330 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2331 UnlinkedConstOperation.pushReference |
| 2332 ], referenceValidators: [ |
| 2333 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2334 expectedKind: ReferenceKind.unresolved, |
| 2335 unresolvedHasName: true, |
| 2336 prefixExpectations: [ |
| 2337 new _PrefixExpectation(ReferenceKind.propertyAccessor, 'F'), |
| 2338 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'), |
| 2339 ]) |
| 2340 ]); |
| 2341 } |
| 2342 |
| 2343 test_constExpr_length_identifierTarget_imported() { |
| 2344 addNamedSource( |
| 2345 '/a.dart', |
| 2346 ''' |
| 2347 const String a = 'aaa'; |
| 2348 '''); |
| 2349 UnlinkedVariable variable = serializeVariableText(''' |
| 2350 import 'a.dart'; |
| 2351 const int v = a.length; |
| 2352 '''); |
| 2353 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2354 UnlinkedConstOperation.pushReference |
| 2355 ], referenceValidators: [ |
| 2356 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2357 expectedKind: ReferenceKind.unresolved, |
| 2358 unresolvedHasName: true, |
| 2359 prefixExpectations: [ |
| 2360 new _PrefixExpectation( |
| 2361 ReferenceKind.topLevelPropertyAccessor, 'a', |
| 2362 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2363 ]) |
| 2364 ]); |
| 2365 } |
| 2366 |
| 2367 test_constExpr_length_identifierTarget_imported_withPrefix() { |
| 2368 addNamedSource( |
| 2369 '/a.dart', |
| 2370 ''' |
| 2371 const String a = 'aaa'; |
| 2372 '''); |
| 2373 UnlinkedVariable variable = serializeVariableText(''' |
| 2374 import 'a.dart' as p; |
| 2375 const int v = p.a.length; |
| 2376 '''); |
| 2377 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2378 UnlinkedConstOperation.pushReference |
| 2379 ], referenceValidators: [ |
| 2380 (EntityRef r) => checkTypeRef(r, null, null, 'length', |
| 2381 expectedKind: ReferenceKind.unresolved, |
| 2382 unresolvedHasName: true, |
| 2383 prefixExpectations: [ |
| 2384 new _PrefixExpectation( |
| 2385 ReferenceKind.topLevelPropertyAccessor, 'a', |
| 2386 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2387 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2388 ]) |
| 2389 ]); |
| 2390 } |
| 2391 |
| 2392 test_constExpr_length_parenthesizedBinaryTarget() { |
| 2393 UnlinkedVariable variable = |
| 2394 serializeVariableText('const v = ("abc" + "edf").length;'); |
| 2395 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2396 UnlinkedConstOperation.pushString, |
| 2397 UnlinkedConstOperation.pushString, |
| 2398 UnlinkedConstOperation.add, |
| 2399 UnlinkedConstOperation.extractProperty |
| 2400 ], strings: [ |
| 2401 'abc', |
| 2402 'edf', |
| 2403 'length' |
| 2404 ]); |
| 2405 } |
| 2406 |
| 2407 test_constExpr_length_parenthesizedStringTarget() { |
| 2408 UnlinkedVariable variable = |
| 2409 serializeVariableText('const v = ("abc").length;'); |
| 2410 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2411 UnlinkedConstOperation.pushString, |
| 2412 UnlinkedConstOperation.extractProperty |
| 2413 ], strings: [ |
| 2414 'abc', |
| 2415 'length' |
| 2416 ]); |
| 2417 } |
| 2418 |
| 2419 test_constExpr_length_stringLiteralTarget() { |
| 2420 UnlinkedVariable variable = |
| 2421 serializeVariableText('const v = "abc".length;'); |
| 2422 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2423 UnlinkedConstOperation.pushString, |
| 2424 UnlinkedConstOperation.extractProperty |
| 2425 ], strings: [ |
| 2426 'abc', |
| 2427 'length' |
| 2428 ]); |
| 2429 } |
| 2430 |
| 2431 test_constExpr_makeSymbol() { |
| 2432 UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;'); |
| 2433 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2434 operators: [UnlinkedConstOperation.makeSymbol], strings: ['a.bb.ccc']); |
| 2435 } |
| 2436 |
| 2437 test_constExpr_makeTypedList() { |
| 2438 UnlinkedVariable variable = |
| 2439 serializeVariableText('const v = const <int>[11, 22, 33];'); |
| 2440 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2441 UnlinkedConstOperation.pushInt, |
| 2442 UnlinkedConstOperation.pushInt, |
| 2443 UnlinkedConstOperation.pushInt, |
| 2444 UnlinkedConstOperation.makeTypedList |
| 2445 ], ints: [ |
| 2446 11, |
| 2447 22, |
| 2448 33, |
| 2449 3 |
| 2450 ], referenceValidators: [ |
| 2451 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int', |
| 2452 expectedKind: ReferenceKind.classOrEnum) |
| 2453 ]); |
| 2454 } |
| 2455 |
| 2456 test_constExpr_makeTypedList_dynamic() { |
| 2457 UnlinkedVariable variable = |
| 2458 serializeVariableText('const v = const <dynamic>[11, 22, 33];'); |
| 2459 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2460 UnlinkedConstOperation.pushInt, |
| 2461 UnlinkedConstOperation.pushInt, |
| 2462 UnlinkedConstOperation.pushInt, |
| 2463 UnlinkedConstOperation.makeTypedList |
| 2464 ], ints: [ |
| 2465 11, |
| 2466 22, |
| 2467 33, |
| 2468 3 |
| 2469 ], referenceValidators: [ |
| 2470 (EntityRef r) => checkDynamicTypeRef(r) |
| 2471 ]); |
| 2472 } |
| 2473 |
| 2474 test_constExpr_makeTypedMap() { |
| 2475 UnlinkedVariable variable = serializeVariableText( |
| 2476 'const v = const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};'); |
| 2477 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2478 UnlinkedConstOperation.pushInt, |
| 2479 UnlinkedConstOperation.pushString, |
| 2480 UnlinkedConstOperation.pushInt, |
| 2481 UnlinkedConstOperation.pushString, |
| 2482 UnlinkedConstOperation.pushInt, |
| 2483 UnlinkedConstOperation.pushString, |
| 2484 UnlinkedConstOperation.makeTypedMap |
| 2485 ], ints: [ |
| 2486 11, |
| 2487 22, |
| 2488 33, |
| 2489 3 |
| 2490 ], strings: [ |
| 2491 'aaa', |
| 2492 'bbb', |
| 2493 'ccc' |
| 2494 ], referenceValidators: [ |
| 2495 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int', |
| 2496 expectedKind: ReferenceKind.classOrEnum), |
| 2497 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String', |
| 2498 expectedKind: ReferenceKind.classOrEnum) |
| 2499 ]); |
| 2500 } |
| 2501 |
| 2502 test_constExpr_makeTypedMap_dynamic() { |
| 2503 UnlinkedVariable variable = serializeVariableText( |
| 2504 'const v = const <dynamic, dynamic>{11: "aaa", 22: "bbb", 33: "ccc"};'); |
| 2505 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2506 UnlinkedConstOperation.pushInt, |
| 2507 UnlinkedConstOperation.pushString, |
| 2508 UnlinkedConstOperation.pushInt, |
| 2509 UnlinkedConstOperation.pushString, |
| 2510 UnlinkedConstOperation.pushInt, |
| 2511 UnlinkedConstOperation.pushString, |
| 2512 UnlinkedConstOperation.makeTypedMap |
| 2513 ], ints: [ |
| 2514 11, |
| 2515 22, |
| 2516 33, |
| 2517 3 |
| 2518 ], strings: [ |
| 2519 'aaa', |
| 2520 'bbb', |
| 2521 'ccc' |
| 2522 ], referenceValidators: [ |
| 2523 (EntityRef r) => checkDynamicTypeRef(r), |
| 2524 (EntityRef r) => checkDynamicTypeRef(r) |
| 2525 ]); |
| 2526 } |
| 2527 |
| 2528 test_constExpr_makeUntypedList() { |
| 2529 UnlinkedVariable variable = |
| 2530 serializeVariableText('const v = const [11, 22, 33];'); |
| 2531 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2532 UnlinkedConstOperation.pushInt, |
| 2533 UnlinkedConstOperation.pushInt, |
| 2534 UnlinkedConstOperation.pushInt, |
| 2535 UnlinkedConstOperation.makeUntypedList |
| 2536 ], ints: [ |
| 2537 11, |
| 2538 22, |
| 2539 33, |
| 2540 3 |
| 2541 ]); |
| 2542 } |
| 2543 |
| 2544 test_constExpr_makeUntypedMap() { |
| 2545 UnlinkedVariable variable = serializeVariableText( |
| 2546 'const v = const {11: "aaa", 22: "bbb", 33: "ccc"};'); |
| 2547 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2548 UnlinkedConstOperation.pushInt, |
| 2549 UnlinkedConstOperation.pushString, |
| 2550 UnlinkedConstOperation.pushInt, |
| 2551 UnlinkedConstOperation.pushString, |
| 2552 UnlinkedConstOperation.pushInt, |
| 2553 UnlinkedConstOperation.pushString, |
| 2554 UnlinkedConstOperation.makeUntypedMap |
| 2555 ], ints: [ |
| 2556 11, |
| 2557 22, |
| 2558 33, |
| 2559 3 |
| 2560 ], strings: [ |
| 2561 'aaa', |
| 2562 'bbb', |
| 2563 'ccc' |
| 2564 ]); |
| 2565 } |
| 2566 |
| 2567 test_constExpr_parenthesized() { |
| 2568 UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;'); |
| 2569 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2570 UnlinkedConstOperation.pushInt, |
| 2571 UnlinkedConstOperation.pushInt, |
| 2572 UnlinkedConstOperation.add, |
| 2573 UnlinkedConstOperation.pushInt, |
| 2574 UnlinkedConstOperation.multiply, |
| 2575 ], ints: [ |
| 2576 1, |
| 2577 2, |
| 2578 3 |
| 2579 ]); |
| 2580 } |
| 2581 |
| 2582 test_constExpr_prefix_complement() { |
| 2583 UnlinkedVariable variable = serializeVariableText('const v = ~2;'); |
| 2584 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2585 UnlinkedConstOperation.pushInt, |
| 2586 UnlinkedConstOperation.complement |
| 2587 ], ints: [ |
| 2588 2 |
| 2589 ]); |
| 2590 } |
| 2591 |
| 2592 test_constExpr_prefix_negate() { |
| 2593 UnlinkedVariable variable = serializeVariableText('const v = -(2);'); |
| 2594 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2595 UnlinkedConstOperation.pushInt, |
| 2596 UnlinkedConstOperation.negate |
| 2597 ], ints: [ |
| 2598 2 |
| 2599 ]); |
| 2600 } |
| 2601 |
| 2602 test_constExpr_prefix_not() { |
| 2603 UnlinkedVariable variable = serializeVariableText('const v = !true;'); |
| 2604 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2605 UnlinkedConstOperation.pushTrue, |
| 2606 UnlinkedConstOperation.not |
| 2607 ]); |
| 2608 } |
| 2609 |
| 2610 test_constExpr_pushDouble() { |
| 2611 UnlinkedVariable variable = serializeVariableText('const v = 123.4567;'); |
| 2612 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2613 operators: [UnlinkedConstOperation.pushDouble], doubles: [123.4567]); |
| 2614 } |
| 2615 |
| 2616 test_constExpr_pushFalse() { |
| 2617 UnlinkedVariable variable = serializeVariableText('const v = false;'); |
| 2618 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2619 operators: [UnlinkedConstOperation.pushFalse]); |
| 2620 } |
| 2621 |
| 2622 test_constExpr_pushInt() { |
| 2623 UnlinkedVariable variable = serializeVariableText('const v = 1;'); |
| 2624 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2625 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 2626 } |
| 2627 |
| 2628 test_constExpr_pushInt_max() { |
| 2629 UnlinkedVariable variable = serializeVariableText('const v = 0xFFFFFFFF;'); |
| 2630 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2631 UnlinkedConstOperation.pushInt, |
| 2632 ], ints: [ |
| 2633 0xFFFFFFFF |
| 2634 ]); |
| 2635 } |
| 2636 |
| 2637 test_constExpr_pushInt_negative() { |
| 2638 UnlinkedVariable variable = serializeVariableText('const v = -5;'); |
| 2639 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2640 UnlinkedConstOperation.pushInt, |
| 2641 UnlinkedConstOperation.negate |
| 2642 ], ints: [ |
| 2643 5 |
| 2644 ]); |
| 2645 } |
| 2646 |
| 2647 test_constExpr_pushLongInt() { |
| 2648 UnlinkedVariable variable = |
| 2649 serializeVariableText('const v = 0xA123456789ABCDEF012345678;'); |
| 2650 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2651 operators: [UnlinkedConstOperation.pushLongInt], |
| 2652 ints: [4, 0xA, 0x12345678, 0x9ABCDEF0, 0x12345678]); |
| 2653 } |
| 2654 |
| 2655 test_constExpr_pushLongInt_min2() { |
| 2656 UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;'); |
| 2657 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2658 UnlinkedConstOperation.pushLongInt |
| 2659 ], ints: [ |
| 2660 2, |
| 2661 1, |
| 2662 0, |
| 2663 ]); |
| 2664 } |
| 2665 |
| 2666 test_constExpr_pushLongInt_min3() { |
| 2667 UnlinkedVariable variable = |
| 2668 serializeVariableText('const v = 0x10000000000000000;'); |
| 2669 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2670 UnlinkedConstOperation.pushLongInt |
| 2671 ], ints: [ |
| 2672 3, |
| 2673 1, |
| 2674 0, |
| 2675 0, |
| 2676 ]); |
| 2677 } |
| 2678 |
| 2679 test_constExpr_pushNull() { |
| 2680 UnlinkedVariable variable = serializeVariableText('const v = null;'); |
| 2681 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 2682 operators: [UnlinkedConstOperation.pushNull]); |
| 2683 } |
| 2684 |
| 2685 test_constExpr_pushReference_class() { |
| 2686 UnlinkedVariable variable = serializeVariableText(''' |
| 2687 class C {} |
| 2688 const v = C; |
| 2689 '''); |
| 2690 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2691 UnlinkedConstOperation.pushReference |
| 2692 ], referenceValidators: [ |
| 2693 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 2694 expectedKind: ReferenceKind.classOrEnum) |
| 2695 ]); |
| 2696 } |
| 2697 |
| 2698 test_constExpr_pushReference_enum() { |
| 2699 UnlinkedVariable variable = serializeVariableText(''' |
| 2700 enum C {V1, V2, V3} |
| 2701 const v = C; |
| 2702 '''); |
| 2703 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2704 UnlinkedConstOperation.pushReference |
| 2705 ], referenceValidators: [ |
| 2706 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 2707 expectedKind: ReferenceKind.classOrEnum) |
| 2708 ]); |
| 2709 } |
| 2710 |
| 2711 test_constExpr_pushReference_enumValue() { |
| 2712 UnlinkedVariable variable = serializeVariableText(''' |
| 2713 enum C {V1, V2, V3} |
| 2714 const v = C.V1; |
| 2715 '''); |
| 2716 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2717 UnlinkedConstOperation.pushReference |
| 2718 ], referenceValidators: [ |
| 2719 (EntityRef r) => checkTypeRef(r, null, null, 'V1', |
| 2720 expectedKind: ReferenceKind.propertyAccessor, |
| 2721 prefixExpectations: [ |
| 2722 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2723 ]) |
| 2724 ]); |
| 2725 } |
| 2726 |
| 2727 test_constExpr_pushReference_enumValue_viaImport() { |
| 2728 addNamedSource( |
| 2729 '/a.dart', |
| 2730 ''' |
| 2731 enum C {V1, V2, V3} |
| 2732 '''); |
| 2733 UnlinkedVariable variable = serializeVariableText(''' |
| 2734 import 'a.dart'; |
| 2735 const v = C.V1; |
| 2736 '''); |
| 2737 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2738 UnlinkedConstOperation.pushReference |
| 2739 ], referenceValidators: [ |
| 2740 (EntityRef r) => checkTypeRef(r, null, null, 'V1', |
| 2741 expectedKind: ReferenceKind.propertyAccessor, |
| 2742 prefixExpectations: [ |
| 2743 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2744 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2745 ]) |
| 2746 ]); |
| 2747 } |
| 2748 |
| 2749 test_constExpr_pushReference_enumValues() { |
| 2750 UnlinkedVariable variable = serializeVariableText(''' |
| 2751 enum C {V1, V2, V3} |
| 2752 const v = C.values; |
| 2753 '''); |
| 2754 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2755 UnlinkedConstOperation.pushReference |
| 2756 ], referenceValidators: [ |
| 2757 (EntityRef r) => checkTypeRef(r, null, null, 'values', |
| 2758 expectedKind: ReferenceKind.propertyAccessor, |
| 2759 prefixExpectations: [ |
| 2760 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2761 ]) |
| 2762 ]); |
| 2763 } |
| 2764 |
| 2765 test_constExpr_pushReference_enumValues_viaImport() { |
| 2766 addNamedSource( |
| 2767 '/a.dart', |
| 2768 ''' |
| 2769 enum C {V1, V2, V3} |
| 2770 '''); |
| 2771 UnlinkedVariable variable = serializeVariableText(''' |
| 2772 import 'a.dart'; |
| 2773 const v = C.values; |
| 2774 '''); |
| 2775 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2776 UnlinkedConstOperation.pushReference |
| 2777 ], referenceValidators: [ |
| 2778 (EntityRef r) => checkTypeRef(r, null, null, 'values', |
| 2779 expectedKind: ReferenceKind.propertyAccessor, |
| 2780 prefixExpectations: [ |
| 2781 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2782 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2783 ]) |
| 2784 ]); |
| 2785 } |
| 2786 |
| 2787 test_constExpr_pushReference_field() { |
| 2788 UnlinkedVariable variable = serializeVariableText(''' |
| 2789 class C { |
| 2790 static const int F = 1; |
| 2791 } |
| 2792 const v = C.F; |
| 2793 '''); |
| 2794 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2795 UnlinkedConstOperation.pushReference |
| 2796 ], referenceValidators: [ |
| 2797 (EntityRef r) => checkTypeRef(r, null, null, 'F', |
| 2798 expectedKind: ReferenceKind.propertyAccessor, |
| 2799 prefixExpectations: [ |
| 2800 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2801 ]) |
| 2802 ]); |
| 2803 } |
| 2804 |
| 2805 test_constExpr_pushReference_field_imported() { |
| 2806 addNamedSource( |
| 2807 '/a.dart', |
| 2808 ''' |
| 2809 class C { |
| 2810 static const int F = 1; |
| 2811 } |
| 2812 '''); |
| 2813 UnlinkedVariable variable = serializeVariableText(''' |
| 2814 import 'a.dart'; |
| 2815 const v = C.F; |
| 2816 '''); |
| 2817 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2818 UnlinkedConstOperation.pushReference |
| 2819 ], referenceValidators: [ |
| 2820 (EntityRef r) => checkTypeRef(r, null, null, 'F', |
| 2821 expectedKind: ReferenceKind.propertyAccessor, |
| 2822 prefixExpectations: [ |
| 2823 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2824 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2825 ]) |
| 2826 ]); |
| 2827 } |
| 2828 |
| 2829 test_constExpr_pushReference_field_imported_withPrefix() { |
| 2830 addNamedSource( |
| 2831 '/a.dart', |
| 2832 ''' |
| 2833 class C { |
| 2834 static const int F = 1; |
| 2835 } |
| 2836 '''); |
| 2837 UnlinkedVariable variable = serializeVariableText(''' |
| 2838 import 'a.dart' as p; |
| 2839 const v = p.C.F; |
| 2840 '''); |
| 2841 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2842 UnlinkedConstOperation.pushReference |
| 2843 ], referenceValidators: [ |
| 2844 (EntityRef r) => checkTypeRef(r, null, null, 'F', |
| 2845 expectedKind: ReferenceKind.propertyAccessor, |
| 2846 prefixExpectations: [ |
| 2847 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2848 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2849 new _PrefixExpectation(ReferenceKind.prefix, 'p'), |
| 2850 ]) |
| 2851 ]); |
| 2852 } |
| 2853 |
| 2854 test_constExpr_pushReference_field_simpleIdentifier() { |
| 2855 UnlinkedVariable variable = serializeClassText(''' |
| 2856 class C { |
| 2857 static const a = b; |
| 2858 static const b = null; |
| 2859 } |
| 2860 ''').fields[0]; |
| 2861 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2862 UnlinkedConstOperation.pushReference |
| 2863 ], referenceValidators: [ |
| 2864 (EntityRef r) => checkTypeRef(r, null, null, 'b', |
| 2865 expectedKind: ReferenceKind.propertyAccessor, |
| 2866 prefixExpectations: [ |
| 2867 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2868 ]) |
| 2869 ]); |
| 2870 } |
| 2871 |
| 2872 test_constExpr_pushReference_staticGetter() { |
| 2873 UnlinkedVariable variable = serializeVariableText(''' |
| 2874 class C { |
| 2875 static int get x => null; |
| 2876 } |
| 2877 const v = C.x; |
| 2878 '''); |
| 2879 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2880 UnlinkedConstOperation.pushReference |
| 2881 ], referenceValidators: [ |
| 2882 (EntityRef r) => checkTypeRef(r, null, null, 'x', |
| 2883 expectedKind: ReferenceKind.propertyAccessor, |
| 2884 prefixExpectations: [ |
| 2885 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2886 ]) |
| 2887 ]); |
| 2888 } |
| 2889 |
| 2890 test_constExpr_pushReference_staticGetter_imported() { |
| 2891 addNamedSource( |
| 2892 '/a.dart', |
| 2893 ''' |
| 2894 class C { |
| 2895 static int get x => null; |
| 2896 } |
| 2897 '''); |
| 2898 UnlinkedVariable variable = serializeVariableText(''' |
| 2899 import 'a.dart'; |
| 2900 const v = C.x; |
| 2901 '''); |
| 2902 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2903 UnlinkedConstOperation.pushReference |
| 2904 ], referenceValidators: [ |
| 2905 (EntityRef r) => checkTypeRef(r, null, null, 'x', |
| 2906 expectedKind: ReferenceKind.propertyAccessor, |
| 2907 prefixExpectations: [ |
| 2908 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2909 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2910 ]) |
| 2911 ]); |
| 2912 } |
| 2913 |
| 2914 test_constExpr_pushReference_staticGetter_imported_withPrefix() { |
| 2915 addNamedSource( |
| 2916 '/a.dart', |
| 2917 ''' |
| 2918 class C { |
| 2919 static int get x => null; |
| 2920 } |
| 2921 '''); |
| 2922 UnlinkedVariable variable = serializeVariableText(''' |
| 2923 import 'a.dart' as p; |
| 2924 const v = p.C.x; |
| 2925 '''); |
| 2926 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2927 UnlinkedConstOperation.pushReference |
| 2928 ], referenceValidators: [ |
| 2929 (EntityRef r) => checkTypeRef(r, null, null, 'x', |
| 2930 expectedKind: ReferenceKind.propertyAccessor, |
| 2931 prefixExpectations: [ |
| 2932 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2933 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 2934 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 2935 ]) |
| 2936 ]); |
| 2937 } |
| 2938 |
| 2939 test_constExpr_pushReference_staticMethod() { |
| 2940 UnlinkedVariable variable = serializeVariableText(''' |
| 2941 class C { |
| 2942 static m() {} |
| 2943 } |
| 2944 const v = C.m; |
| 2945 '''); |
| 2946 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2947 UnlinkedConstOperation.pushReference |
| 2948 ], referenceValidators: [ |
| 2949 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 2950 expectedKind: ReferenceKind.method, |
| 2951 prefixExpectations: [ |
| 2952 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 2953 ]) |
| 2954 ]); |
| 2955 } |
| 2956 |
| 2957 test_constExpr_pushReference_staticMethod_imported() { |
| 2958 addNamedSource( |
| 2959 '/a.dart', |
| 2960 ''' |
| 2961 class C { |
| 2962 static m() {} |
| 2963 } |
| 2964 '''); |
| 2965 UnlinkedVariable variable = serializeVariableText(''' |
| 2966 import 'a.dart'; |
| 2967 const v = C.m; |
| 2968 '''); |
| 2969 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2970 UnlinkedConstOperation.pushReference |
| 2971 ], referenceValidators: [ |
| 2972 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 2973 expectedKind: ReferenceKind.method, |
| 2974 prefixExpectations: [ |
| 2975 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 2976 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart') |
| 2977 ]) |
| 2978 ]); |
| 2979 } |
| 2980 |
| 2981 test_constExpr_pushReference_staticMethod_imported_withPrefix() { |
| 2982 addNamedSource( |
| 2983 '/a.dart', |
| 2984 ''' |
| 2985 class C { |
| 2986 static m() {} |
| 2987 } |
| 2988 '''); |
| 2989 UnlinkedVariable variable = serializeVariableText(''' |
| 2990 import 'a.dart' as p; |
| 2991 const v = p.C.m; |
| 2992 '''); |
| 2993 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 2994 UnlinkedConstOperation.pushReference |
| 2995 ], referenceValidators: [ |
| 2996 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 2997 expectedKind: ReferenceKind.method, |
| 2998 prefixExpectations: [ |
| 2999 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 3000 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 3001 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 3002 ]) |
| 3003 ]); |
| 3004 } |
| 3005 |
| 3006 test_constExpr_pushReference_staticMethod_simpleIdentifier() { |
| 3007 UnlinkedVariable variable = serializeClassText(''' |
| 3008 class C { |
| 3009 static const a = m; |
| 3010 static m() {} |
| 3011 } |
| 3012 ''').fields[0]; |
| 3013 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3014 UnlinkedConstOperation.pushReference |
| 3015 ], referenceValidators: [ |
| 3016 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 3017 expectedKind: ReferenceKind.method, |
| 3018 prefixExpectations: [ |
| 3019 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 3020 ]) |
| 3021 ]); |
| 3022 } |
| 3023 |
| 3024 test_constExpr_pushReference_topLevelFunction() { |
| 3025 UnlinkedVariable variable = serializeVariableText(''' |
| 3026 f() {} |
| 3027 const v = f; |
| 3028 '''); |
| 3029 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3030 UnlinkedConstOperation.pushReference |
| 3031 ], referenceValidators: [ |
| 3032 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 3033 expectedKind: ReferenceKind.topLevelFunction) |
| 3034 ]); |
| 3035 } |
| 3036 |
| 3037 test_constExpr_pushReference_topLevelFunction_imported() { |
| 3038 addNamedSource( |
| 3039 '/a.dart', |
| 3040 ''' |
| 3041 f() {} |
| 3042 '''); |
| 3043 UnlinkedVariable variable = serializeVariableText(''' |
| 3044 import 'a.dart'; |
| 3045 const v = f; |
| 3046 '''); |
| 3047 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3048 UnlinkedConstOperation.pushReference |
| 3049 ], referenceValidators: [ |
| 3050 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'f', |
| 3051 expectedKind: ReferenceKind.topLevelFunction) |
| 3052 ]); |
| 3053 } |
| 3054 |
| 3055 test_constExpr_pushReference_topLevelFunction_imported_withPrefix() { |
| 3056 addNamedSource( |
| 3057 '/a.dart', |
| 3058 ''' |
| 3059 f() {} |
| 3060 '''); |
| 3061 UnlinkedVariable variable = serializeVariableText(''' |
| 3062 import 'a.dart' as p; |
| 3063 const v = p.f; |
| 3064 '''); |
| 3065 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3066 UnlinkedConstOperation.pushReference |
| 3067 ], referenceValidators: [ |
| 3068 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'f', |
| 3069 expectedKind: ReferenceKind.topLevelFunction, |
| 3070 prefixExpectations: [ |
| 3071 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 3072 ]) |
| 3073 ]); |
| 3074 } |
| 3075 |
| 3076 test_constExpr_pushReference_topLevelGetter() { |
| 3077 UnlinkedVariable variable = serializeVariableText(''' |
| 3078 int get x => null; |
| 3079 const v = x; |
| 3080 '''); |
| 3081 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3082 UnlinkedConstOperation.pushReference |
| 3083 ], referenceValidators: [ |
| 3084 (EntityRef r) => checkTypeRef(r, null, null, 'x', |
| 3085 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 3086 ]); |
| 3087 } |
| 3088 |
| 3089 test_constExpr_pushReference_topLevelGetter_imported() { |
| 3090 addNamedSource('/a.dart', 'int get x => null;'); |
| 3091 UnlinkedVariable variable = serializeVariableText(''' |
| 3092 import 'a.dart'; |
| 3093 const v = x; |
| 3094 '''); |
| 3095 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3096 UnlinkedConstOperation.pushReference |
| 3097 ], referenceValidators: [ |
| 3098 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x', |
| 3099 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 3100 ]); |
| 3101 } |
| 3102 |
| 3103 test_constExpr_pushReference_topLevelGetter_imported_withPrefix() { |
| 3104 addNamedSource('/a.dart', 'int get x => null;'); |
| 3105 UnlinkedVariable variable = serializeVariableText(''' |
| 3106 import 'a.dart' as p; |
| 3107 const v = p.x; |
| 3108 '''); |
| 3109 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3110 UnlinkedConstOperation.pushReference |
| 3111 ], referenceValidators: [ |
| 3112 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x', |
| 3113 expectedKind: ReferenceKind.topLevelPropertyAccessor, |
| 3114 expectedPrefix: 'p') |
| 3115 ]); |
| 3116 } |
| 3117 |
| 3118 test_constExpr_pushReference_topLevelVariable() { |
| 3119 UnlinkedVariable variable = serializeVariableText(''' |
| 3120 const int a = 1; |
| 3121 const v = a; |
| 3122 '''); |
| 3123 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3124 UnlinkedConstOperation.pushReference |
| 3125 ], referenceValidators: [ |
| 3126 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 3127 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 3128 ]); |
| 3129 } |
| 3130 |
| 3131 test_constExpr_pushReference_topLevelVariable_imported() { |
| 3132 addNamedSource('/a.dart', 'const int a = 1;'); |
| 3133 UnlinkedVariable variable = serializeVariableText(''' |
| 3134 import 'a.dart'; |
| 3135 const v = a; |
| 3136 '''); |
| 3137 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3138 UnlinkedConstOperation.pushReference |
| 3139 ], referenceValidators: [ |
| 3140 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a', |
| 3141 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 3142 ]); |
| 3143 } |
| 3144 |
| 3145 test_constExpr_pushReference_topLevelVariable_imported_withPrefix() { |
| 3146 addNamedSource('/a.dart', 'const int a = 1;'); |
| 3147 UnlinkedVariable variable = serializeVariableText(''' |
| 3148 import 'a.dart' as p; |
| 3149 const v = p.a; |
| 3150 '''); |
| 3151 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3152 UnlinkedConstOperation.pushReference |
| 3153 ], referenceValidators: [ |
| 3154 (EntityRef r) { |
| 3155 return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a', |
| 3156 expectedKind: ReferenceKind.topLevelPropertyAccessor, |
| 3157 expectedPrefix: 'p'); |
| 3158 } |
| 3159 ]); |
| 3160 } |
| 3161 |
| 3162 test_constExpr_pushReference_typeParameter() { |
| 3163 String text = ''' |
| 3164 class C<T> { |
| 3165 static const a = T; |
| 3166 } |
| 3167 '''; |
| 3168 UnlinkedVariable variable = |
| 3169 serializeClassText(text, allowErrors: true).fields[0]; |
| 3170 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3171 UnlinkedConstOperation.pushReference |
| 3172 ], referenceValidators: [ |
| 3173 (EntityRef r) { |
| 3174 return checkParamTypeRef(r, 1); |
| 3175 } |
| 3176 ]); |
| 3177 } |
| 3178 |
| 3179 test_constExpr_pushReference_unresolved_prefix0() { |
| 3180 UnlinkedVariable variable = serializeVariableText( |
| 3181 ''' |
| 3182 const v = foo; |
| 3183 ''', |
| 3184 allowErrors: true); |
| 3185 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3186 UnlinkedConstOperation.pushReference |
| 3187 ], referenceValidators: [ |
| 3188 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 3189 expectedKind: ReferenceKind.unresolved) |
| 3190 ]); |
| 3191 } |
| 3192 |
| 3193 test_constExpr_pushReference_unresolved_prefix1() { |
| 3194 UnlinkedVariable variable = serializeVariableText( |
| 3195 ''' |
| 3196 class C {} |
| 3197 const v = C.foo; |
| 3198 ''', |
| 3199 allowErrors: true); |
| 3200 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3201 UnlinkedConstOperation.pushReference |
| 3202 ], referenceValidators: [ |
| 3203 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 3204 expectedKind: ReferenceKind.unresolved, |
| 3205 prefixExpectations: [ |
| 3206 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 3207 ]) |
| 3208 ]); |
| 3209 } |
| 3210 |
| 3211 test_constExpr_pushReference_unresolved_prefix2() { |
| 3212 addNamedSource( |
| 3213 '/a.dart', |
| 3214 ''' |
| 3215 class C {} |
| 3216 '''); |
| 3217 UnlinkedVariable variable = serializeVariableText( |
| 3218 ''' |
| 3219 import 'a.dart' as p; |
| 3220 const v = p.C.foo; |
| 3221 ''', |
| 3222 allowErrors: true); |
| 3223 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3224 UnlinkedConstOperation.pushReference |
| 3225 ], referenceValidators: [ |
| 3226 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 3227 expectedKind: ReferenceKind.unresolved, |
| 3228 prefixExpectations: [ |
| 3229 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 3230 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 3231 new _PrefixExpectation(ReferenceKind.prefix, 'p'), |
| 3232 ]) |
| 3233 ]); |
| 3234 } |
| 3235 |
| 3236 test_constExpr_pushString_adjacent() { |
| 3237 UnlinkedVariable variable = |
| 3238 serializeVariableText('const v = "aaa" "b" "ccc";'); |
| 3239 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 3240 operators: [UnlinkedConstOperation.pushString], strings: ['aaabccc']); |
| 3241 } |
| 3242 |
| 3243 test_constExpr_pushString_adjacent_interpolation() { |
| 3244 UnlinkedVariable variable = |
| 3245 serializeVariableText(r'const v = "aaa" "bb ${42} bbb" "cccc";'); |
| 3246 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3247 UnlinkedConstOperation.pushString, |
| 3248 UnlinkedConstOperation.pushString, |
| 3249 UnlinkedConstOperation.pushInt, |
| 3250 UnlinkedConstOperation.pushString, |
| 3251 UnlinkedConstOperation.concatenate, |
| 3252 UnlinkedConstOperation.pushString, |
| 3253 UnlinkedConstOperation.concatenate, |
| 3254 ], ints: [ |
| 3255 42, |
| 3256 3, |
| 3257 3, |
| 3258 ], strings: [ |
| 3259 'aaa', |
| 3260 'bb ', |
| 3261 ' bbb', |
| 3262 'cccc' |
| 3263 ]); |
| 3264 } |
| 3265 |
| 3266 test_constExpr_pushString_interpolation() { |
| 3267 UnlinkedVariable variable = |
| 3268 serializeVariableText(r'const v = "aaa ${42} bbb";'); |
| 3269 _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [ |
| 3270 UnlinkedConstOperation.pushString, |
| 3271 UnlinkedConstOperation.pushInt, |
| 3272 UnlinkedConstOperation.pushString, |
| 3273 UnlinkedConstOperation.concatenate |
| 3274 ], ints: [ |
| 3275 42, |
| 3276 3 |
| 3277 ], strings: [ |
| 3278 'aaa ', |
| 3279 ' bbb' |
| 3280 ]); |
| 3281 } |
| 3282 |
| 3283 test_constExpr_pushString_simple() { |
| 3284 UnlinkedVariable variable = serializeVariableText('const v = "abc";'); |
| 3285 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 3286 operators: [UnlinkedConstOperation.pushString], strings: ['abc']); |
| 3287 } |
| 3288 |
| 3289 test_constExpr_pushTrue() { |
| 3290 UnlinkedVariable variable = serializeVariableText('const v = true;'); |
| 3291 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 3292 operators: [UnlinkedConstOperation.pushTrue]); |
| 3293 } |
| 3294 |
| 3295 test_constructor() { |
| 3296 String text = 'class C { C(); }'; |
| 3297 UnlinkedExecutable executable = |
| 3298 findExecutable('', executables: serializeClassText(text).executables); |
| 3299 expect(executable.kind, UnlinkedExecutableKind.constructor); |
| 3300 expect(executable.returnType, isNull); |
| 3301 expect(executable.isAsynchronous, isFalse); |
| 3302 expect(executable.isExternal, isFalse); |
| 3303 expect(executable.isGenerator, isFalse); |
| 3304 expect(executable.nameOffset, text.indexOf('C();')); |
| 3305 expect(executable.periodOffset, 0); |
| 3306 expect(executable.nameEnd, 0); |
| 3307 expect(executable.isRedirectedConstructor, isFalse); |
| 3308 expect(executable.redirectedConstructor, isNull); |
| 3309 expect(executable.redirectedConstructorName, isEmpty); |
| 3310 expect(executable.visibleOffset, 0); |
| 3311 expect(executable.visibleLength, 0); |
| 3312 } |
| 3313 |
| 3314 test_constructor_anonymous() { |
| 3315 UnlinkedExecutable executable = findExecutable('', |
| 3316 executables: serializeClassText('class C { C(); }').executables); |
| 3317 expect(executable.name, isEmpty); |
| 3318 } |
| 3319 |
| 3320 test_constructor_const() { |
| 3321 UnlinkedExecutable executable = findExecutable('', |
| 3322 executables: serializeClassText('class C { const C(); }').executables); |
| 3323 expect(executable.isConst, isTrue); |
| 3324 expect(executable.isExternal, isFalse); |
| 3325 } |
| 3326 |
| 3327 test_constructor_const_external() { |
| 3328 UnlinkedExecutable executable = findExecutable('', |
| 3329 executables: |
| 3330 serializeClassText('class C { external const C(); }').executables); |
| 3331 expect(executable.isConst, isTrue); |
| 3332 expect(executable.isExternal, isTrue); |
| 3333 } |
| 3334 |
| 3335 test_constructor_documented() { |
| 3336 String text = ''' |
| 3337 class C { |
| 3338 /** |
| 3339 * Docs |
| 3340 */ |
| 3341 C(); |
| 3342 }'''; |
| 3343 UnlinkedExecutable executable = serializeClassText(text).executables[0]; |
| 3344 expect(executable.documentationComment, isNotNull); |
| 3345 checkDocumentationComment(executable.documentationComment, text); |
| 3346 } |
| 3347 |
| 3348 test_constructor_external() { |
| 3349 UnlinkedExecutable executable = findExecutable('', |
| 3350 executables: |
| 3351 serializeClassText('class C { external C(); }').executables); |
| 3352 expect(executable.isExternal, isTrue); |
| 3353 } |
| 3354 |
| 3355 test_constructor_factory() { |
| 3356 UnlinkedExecutable executable = findExecutable('', |
| 3357 executables: |
| 3358 serializeClassText('class C { factory C() => null; }').executables); |
| 3359 expect(executable.isFactory, isTrue); |
| 3360 } |
| 3361 |
| 3362 test_constructor_implicit() { |
| 3363 // Implicit constructors are not serialized. |
| 3364 UnlinkedExecutable executable = findExecutable(null, |
| 3365 executables: serializeClassText('class C { C(); }').executables, |
| 3366 failIfAbsent: false); |
| 3367 expect(executable, isNull); |
| 3368 } |
| 3369 |
| 3370 test_constructor_initializers_field() { |
| 3371 UnlinkedExecutable executable = |
| 3372 findExecutable('', executables: serializeClassText(r''' |
| 3373 class C { |
| 3374 final x; |
| 3375 const C() : x = 42; |
| 3376 } |
| 3377 ''').executables); |
| 3378 expect(executable.constantInitializers, hasLength(1)); |
| 3379 UnlinkedConstructorInitializer initializer = |
| 3380 executable.constantInitializers[0]; |
| 3381 expect(initializer.kind, UnlinkedConstructorInitializerKind.field); |
| 3382 expect(initializer.name, 'x'); |
| 3383 _assertUnlinkedConst(initializer.expression, |
| 3384 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3385 expect(initializer.arguments, isEmpty); |
| 3386 } |
| 3387 |
| 3388 test_constructor_initializers_field_withParameter() { |
| 3389 UnlinkedExecutable executable = |
| 3390 findExecutable('', executables: serializeClassText(r''' |
| 3391 class C { |
| 3392 final x; |
| 3393 const C(int p) : x = p; |
| 3394 } |
| 3395 ''').executables); |
| 3396 expect(executable.constantInitializers, hasLength(1)); |
| 3397 UnlinkedConstructorInitializer initializer = |
| 3398 executable.constantInitializers[0]; |
| 3399 expect(initializer.kind, UnlinkedConstructorInitializerKind.field); |
| 3400 expect(initializer.name, 'x'); |
| 3401 _assertUnlinkedConst(initializer.expression, |
| 3402 operators: [UnlinkedConstOperation.pushParameter], strings: ['p']); |
| 3403 expect(initializer.arguments, isEmpty); |
| 3404 } |
| 3405 |
| 3406 test_constructor_initializers_notConst() { |
| 3407 UnlinkedExecutable executable = |
| 3408 findExecutable('', executables: serializeClassText(r''' |
| 3409 class C { |
| 3410 final x; |
| 3411 C() : x = 42; |
| 3412 } |
| 3413 ''').executables); |
| 3414 expect(executable.constantInitializers, isEmpty); |
| 3415 } |
| 3416 |
| 3417 test_constructor_initializers_superInvocation_named() { |
| 3418 UnlinkedExecutable executable = |
| 3419 findExecutable('', executables: serializeClassText(r''' |
| 3420 class A { |
| 3421 const A.aaa(int p); |
| 3422 } |
| 3423 class C extends A { |
| 3424 const C() : super.aaa(42); |
| 3425 } |
| 3426 ''').executables); |
| 3427 expect(executable.constantInitializers, hasLength(1)); |
| 3428 UnlinkedConstructorInitializer initializer = |
| 3429 executable.constantInitializers[0]; |
| 3430 expect( |
| 3431 initializer.kind, UnlinkedConstructorInitializerKind.superInvocation); |
| 3432 expect(initializer.name, 'aaa'); |
| 3433 expect(initializer.expression, isNull); |
| 3434 expect(initializer.arguments, hasLength(1)); |
| 3435 _assertUnlinkedConst(initializer.arguments[0], |
| 3436 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3437 } |
| 3438 |
| 3439 test_constructor_initializers_superInvocation_namedExpression() { |
| 3440 UnlinkedExecutable executable = |
| 3441 findExecutable('', executables: serializeClassText(r''' |
| 3442 class A { |
| 3443 const A(a, {int b, int c}); |
| 3444 } |
| 3445 class C extends A { |
| 3446 const C() : super(1, b: 2, c: 3); |
| 3447 } |
| 3448 ''').executables); |
| 3449 expect(executable.constantInitializers, hasLength(1)); |
| 3450 UnlinkedConstructorInitializer initializer = |
| 3451 executable.constantInitializers[0]; |
| 3452 expect( |
| 3453 initializer.kind, UnlinkedConstructorInitializerKind.superInvocation); |
| 3454 expect(initializer.name, ''); |
| 3455 expect(initializer.expression, isNull); |
| 3456 expect(initializer.arguments, hasLength(3)); |
| 3457 _assertUnlinkedConst(initializer.arguments[0], |
| 3458 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 3459 _assertUnlinkedConst(initializer.arguments[1], |
| 3460 operators: [UnlinkedConstOperation.pushInt], ints: [2]); |
| 3461 _assertUnlinkedConst(initializer.arguments[2], |
| 3462 operators: [UnlinkedConstOperation.pushInt], ints: [3]); |
| 3463 expect(initializer.argumentNames, ['b', 'c']); |
| 3464 } |
| 3465 |
| 3466 test_constructor_initializers_superInvocation_unnamed() { |
| 3467 UnlinkedExecutable executable = |
| 3468 findExecutable('ccc', executables: serializeClassText(r''' |
| 3469 class A { |
| 3470 const A(int p); |
| 3471 } |
| 3472 class C extends A { |
| 3473 const C.ccc() : super(42); |
| 3474 } |
| 3475 ''').executables); |
| 3476 expect(executable.constantInitializers, hasLength(1)); |
| 3477 UnlinkedConstructorInitializer initializer = |
| 3478 executable.constantInitializers[0]; |
| 3479 expect( |
| 3480 initializer.kind, UnlinkedConstructorInitializerKind.superInvocation); |
| 3481 expect(initializer.name, ''); |
| 3482 expect(initializer.expression, isNull); |
| 3483 expect(initializer.arguments, hasLength(1)); |
| 3484 _assertUnlinkedConst(initializer.arguments[0], |
| 3485 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3486 } |
| 3487 |
| 3488 test_constructor_initializers_thisInvocation_named() { |
| 3489 UnlinkedExecutable executable = |
| 3490 findExecutable('', executables: serializeClassText(r''' |
| 3491 class C { |
| 3492 const C() : this.named(1, 'bbb'); |
| 3493 const C.named(int a, String b); |
| 3494 } |
| 3495 ''').executables); |
| 3496 expect(executable.constantInitializers, hasLength(1)); |
| 3497 UnlinkedConstructorInitializer initializer = |
| 3498 executable.constantInitializers[0]; |
| 3499 expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation); |
| 3500 expect(initializer.name, 'named'); |
| 3501 expect(initializer.expression, isNull); |
| 3502 expect(initializer.arguments, hasLength(2)); |
| 3503 _assertUnlinkedConst(initializer.arguments[0], |
| 3504 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 3505 _assertUnlinkedConst(initializer.arguments[1], |
| 3506 operators: [UnlinkedConstOperation.pushString], strings: ['bbb']); |
| 3507 } |
| 3508 |
| 3509 test_constructor_initializers_thisInvocation_namedExpression() { |
| 3510 UnlinkedExecutable executable = |
| 3511 findExecutable('', executables: serializeClassText(r''' |
| 3512 class C { |
| 3513 const C() : this.named(1, b: 2, c: 3); |
| 3514 const C.named(a, {int b, int c}); |
| 3515 } |
| 3516 ''').executables); |
| 3517 expect(executable.constantInitializers, hasLength(1)); |
| 3518 UnlinkedConstructorInitializer initializer = |
| 3519 executable.constantInitializers[0]; |
| 3520 expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation); |
| 3521 expect(initializer.name, 'named'); |
| 3522 expect(initializer.expression, isNull); |
| 3523 expect(initializer.arguments, hasLength(3)); |
| 3524 _assertUnlinkedConst(initializer.arguments[0], |
| 3525 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 3526 _assertUnlinkedConst(initializer.arguments[1], |
| 3527 operators: [UnlinkedConstOperation.pushInt], ints: [2]); |
| 3528 _assertUnlinkedConst(initializer.arguments[2], |
| 3529 operators: [UnlinkedConstOperation.pushInt], ints: [3]); |
| 3530 expect(initializer.argumentNames, ['b', 'c']); |
| 3531 } |
| 3532 |
| 3533 test_constructor_initializers_thisInvocation_unnamed() { |
| 3534 UnlinkedExecutable executable = |
| 3535 findExecutable('named', executables: serializeClassText(r''' |
| 3536 class C { |
| 3537 const C.named() : this(1, 'bbb'); |
| 3538 const C(int a, String b); |
| 3539 } |
| 3540 ''').executables); |
| 3541 expect(executable.constantInitializers, hasLength(1)); |
| 3542 UnlinkedConstructorInitializer initializer = |
| 3543 executable.constantInitializers[0]; |
| 3544 expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation); |
| 3545 expect(initializer.name, ''); |
| 3546 expect(initializer.expression, isNull); |
| 3547 expect(initializer.arguments, hasLength(2)); |
| 3548 _assertUnlinkedConst(initializer.arguments[0], |
| 3549 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 3550 _assertUnlinkedConst(initializer.arguments[1], |
| 3551 operators: [UnlinkedConstOperation.pushString], strings: ['bbb']); |
| 3552 } |
| 3553 |
| 3554 test_constructor_initializing_formal() { |
| 3555 UnlinkedExecutable executable = findExecutable('', |
| 3556 executables: |
| 3557 serializeClassText('class C { C(this.x); final x; }').executables); |
| 3558 UnlinkedParam parameter = executable.parameters[0]; |
| 3559 expect(parameter.isInitializingFormal, isTrue); |
| 3560 } |
| 3561 |
| 3562 test_constructor_initializing_formal_explicit_type() { |
| 3563 UnlinkedExecutable executable = findExecutable('', |
| 3564 executables: serializeClassText('class C { C(int this.x); final x; }') |
| 3565 .executables); |
| 3566 UnlinkedParam parameter = executable.parameters[0]; |
| 3567 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int'); |
| 3568 } |
| 3569 |
| 3570 test_constructor_initializing_formal_function_typed() { |
| 3571 UnlinkedExecutable executable = findExecutable('', |
| 3572 executables: serializeClassText('class C { C(this.x()); final x; }') |
| 3573 .executables); |
| 3574 UnlinkedParam parameter = executable.parameters[0]; |
| 3575 expect(parameter.isFunctionTyped, isTrue); |
| 3576 } |
| 3577 |
| 3578 test_constructor_initializing_formal_function_typed_explicit_return_type() { |
| 3579 UnlinkedExecutable executable = findExecutable('', |
| 3580 executables: |
| 3581 serializeClassText('class C { C(int this.x()); Function x; }') |
| 3582 .executables); |
| 3583 UnlinkedParam parameter = executable.parameters[0]; |
| 3584 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int'); |
| 3585 } |
| 3586 |
| 3587 test_constructor_initializing_formal_function_typed_implicit_return_type() { |
| 3588 UnlinkedExecutable executable = findExecutable('', |
| 3589 executables: serializeClassText('class C { C(this.x()); Function x; }') |
| 3590 .executables); |
| 3591 UnlinkedParam parameter = executable.parameters[0]; |
| 3592 expect(parameter.isFunctionTyped, isTrue); |
| 3593 expect(parameter.type, isNull); |
| 3594 } |
| 3595 |
| 3596 test_constructor_initializing_formal_function_typed_no_parameters() { |
| 3597 UnlinkedExecutable executable = findExecutable('', |
| 3598 executables: serializeClassText('class C { C(this.x()); final x; }') |
| 3599 .executables); |
| 3600 UnlinkedParam parameter = executable.parameters[0]; |
| 3601 expect(parameter.parameters, isEmpty); |
| 3602 } |
| 3603 |
| 3604 test_constructor_initializing_formal_function_typed_parameter() { |
| 3605 UnlinkedExecutable executable = findExecutable('', |
| 3606 executables: serializeClassText('class C { C(this.x(a)); final x; }') |
| 3607 .executables); |
| 3608 UnlinkedParam parameter = executable.parameters[0]; |
| 3609 expect(parameter.parameters, hasLength(1)); |
| 3610 } |
| 3611 |
| 3612 test_constructor_initializing_formal_function_typed_parameter_order() { |
| 3613 UnlinkedExecutable executable = findExecutable('', |
| 3614 executables: serializeClassText('class C { C(this.x(a, b)); final x; }') |
| 3615 .executables); |
| 3616 UnlinkedParam parameter = executable.parameters[0]; |
| 3617 expect(parameter.parameters, hasLength(2)); |
| 3618 expect(parameter.parameters[0].name, 'a'); |
| 3619 expect(parameter.parameters[1].name, 'b'); |
| 3620 } |
| 3621 |
| 3622 test_constructor_initializing_formal_function_typed_withDefault() { |
| 3623 UnlinkedExecutable executable = |
| 3624 findExecutable('', executables: serializeClassText(r''' |
| 3625 class C { |
| 3626 C([this.x() = foo]); |
| 3627 final x; |
| 3628 } |
| 3629 int foo() => 0; |
| 3630 ''').executables); |
| 3631 UnlinkedParam param = executable.parameters[0]; |
| 3632 expect(param.isFunctionTyped, isTrue); |
| 3633 expect(param.kind, UnlinkedParamKind.positional); |
| 3634 expect(param.defaultValueCode, 'foo'); |
| 3635 _assertUnlinkedConst(param.initializer.bodyExpr, operators: [ |
| 3636 UnlinkedConstOperation.pushReference |
| 3637 ], referenceValidators: [ |
| 3638 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 3639 expectedKind: ReferenceKind.topLevelFunction) |
| 3640 ]); |
| 3641 } |
| 3642 |
| 3643 test_constructor_initializing_formal_implicit_type() { |
| 3644 // Note: the implicit type of an initializing formal is the type of the |
| 3645 // field. |
| 3646 UnlinkedExecutable executable = findExecutable('', |
| 3647 executables: |
| 3648 serializeClassText('class C { C(this.x); int x; }').executables); |
| 3649 UnlinkedParam parameter = executable.parameters[0]; |
| 3650 expect(parameter.type, isNull); |
| 3651 } |
| 3652 |
| 3653 test_constructor_initializing_formal_name() { |
| 3654 UnlinkedExecutable executable = findExecutable('', |
| 3655 executables: |
| 3656 serializeClassText('class C { C(this.x); final x; }').executables); |
| 3657 UnlinkedParam parameter = executable.parameters[0]; |
| 3658 expect(parameter.name, 'x'); |
| 3659 } |
| 3660 |
| 3661 test_constructor_initializing_formal_named() { |
| 3662 UnlinkedExecutable executable = findExecutable('', |
| 3663 executables: serializeClassText('class C { C({this.x}); final x; }') |
| 3664 .executables); |
| 3665 UnlinkedParam parameter = executable.parameters[0]; |
| 3666 expect(parameter.kind, UnlinkedParamKind.named); |
| 3667 expect(parameter.initializer, isNull); |
| 3668 expect(parameter.defaultValueCode, isEmpty); |
| 3669 } |
| 3670 |
| 3671 test_constructor_initializing_formal_named_withDefault() { |
| 3672 UnlinkedExecutable executable = findExecutable('', |
| 3673 executables: serializeClassText('class C { C({this.x: 42}); final x; }') |
| 3674 .executables); |
| 3675 UnlinkedParam parameter = executable.parameters[0]; |
| 3676 expect(parameter.kind, UnlinkedParamKind.named); |
| 3677 expect(parameter.initializer, isNotNull); |
| 3678 expect(parameter.defaultValueCode, '42'); |
| 3679 _assertCodeRange(parameter.codeRange, 13, 10); |
| 3680 _assertUnlinkedConst(parameter.initializer.bodyExpr, |
| 3681 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3682 } |
| 3683 |
| 3684 test_constructor_initializing_formal_non_function_typed() { |
| 3685 UnlinkedExecutable executable = findExecutable('', |
| 3686 executables: |
| 3687 serializeClassText('class C { C(this.x); final x; }').executables); |
| 3688 UnlinkedParam parameter = executable.parameters[0]; |
| 3689 expect(parameter.isFunctionTyped, isFalse); |
| 3690 } |
| 3691 |
| 3692 test_constructor_initializing_formal_positional() { |
| 3693 UnlinkedExecutable executable = findExecutable('', |
| 3694 executables: serializeClassText('class C { C([this.x]); final x; }') |
| 3695 .executables); |
| 3696 UnlinkedParam parameter = executable.parameters[0]; |
| 3697 expect(parameter.kind, UnlinkedParamKind.positional); |
| 3698 expect(parameter.initializer, isNull); |
| 3699 expect(parameter.defaultValueCode, isEmpty); |
| 3700 } |
| 3701 |
| 3702 test_constructor_initializing_formal_positional_withDefault() { |
| 3703 UnlinkedExecutable executable = findExecutable('', |
| 3704 executables: |
| 3705 serializeClassText('class C { C([this.x = 42]); final x; }') |
| 3706 .executables); |
| 3707 UnlinkedParam parameter = executable.parameters[0]; |
| 3708 expect(parameter.kind, UnlinkedParamKind.positional); |
| 3709 expect(parameter.initializer, isNotNull); |
| 3710 expect(parameter.defaultValueCode, '42'); |
| 3711 _assertCodeRange(parameter.codeRange, 13, 11); |
| 3712 _assertUnlinkedConst(parameter.initializer.bodyExpr, |
| 3713 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3714 } |
| 3715 |
| 3716 test_constructor_initializing_formal_required() { |
| 3717 UnlinkedExecutable executable = findExecutable('', |
| 3718 executables: |
| 3719 serializeClassText('class C { C(this.x); final x; }').executables); |
| 3720 UnlinkedParam parameter = executable.parameters[0]; |
| 3721 expect(parameter.kind, UnlinkedParamKind.required); |
| 3722 } |
| 3723 |
| 3724 test_constructor_initializing_formal_typedef() { |
| 3725 UnlinkedExecutable executable = findExecutable('', |
| 3726 executables: serializeClassText( |
| 3727 'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }') |
| 3728 .executables); |
| 3729 UnlinkedParam parameter = executable.parameters[0]; |
| 3730 expect(parameter.isFunctionTyped, isFalse); |
| 3731 expect(parameter.parameters, isEmpty); |
| 3732 } |
| 3733 |
| 3734 test_constructor_initializing_formal_withDefault() { |
| 3735 UnlinkedExecutable executable = |
| 3736 findExecutable('', executables: serializeClassText(r''' |
| 3737 class C { |
| 3738 C([this.x = 42]); |
| 3739 final int x; |
| 3740 }''').executables); |
| 3741 UnlinkedParam param = executable.parameters[0]; |
| 3742 expect(param.kind, UnlinkedParamKind.positional); |
| 3743 expect(param.defaultValueCode, '42'); |
| 3744 _assertUnlinkedConst(param.initializer.bodyExpr, |
| 3745 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 3746 } |
| 3747 |
| 3748 test_constructor_named() { |
| 3749 String text = 'class C { C.foo(); }'; |
| 3750 UnlinkedExecutable executable = findExecutable('foo', |
| 3751 executables: serializeClassText(text).executables); |
| 3752 expect(executable.name, 'foo'); |
| 3753 expect(executable.nameOffset, text.indexOf('foo')); |
| 3754 expect(executable.periodOffset, text.indexOf('.foo')); |
| 3755 expect(executable.nameEnd, text.indexOf('()')); |
| 3756 _assertCodeRange(executable.codeRange, 10, 8); |
| 3757 } |
| 3758 |
| 3759 test_constructor_non_const() { |
| 3760 UnlinkedExecutable executable = findExecutable('', |
| 3761 executables: serializeClassText('class C { C(); }').executables); |
| 3762 expect(executable.isConst, isFalse); |
| 3763 } |
| 3764 |
| 3765 test_constructor_non_factory() { |
| 3766 UnlinkedExecutable executable = findExecutable('', |
| 3767 executables: serializeClassText('class C { C(); }').executables); |
| 3768 expect(executable.isFactory, isFalse); |
| 3769 } |
| 3770 |
| 3771 test_constructor_param_inferred_type_explicit() { |
| 3772 UnlinkedExecutable ctor = |
| 3773 serializeClassText('class C { C(int v); }').executables[0]; |
| 3774 expect(ctor.kind, UnlinkedExecutableKind.constructor); |
| 3775 expect(ctor.parameters[0].inferredTypeSlot, 0); |
| 3776 } |
| 3777 |
| 3778 test_constructor_param_inferred_type_implicit() { |
| 3779 UnlinkedExecutable ctor = |
| 3780 serializeClassText('class C { C(v); }').executables[0]; |
| 3781 expect(ctor.kind, UnlinkedExecutableKind.constructor); |
| 3782 expect(ctor.parameters[0].inferredTypeSlot, 0); |
| 3783 } |
| 3784 |
| 3785 test_constructor_redirected_factory_named() { |
| 3786 String text = ''' |
| 3787 class C { |
| 3788 factory C() = D.named; |
| 3789 C._(); |
| 3790 } |
| 3791 class D extends C { |
| 3792 D.named() : super._(); |
| 3793 } |
| 3794 '''; |
| 3795 UnlinkedExecutable executable = |
| 3796 serializeClassText(text, className: 'C').executables[0]; |
| 3797 expect(executable.isRedirectedConstructor, isTrue); |
| 3798 expect(executable.isFactory, isTrue); |
| 3799 expect(executable.redirectedConstructorName, isEmpty); |
| 3800 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3801 expectedKind: ReferenceKind.constructor, |
| 3802 prefixExpectations: [ |
| 3803 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D') |
| 3804 ]); |
| 3805 } |
| 3806 |
| 3807 test_constructor_redirected_factory_named_generic() { |
| 3808 String text = ''' |
| 3809 class C<T, U> { |
| 3810 factory C() = D<U, T>.named; |
| 3811 C._(); |
| 3812 } |
| 3813 class D<T, U> extends C<U, T> { |
| 3814 D.named() : super._(); |
| 3815 } |
| 3816 '''; |
| 3817 UnlinkedExecutable executable = |
| 3818 serializeClassText(text, className: 'C').executables[0]; |
| 3819 expect(executable.isRedirectedConstructor, isTrue); |
| 3820 expect(executable.isFactory, isTrue); |
| 3821 expect(executable.redirectedConstructorName, isEmpty); |
| 3822 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3823 expectedKind: ReferenceKind.constructor, |
| 3824 prefixExpectations: [ |
| 3825 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D', |
| 3826 numTypeParameters: 2) |
| 3827 ], |
| 3828 numTypeArguments: 2); |
| 3829 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 3830 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 3831 } |
| 3832 |
| 3833 test_constructor_redirected_factory_named_imported() { |
| 3834 addNamedSource( |
| 3835 '/foo.dart', |
| 3836 ''' |
| 3837 import 'test.dart'; |
| 3838 class D extends C { |
| 3839 D.named() : super._(); |
| 3840 } |
| 3841 '''); |
| 3842 String text = ''' |
| 3843 import 'foo.dart'; |
| 3844 class C { |
| 3845 factory C() = D.named; |
| 3846 C._(); |
| 3847 } |
| 3848 '''; |
| 3849 UnlinkedExecutable executable = |
| 3850 serializeClassText(text, className: 'C').executables[0]; |
| 3851 expect(executable.isRedirectedConstructor, isTrue); |
| 3852 expect(executable.isFactory, isTrue); |
| 3853 expect(executable.redirectedConstructorName, isEmpty); |
| 3854 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3855 expectedKind: ReferenceKind.constructor, |
| 3856 prefixExpectations: [ |
| 3857 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D', |
| 3858 absoluteUri: absUri('/foo.dart'), relativeUri: 'foo.dart') |
| 3859 ]); |
| 3860 } |
| 3861 |
| 3862 test_constructor_redirected_factory_named_imported_generic() { |
| 3863 addNamedSource( |
| 3864 '/foo.dart', |
| 3865 ''' |
| 3866 import 'test.dart'; |
| 3867 class D<T, U> extends C<U, T> { |
| 3868 D.named() : super._(); |
| 3869 } |
| 3870 '''); |
| 3871 String text = ''' |
| 3872 import 'foo.dart'; |
| 3873 class C<T, U> { |
| 3874 factory C() = D<U, T>.named; |
| 3875 C._(); |
| 3876 } |
| 3877 '''; |
| 3878 UnlinkedExecutable executable = |
| 3879 serializeClassText(text, className: 'C').executables[0]; |
| 3880 expect(executable.isRedirectedConstructor, isTrue); |
| 3881 expect(executable.isFactory, isTrue); |
| 3882 expect(executable.redirectedConstructorName, isEmpty); |
| 3883 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3884 expectedKind: ReferenceKind.constructor, |
| 3885 prefixExpectations: [ |
| 3886 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D', |
| 3887 numTypeParameters: 2, |
| 3888 absoluteUri: absUri('/foo.dart'), |
| 3889 relativeUri: 'foo.dart') |
| 3890 ], |
| 3891 numTypeArguments: 2); |
| 3892 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 3893 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 3894 } |
| 3895 |
| 3896 test_constructor_redirected_factory_named_prefixed() { |
| 3897 addNamedSource( |
| 3898 '/foo.dart', |
| 3899 ''' |
| 3900 import 'test.dart'; |
| 3901 class D extends C { |
| 3902 D.named() : super._(); |
| 3903 } |
| 3904 '''); |
| 3905 String text = ''' |
| 3906 import 'foo.dart' as foo; |
| 3907 class C { |
| 3908 factory C() = foo.D.named; |
| 3909 C._(); |
| 3910 } |
| 3911 '''; |
| 3912 UnlinkedExecutable executable = |
| 3913 serializeClassText(text, className: 'C').executables[0]; |
| 3914 expect(executable.isRedirectedConstructor, isTrue); |
| 3915 expect(executable.isFactory, isTrue); |
| 3916 expect(executable.redirectedConstructorName, isEmpty); |
| 3917 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3918 expectedKind: ReferenceKind.constructor, |
| 3919 prefixExpectations: [ |
| 3920 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D', |
| 3921 absoluteUri: absUri('/foo.dart'), relativeUri: 'foo.dart'), |
| 3922 new _PrefixExpectation(ReferenceKind.prefix, 'foo') |
| 3923 ]); |
| 3924 } |
| 3925 |
| 3926 test_constructor_redirected_factory_named_prefixed_generic() { |
| 3927 addNamedSource( |
| 3928 '/foo.dart', |
| 3929 ''' |
| 3930 import 'test.dart'; |
| 3931 class D<T, U> extends C<U, T> { |
| 3932 D.named() : super._(); |
| 3933 } |
| 3934 '''); |
| 3935 String text = ''' |
| 3936 import 'foo.dart' as foo; |
| 3937 class C<T, U> { |
| 3938 factory C() = foo.D<U, T>.named; |
| 3939 C._(); |
| 3940 } |
| 3941 '''; |
| 3942 UnlinkedExecutable executable = |
| 3943 serializeClassText(text, className: 'C').executables[0]; |
| 3944 expect(executable.isRedirectedConstructor, isTrue); |
| 3945 expect(executable.isFactory, isTrue); |
| 3946 expect(executable.redirectedConstructorName, isEmpty); |
| 3947 checkTypeRef(executable.redirectedConstructor, null, null, 'named', |
| 3948 expectedKind: ReferenceKind.constructor, |
| 3949 prefixExpectations: [ |
| 3950 new _PrefixExpectation(ReferenceKind.classOrEnum, 'D', |
| 3951 numTypeParameters: 2, |
| 3952 absoluteUri: absUri('/foo.dart'), |
| 3953 relativeUri: 'foo.dart'), |
| 3954 new _PrefixExpectation(ReferenceKind.prefix, 'foo') |
| 3955 ], |
| 3956 numTypeArguments: 2); |
| 3957 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 3958 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 3959 } |
| 3960 |
| 3961 test_constructor_redirected_factory_unnamed() { |
| 3962 String text = ''' |
| 3963 class C { |
| 3964 factory C() = D; |
| 3965 C._(); |
| 3966 } |
| 3967 class D extends C { |
| 3968 D() : super._(); |
| 3969 } |
| 3970 '''; |
| 3971 UnlinkedExecutable executable = |
| 3972 serializeClassText(text, className: 'C').executables[0]; |
| 3973 expect(executable.isRedirectedConstructor, isTrue); |
| 3974 expect(executable.isFactory, isTrue); |
| 3975 expect(executable.redirectedConstructorName, isEmpty); |
| 3976 checkTypeRef(executable.redirectedConstructor, null, null, 'D'); |
| 3977 } |
| 3978 |
| 3979 test_constructor_redirected_factory_unnamed_generic() { |
| 3980 String text = ''' |
| 3981 class C<T, U> { |
| 3982 factory C() = D<U, T>; |
| 3983 C._(); |
| 3984 } |
| 3985 class D<T, U> extends C<U, T> { |
| 3986 D() : super._(); |
| 3987 } |
| 3988 '''; |
| 3989 UnlinkedExecutable executable = |
| 3990 serializeClassText(text, className: 'C').executables[0]; |
| 3991 expect(executable.isRedirectedConstructor, isTrue); |
| 3992 expect(executable.isFactory, isTrue); |
| 3993 expect(executable.redirectedConstructorName, isEmpty); |
| 3994 checkTypeRef(executable.redirectedConstructor, null, null, 'D', |
| 3995 numTypeParameters: 2, numTypeArguments: 2); |
| 3996 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 3997 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 3998 } |
| 3999 |
| 4000 test_constructor_redirected_factory_unnamed_imported() { |
| 4001 addNamedSource( |
| 4002 '/foo.dart', |
| 4003 ''' |
| 4004 import 'test.dart'; |
| 4005 class D extends C { |
| 4006 D() : super._(); |
| 4007 } |
| 4008 '''); |
| 4009 String text = ''' |
| 4010 import 'foo.dart'; |
| 4011 class C { |
| 4012 factory C() = D; |
| 4013 C._(); |
| 4014 } |
| 4015 '''; |
| 4016 UnlinkedExecutable executable = |
| 4017 serializeClassText(text, className: 'C').executables[0]; |
| 4018 expect(executable.isRedirectedConstructor, isTrue); |
| 4019 expect(executable.isFactory, isTrue); |
| 4020 expect(executable.redirectedConstructorName, isEmpty); |
| 4021 checkTypeRef( |
| 4022 executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D'); |
| 4023 } |
| 4024 |
| 4025 test_constructor_redirected_factory_unnamed_imported_generic() { |
| 4026 addNamedSource( |
| 4027 '/foo.dart', |
| 4028 ''' |
| 4029 import 'test.dart'; |
| 4030 class D<T, U> extends C<U, T> { |
| 4031 D() : super._(); |
| 4032 } |
| 4033 '''); |
| 4034 String text = ''' |
| 4035 import 'foo.dart'; |
| 4036 class C<T, U> { |
| 4037 factory C() = D<U, T>; |
| 4038 C._(); |
| 4039 } |
| 4040 '''; |
| 4041 UnlinkedExecutable executable = |
| 4042 serializeClassText(text, className: 'C').executables[0]; |
| 4043 expect(executable.isRedirectedConstructor, isTrue); |
| 4044 expect(executable.isFactory, isTrue); |
| 4045 expect(executable.redirectedConstructorName, isEmpty); |
| 4046 checkTypeRef( |
| 4047 executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D', |
| 4048 numTypeParameters: 2, numTypeArguments: 2); |
| 4049 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 4050 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 4051 } |
| 4052 |
| 4053 test_constructor_redirected_factory_unnamed_prefixed() { |
| 4054 addNamedSource( |
| 4055 '/foo.dart', |
| 4056 ''' |
| 4057 import 'test.dart'; |
| 4058 class D extends C { |
| 4059 D() : super._(); |
| 4060 } |
| 4061 '''); |
| 4062 String text = ''' |
| 4063 import 'foo.dart' as foo; |
| 4064 class C { |
| 4065 factory C() = foo.D; |
| 4066 C._(); |
| 4067 } |
| 4068 '''; |
| 4069 UnlinkedExecutable executable = |
| 4070 serializeClassText(text, className: 'C').executables[0]; |
| 4071 expect(executable.isRedirectedConstructor, isTrue); |
| 4072 expect(executable.isFactory, isTrue); |
| 4073 expect(executable.redirectedConstructorName, isEmpty); |
| 4074 checkTypeRef( |
| 4075 executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D', |
| 4076 expectedPrefix: 'foo'); |
| 4077 } |
| 4078 |
| 4079 test_constructor_redirected_factory_unnamed_prefixed_generic() { |
| 4080 addNamedSource( |
| 4081 '/foo.dart', |
| 4082 ''' |
| 4083 import 'test.dart'; |
| 4084 class D<T, U> extends C<U, T> { |
| 4085 D() : super._(); |
| 4086 } |
| 4087 '''); |
| 4088 String text = ''' |
| 4089 import 'foo.dart' as foo; |
| 4090 class C<T, U> { |
| 4091 factory C() = foo.D<U, T>; |
| 4092 C._(); |
| 4093 } |
| 4094 '''; |
| 4095 UnlinkedExecutable executable = |
| 4096 serializeClassText(text, className: 'C').executables[0]; |
| 4097 expect(executable.isRedirectedConstructor, isTrue); |
| 4098 expect(executable.isFactory, isTrue); |
| 4099 expect(executable.redirectedConstructorName, isEmpty); |
| 4100 checkTypeRef( |
| 4101 executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D', |
| 4102 numTypeParameters: 2, expectedPrefix: 'foo', numTypeArguments: 2); |
| 4103 checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1); |
| 4104 checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2); |
| 4105 } |
| 4106 |
| 4107 test_constructor_redirected_thisInvocation_named() { |
| 4108 String text = ''' |
| 4109 class C { |
| 4110 C() : this.named(); |
| 4111 C.named(); |
| 4112 } |
| 4113 '''; |
| 4114 UnlinkedExecutable executable = |
| 4115 serializeClassText(text, className: 'C').executables[0]; |
| 4116 expect(executable.isRedirectedConstructor, isTrue); |
| 4117 expect(executable.isFactory, isFalse); |
| 4118 expect(executable.redirectedConstructorName, 'named'); |
| 4119 expect(executable.redirectedConstructor, isNull); |
| 4120 } |
| 4121 |
| 4122 test_constructor_redirected_thisInvocation_unnamed() { |
| 4123 String text = ''' |
| 4124 class C { |
| 4125 C.named() : this(); |
| 4126 C(); |
| 4127 } |
| 4128 '''; |
| 4129 UnlinkedExecutable executable = |
| 4130 serializeClassText(text, className: 'C').executables[0]; |
| 4131 expect(executable.isRedirectedConstructor, isTrue); |
| 4132 expect(executable.isFactory, isFalse); |
| 4133 expect(executable.redirectedConstructorName, isEmpty); |
| 4134 expect(executable.redirectedConstructor, isNull); |
| 4135 } |
| 4136 |
| 4137 test_constructor_return_type() { |
| 4138 UnlinkedExecutable executable = findExecutable('', |
| 4139 executables: serializeClassText('class C { C(); }').executables); |
| 4140 expect(executable.returnType, isNull); |
| 4141 } |
| 4142 |
| 4143 test_constructor_return_type_parameterized() { |
| 4144 UnlinkedExecutable executable = findExecutable('', |
| 4145 executables: serializeClassText('class C<T, U> { C(); }').executables); |
| 4146 expect(executable.returnType, isNull); |
| 4147 } |
| 4148 |
| 4149 test_constructor_withCycles_const() { |
| 4150 serializeLibraryText(''' |
| 4151 class C { |
| 4152 final x; |
| 4153 const C() : x = const D(); |
| 4154 } |
| 4155 class D { |
| 4156 final x; |
| 4157 const D() : x = const C(); |
| 4158 } |
| 4159 class E { |
| 4160 final x; |
| 4161 const E() : x = null; |
| 4162 } |
| 4163 '''); |
| 4164 checkConstCycle('C'); |
| 4165 checkConstCycle('D'); |
| 4166 checkConstCycle('E', hasCycle: false); |
| 4167 } |
| 4168 |
| 4169 test_constructor_withCycles_nonConst() { |
| 4170 serializeLibraryText(''' |
| 4171 class C { |
| 4172 final x; |
| 4173 C() : x = new D(); |
| 4174 } |
| 4175 class D { |
| 4176 final x; |
| 4177 D() : x = new C(); |
| 4178 } |
| 4179 '''); |
| 4180 expect(findClass('C').executables[0].constCycleSlot, 0); |
| 4181 expect(findClass('D').executables[0].constCycleSlot, 0); |
| 4182 } |
| 4183 |
| 4184 test_constructorCycle_redirectToImplicitConstructor() { |
| 4185 serializeLibraryText( |
| 4186 ''' |
| 4187 class C { |
| 4188 const factory C() = D; |
| 4189 } |
| 4190 class D extends C {} |
| 4191 ''', |
| 4192 allowErrors: true); |
| 4193 checkConstCycle('C', hasCycle: false); |
| 4194 } |
| 4195 |
| 4196 test_constructorCycle_redirectToNonConstConstructor() { |
| 4197 // It's not valid Dart but we need to make sure it doesn't crash |
| 4198 // summary generation. |
| 4199 serializeLibraryText( |
| 4200 ''' |
| 4201 class C { |
| 4202 const factory C() = D; |
| 4203 } |
| 4204 class D extends C { |
| 4205 D(); |
| 4206 } |
| 4207 ''', |
| 4208 allowErrors: true); |
| 4209 checkConstCycle('C', hasCycle: false); |
| 4210 } |
| 4211 |
| 4212 test_constructorCycle_redirectToSymbolConstructor() { |
| 4213 // The symbol constructor has some special case behaviors in analyzer. |
| 4214 // Make sure those special case behaviors don't cause problems. |
| 4215 serializeLibraryText( |
| 4216 ''' |
| 4217 class C { |
| 4218 const factory C(String name) = Symbol; |
| 4219 } |
| 4220 ''', |
| 4221 allowErrors: true); |
| 4222 checkConstCycle('C', hasCycle: false); |
| 4223 } |
| 4224 |
| 4225 test_constructorCycle_referenceToClass() { |
| 4226 serializeLibraryText(''' |
| 4227 class C { |
| 4228 final x; |
| 4229 const C() : x = C; |
| 4230 } |
| 4231 '''); |
| 4232 checkConstCycle('C', hasCycle: false); |
| 4233 } |
| 4234 |
| 4235 test_constructorCycle_referenceToEnum() { |
| 4236 serializeLibraryText(''' |
| 4237 enum E { v } |
| 4238 class C { |
| 4239 final x; |
| 4240 const C() : x = E; |
| 4241 } |
| 4242 '''); |
| 4243 checkConstCycle('C', hasCycle: false); |
| 4244 } |
| 4245 |
| 4246 test_constructorCycle_referenceToEnumValue() { |
| 4247 serializeLibraryText(''' |
| 4248 enum E { v } |
| 4249 class C { |
| 4250 final x; |
| 4251 const C() : x = E.v; |
| 4252 } |
| 4253 '''); |
| 4254 checkConstCycle('C', hasCycle: false); |
| 4255 } |
| 4256 |
| 4257 test_constructorCycle_referenceToEnumValues() { |
| 4258 serializeLibraryText(''' |
| 4259 enum E { v } |
| 4260 class C { |
| 4261 final x; |
| 4262 const C() : x = E.values; |
| 4263 } |
| 4264 '''); |
| 4265 checkConstCycle('C', hasCycle: false); |
| 4266 } |
| 4267 |
| 4268 test_constructorCycle_referenceToGenericParameter() { |
| 4269 // It's not valid Dart but we need to make sure it doesn't crash |
| 4270 // summary generation. |
| 4271 serializeLibraryText( |
| 4272 ''' |
| 4273 class C<T> { |
| 4274 final x; |
| 4275 const C() : x = T; |
| 4276 } |
| 4277 ''', |
| 4278 allowErrors: true); |
| 4279 checkConstCycle('C', hasCycle: false); |
| 4280 } |
| 4281 |
| 4282 test_constructorCycle_referenceToGenericParameter_asSupertype() { |
| 4283 // It's not valid Dart but we need to make sure it doesn't crash |
| 4284 // summary generation. |
| 4285 serializeLibraryText( |
| 4286 ''' |
| 4287 class C<T> extends T { |
| 4288 const C(); |
| 4289 } |
| 4290 ''', |
| 4291 allowErrors: true); |
| 4292 checkConstCycle('C', hasCycle: false); |
| 4293 } |
| 4294 |
| 4295 test_constructorCycle_referenceToStaticMethod_inOtherClass() { |
| 4296 serializeLibraryText(''' |
| 4297 class C { |
| 4298 final x; |
| 4299 const C() : x = D.f; |
| 4300 } |
| 4301 class D { |
| 4302 static void f() {} |
| 4303 } |
| 4304 '''); |
| 4305 checkConstCycle('C', hasCycle: false); |
| 4306 } |
| 4307 |
| 4308 test_constructorCycle_referenceToStaticMethod_inSameClass() { |
| 4309 serializeLibraryText(''' |
| 4310 class C { |
| 4311 final x; |
| 4312 static void f() {} |
| 4313 const C() : x = f; |
| 4314 } |
| 4315 '''); |
| 4316 checkConstCycle('C', hasCycle: false); |
| 4317 } |
| 4318 |
| 4319 test_constructorCycle_referenceToTopLevelFunction() { |
| 4320 serializeLibraryText(''' |
| 4321 void f() {} |
| 4322 class C { |
| 4323 final x; |
| 4324 const C() : x = f; |
| 4325 } |
| 4326 '''); |
| 4327 checkConstCycle('C', hasCycle: false); |
| 4328 } |
| 4329 |
| 4330 test_constructorCycle_referenceToTypedef() { |
| 4331 serializeLibraryText(''' |
| 4332 typedef F(); |
| 4333 class C { |
| 4334 final x; |
| 4335 const C() : x = F; |
| 4336 } |
| 4337 '''); |
| 4338 checkConstCycle('C', hasCycle: false); |
| 4339 } |
| 4340 |
| 4341 test_constructorCycle_referenceToUndefinedName() { |
| 4342 // It's not valid Dart but we need to make sure it doesn't crash |
| 4343 // summary generation. |
| 4344 serializeLibraryText( |
| 4345 ''' |
| 4346 class C { |
| 4347 final x; |
| 4348 const C() : x = foo; |
| 4349 } |
| 4350 ''', |
| 4351 allowErrors: true); |
| 4352 checkConstCycle('C', hasCycle: false); |
| 4353 } |
| 4354 |
| 4355 test_constructorCycle_referenceToUndefinedName_viaPrefix() { |
| 4356 // It's not valid Dart but we need to make sure it doesn't crash |
| 4357 // summary generation. |
| 4358 addNamedSource('/a.dart', ''); |
| 4359 serializeLibraryText( |
| 4360 ''' |
| 4361 import 'a.dart' as a; |
| 4362 class C { |
| 4363 final x; |
| 4364 const C() : x = a.foo; |
| 4365 } |
| 4366 ''', |
| 4367 allowErrors: true); |
| 4368 checkConstCycle('C', hasCycle: false); |
| 4369 } |
| 4370 |
| 4371 test_constructorCycle_referenceToUndefinedName_viaPrefix_nonExistentFile() { |
| 4372 // It's not valid Dart but we need to make sure it doesn't crash |
| 4373 // summary generation. |
| 4374 allowMissingFiles = true; |
| 4375 serializeLibraryText( |
| 4376 ''' |
| 4377 import 'a.dart' as a; |
| 4378 class C { |
| 4379 final x; |
| 4380 const C() : x = a.foo; |
| 4381 } |
| 4382 ''', |
| 4383 allowErrors: true); |
| 4384 checkConstCycle('C', hasCycle: false); |
| 4385 } |
| 4386 |
| 4387 test_constructorCycle_trivial() { |
| 4388 serializeLibraryText( |
| 4389 ''' |
| 4390 class C { |
| 4391 const C() : this(); |
| 4392 } |
| 4393 ''', |
| 4394 allowErrors: true); |
| 4395 checkConstCycle('C'); |
| 4396 } |
| 4397 |
| 4398 test_constructorCycle_viaFactoryRedirect() { |
| 4399 serializeLibraryText( |
| 4400 ''' |
| 4401 class C { |
| 4402 const C(); |
| 4403 const factory C.named() = D; |
| 4404 } |
| 4405 class D extends C { |
| 4406 final x; |
| 4407 const D() : x = y; |
| 4408 } |
| 4409 const y = const C.named(); |
| 4410 ''', |
| 4411 allowErrors: true); |
| 4412 checkConstCycle('C', hasCycle: false); |
| 4413 checkConstCycle('C', name: 'named'); |
| 4414 checkConstCycle('D'); |
| 4415 } |
| 4416 |
| 4417 test_constructorCycle_viaFinalField() { |
| 4418 serializeLibraryText( |
| 4419 ''' |
| 4420 class C { |
| 4421 final x = const C(); |
| 4422 const C(); |
| 4423 } |
| 4424 ''', |
| 4425 allowErrors: true); |
| 4426 checkConstCycle('C'); |
| 4427 } |
| 4428 |
| 4429 test_constructorCycle_viaLength() { |
| 4430 // It's not valid Dart but we need to make sure it doesn't crash |
| 4431 // summary generation. |
| 4432 serializeLibraryText( |
| 4433 ''' |
| 4434 class C { |
| 4435 final x; |
| 4436 const C() : x = y.length; |
| 4437 } |
| 4438 const y = const C(); |
| 4439 ''', |
| 4440 allowErrors: true); |
| 4441 checkConstCycle('C'); |
| 4442 } |
| 4443 |
| 4444 test_constructorCycle_viaNamedConstructor() { |
| 4445 serializeLibraryText(''' |
| 4446 class C { |
| 4447 final x; |
| 4448 const C() : x = const D.named(); |
| 4449 } |
| 4450 class D { |
| 4451 final x; |
| 4452 const D.named() : x = const C(); |
| 4453 } |
| 4454 '''); |
| 4455 checkConstCycle('C'); |
| 4456 checkConstCycle('D', name: 'named'); |
| 4457 } |
| 4458 |
| 4459 test_constructorCycle_viaOrdinaryRedirect() { |
| 4460 serializeLibraryText(''' |
| 4461 class C { |
| 4462 final x; |
| 4463 const C() : this.named(); |
| 4464 const C.named() : x = const C(); |
| 4465 } |
| 4466 '''); |
| 4467 checkConstCycle('C'); |
| 4468 checkConstCycle('C', name: 'named'); |
| 4469 } |
| 4470 |
| 4471 test_constructorCycle_viaOrdinaryRedirect_suppressSupertype() { |
| 4472 // Since C redirects to C.named, it doesn't implicitly refer to B's unnamed |
| 4473 // constructor. Therefore there is no cycle. |
| 4474 serializeLibraryText(''' |
| 4475 class B { |
| 4476 final x; |
| 4477 const B() : x = const C(); |
| 4478 const B.named() : x = null; |
| 4479 } |
| 4480 class C extends B { |
| 4481 const C() : this.named(); |
| 4482 const C.named() : super.named(); |
| 4483 } |
| 4484 '''); |
| 4485 checkConstCycle('B', hasCycle: false); |
| 4486 checkConstCycle('B', name: 'named', hasCycle: false); |
| 4487 checkConstCycle('C', hasCycle: false); |
| 4488 checkConstCycle('C', name: 'named', hasCycle: false); |
| 4489 } |
| 4490 |
| 4491 test_constructorCycle_viaRedirectArgument() { |
| 4492 serializeLibraryText( |
| 4493 ''' |
| 4494 class C { |
| 4495 final x; |
| 4496 const C() : this.named(y); |
| 4497 const C.named(this.x); |
| 4498 } |
| 4499 const y = const C(); |
| 4500 ''', |
| 4501 allowErrors: true); |
| 4502 checkConstCycle('C'); |
| 4503 checkConstCycle('C', name: 'named', hasCycle: false); |
| 4504 } |
| 4505 |
| 4506 test_constructorCycle_viaStaticField_inOtherClass() { |
| 4507 serializeLibraryText( |
| 4508 ''' |
| 4509 class C { |
| 4510 final x; |
| 4511 const C() : x = D.y; |
| 4512 } |
| 4513 class D { |
| 4514 static const y = const C(); |
| 4515 } |
| 4516 ''', |
| 4517 allowErrors: true); |
| 4518 checkConstCycle('C'); |
| 4519 } |
| 4520 |
| 4521 test_constructorCycle_viaStaticField_inSameClass() { |
| 4522 serializeLibraryText( |
| 4523 ''' |
| 4524 class C { |
| 4525 final x; |
| 4526 static const y = const C(); |
| 4527 const C() : x = y; |
| 4528 } |
| 4529 ''', |
| 4530 allowErrors: true); |
| 4531 checkConstCycle('C'); |
| 4532 } |
| 4533 |
| 4534 test_constructorCycle_viaSuperArgument() { |
| 4535 serializeLibraryText( |
| 4536 ''' |
| 4537 class B { |
| 4538 final x; |
| 4539 const B(this.x); |
| 4540 } |
| 4541 class C extends B { |
| 4542 const C() : super(y); |
| 4543 } |
| 4544 const y = const C(); |
| 4545 ''', |
| 4546 allowErrors: true); |
| 4547 checkConstCycle('B', hasCycle: false); |
| 4548 checkConstCycle('C'); |
| 4549 } |
| 4550 |
| 4551 test_constructorCycle_viaSupertype() { |
| 4552 serializeLibraryText(''' |
| 4553 class C { |
| 4554 final x; |
| 4555 const C() : x = const D(); |
| 4556 } |
| 4557 class D extends C { |
| 4558 const D(); |
| 4559 } |
| 4560 '''); |
| 4561 checkConstCycle('C'); |
| 4562 checkConstCycle('D'); |
| 4563 } |
| 4564 |
| 4565 test_constructorCycle_viaSupertype_Enum() { |
| 4566 // It's not valid Dart but we need to make sure it doesn't crash |
| 4567 // summary generation. |
| 4568 serializeLibraryText( |
| 4569 ''' |
| 4570 enum E { v } |
| 4571 class C extends E { |
| 4572 const C(); |
| 4573 } |
| 4574 ''', |
| 4575 allowErrors: true); |
| 4576 checkConstCycle('C', hasCycle: false); |
| 4577 } |
| 4578 |
| 4579 test_constructorCycle_viaSupertype_explicit() { |
| 4580 serializeLibraryText(''' |
| 4581 class C { |
| 4582 final x; |
| 4583 const C() : x = const D(); |
| 4584 const C.named() : x = const D.named(); |
| 4585 } |
| 4586 class D extends C { |
| 4587 const D() : super(); |
| 4588 const D.named() : super.named(); |
| 4589 } |
| 4590 '''); |
| 4591 checkConstCycle('C'); |
| 4592 checkConstCycle('C', name: 'named'); |
| 4593 checkConstCycle('D'); |
| 4594 checkConstCycle('D', name: 'named'); |
| 4595 } |
| 4596 |
| 4597 test_constructorCycle_viaSupertype_explicit_undefined() { |
| 4598 // It's not valid Dart but we need to make sure it doesn't crash |
| 4599 // summary generation. |
| 4600 serializeLibraryText( |
| 4601 ''' |
| 4602 class C { |
| 4603 final x; |
| 4604 const C() : x = const D(); |
| 4605 } |
| 4606 class D extends C { |
| 4607 const D() : super.named(); |
| 4608 } |
| 4609 ''', |
| 4610 allowErrors: true); |
| 4611 checkConstCycle('C', hasCycle: false); |
| 4612 checkConstCycle('D', hasCycle: false); |
| 4613 } |
| 4614 |
| 4615 test_constructorCycle_viaSupertype_withDefaultTypeArgument() { |
| 4616 serializeLibraryText(''' |
| 4617 class C<T> { |
| 4618 final x; |
| 4619 const C() : x = const D(); |
| 4620 } |
| 4621 class D extends C { |
| 4622 const D(); |
| 4623 } |
| 4624 '''); |
| 4625 checkConstCycle('C'); |
| 4626 checkConstCycle('D'); |
| 4627 } |
| 4628 |
| 4629 test_constructorCycle_viaSupertype_withTypeArgument() { |
| 4630 serializeLibraryText(''' |
| 4631 class C<T> { |
| 4632 final x; |
| 4633 const C() : x = const D(); |
| 4634 } |
| 4635 class D extends C<int> { |
| 4636 const D(); |
| 4637 } |
| 4638 '''); |
| 4639 checkConstCycle('C'); |
| 4640 checkConstCycle('D'); |
| 4641 } |
| 4642 |
| 4643 test_constructorCycle_viaTopLevelVariable() { |
| 4644 serializeLibraryText( |
| 4645 ''' |
| 4646 class C { |
| 4647 final x; |
| 4648 const C() : x = y; |
| 4649 } |
| 4650 const y = const C(); |
| 4651 ''', |
| 4652 allowErrors: true); |
| 4653 checkConstCycle('C'); |
| 4654 } |
| 4655 |
| 4656 test_constructorCycle_viaTopLevelVariable_imported() { |
| 4657 addNamedSource( |
| 4658 '/a.dart', |
| 4659 ''' |
| 4660 import 'test.dart'; |
| 4661 const y = const C(); |
| 4662 '''); |
| 4663 serializeLibraryText( |
| 4664 ''' |
| 4665 import 'a.dart'; |
| 4666 class C { |
| 4667 final x; |
| 4668 const C() : x = y; |
| 4669 } |
| 4670 ''', |
| 4671 allowErrors: true); |
| 4672 checkConstCycle('C'); |
| 4673 } |
| 4674 |
| 4675 test_constructorCycle_viaTopLevelVariable_importedViaPrefix() { |
| 4676 addNamedSource( |
| 4677 '/a.dart', |
| 4678 ''' |
| 4679 import 'test.dart'; |
| 4680 const y = const C(); |
| 4681 '''); |
| 4682 serializeLibraryText( |
| 4683 ''' |
| 4684 import 'a.dart' as a; |
| 4685 class C { |
| 4686 final x; |
| 4687 const C() : x = a.y; |
| 4688 } |
| 4689 ''', |
| 4690 allowErrors: true); |
| 4691 checkConstCycle('C'); |
| 4692 } |
| 4693 |
| 4694 test_dependencies_export_to_export_unused() { |
| 4695 addNamedSource('/a.dart', 'export "b.dart";'); |
| 4696 addNamedSource('/b.dart', ''); |
| 4697 serializeLibraryText('export "a.dart";'); |
| 4698 // The main test library depends on b.dart, even though it doesn't |
| 4699 // re-export any names defined in b.dart, because a change to b.dart might |
| 4700 // cause it to start exporting a name that the main test library *does* |
| 4701 // use. |
| 4702 checkHasDependency('b.dart'); |
| 4703 } |
| 4704 |
| 4705 test_dependencies_export_unused() { |
| 4706 addNamedSource('/a.dart', ''); |
| 4707 serializeLibraryText('export "a.dart";'); |
| 4708 // The main test library depends on a.dart, even though it doesn't |
| 4709 // re-export any names defined in a.dart, because a change to a.dart might |
| 4710 // cause it to start exporting a name that the main test library *will* |
| 4711 // re-export. |
| 4712 checkHasDependency('a.dart'); |
| 4713 } |
| 4714 |
| 4715 test_dependencies_import_to_export() { |
| 4716 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 4717 addNamedSource('/b.dart', 'library b;'); |
| 4718 serializeLibraryText('import "a.dart"; A a;'); |
| 4719 checkHasDependency('a.dart'); |
| 4720 // The main test library depends on b.dart, because names defined in |
| 4721 // b.dart are exported by a.dart. |
| 4722 checkHasDependency('b.dart'); |
| 4723 } |
| 4724 |
| 4725 test_dependencies_import_to_export_in_subdirs_absolute_export() { |
| 4726 addNamedSource('/a/a.dart', |
| 4727 'library a; export "${absUri('/a/b/b.dart')}"; class A {}'); |
| 4728 addNamedSource('/a/b/b.dart', 'library b;'); |
| 4729 serializeLibraryText('import "a/a.dart"; A a;'); |
| 4730 checkHasDependency('a/a.dart'); |
| 4731 // The main test library depends on b.dart, because names defined in |
| 4732 // b.dart are exported by a.dart. |
| 4733 checkHasDependency(absUri('/a/b/b.dart')); |
| 4734 } |
| 4735 |
| 4736 test_dependencies_import_to_export_in_subdirs_absolute_import() { |
| 4737 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 4738 addNamedSource('/a/b/b.dart', 'library b;'); |
| 4739 serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;'); |
| 4740 checkHasDependency(absUri('/a/a.dart')); |
| 4741 // The main test library depends on b.dart, because names defined in |
| 4742 // b.dart are exported by a.dart. |
| 4743 checkHasDependency(absUri('/a/b/b.dart')); |
| 4744 } |
| 4745 |
| 4746 test_dependencies_import_to_export_in_subdirs_relative() { |
| 4747 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}'); |
| 4748 addNamedSource('/a/b/b.dart', 'library b;'); |
| 4749 serializeLibraryText('import "a/a.dart"; A a;'); |
| 4750 checkHasDependency('a/a.dart'); |
| 4751 // The main test library depends on b.dart, because names defined in |
| 4752 // b.dart are exported by a.dart. |
| 4753 checkHasDependency('a/b/b.dart'); |
| 4754 } |
| 4755 |
| 4756 test_dependencies_import_to_export_loop() { |
| 4757 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 4758 addNamedSource('/b.dart', 'library b; export "a.dart";'); |
| 4759 serializeLibraryText('import "a.dart"; A a;'); |
| 4760 checkHasDependency('a.dart'); |
| 4761 // Serialization should have been able to walk the transitive export |
| 4762 // dependencies to b.dart without going into an infinite loop. |
| 4763 checkHasDependency('b.dart'); |
| 4764 } |
| 4765 |
| 4766 test_dependencies_import_to_export_transitive_closure() { |
| 4767 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}'); |
| 4768 addNamedSource('/b.dart', 'library b; export "c.dart";'); |
| 4769 addNamedSource('/c.dart', 'library c;'); |
| 4770 serializeLibraryText('import "a.dart"; A a;'); |
| 4771 checkHasDependency('a.dart'); |
| 4772 // The main test library depends on c.dart, because names defined in |
| 4773 // c.dart are exported by b.dart and then re-exported by a.dart. |
| 4774 checkHasDependency('c.dart'); |
| 4775 } |
| 4776 |
| 4777 test_dependencies_import_to_export_unused() { |
| 4778 addNamedSource('/a.dart', 'export "b.dart";'); |
| 4779 addNamedSource('/b.dart', ''); |
| 4780 serializeLibraryText('import "a.dart";', allowErrors: true); |
| 4781 // The main test library depends on b.dart, even though it doesn't use any |
| 4782 // names defined in b.dart, because a change to b.dart might cause it to |
| 4783 // start exporting a name that the main test library *does* use. |
| 4784 checkHasDependency('b.dart'); |
| 4785 } |
| 4786 |
| 4787 test_dependencies_import_transitive_closure() { |
| 4788 addNamedSource( |
| 4789 '/a.dart', 'library a; import "b.dart"; class A extends B {}'); |
| 4790 addNamedSource('/b.dart', 'library b; class B {}'); |
| 4791 serializeLibraryText('import "a.dart"; A a;'); |
| 4792 checkHasDependency('a.dart'); |
| 4793 // The main test library doesn't depend on b.dart, because no change to |
| 4794 // b.dart can possibly affect the serialized element model for it. |
| 4795 checkLacksDependency('b.dart'); |
| 4796 } |
| 4797 |
| 4798 test_dependencies_import_unused() { |
| 4799 addNamedSource('/a.dart', ''); |
| 4800 serializeLibraryText('import "a.dart";', allowErrors: true); |
| 4801 // The main test library depends on a.dart, even though it doesn't use any |
| 4802 // names defined in a.dart, because a change to a.dart might cause it to |
| 4803 // start exporting a name that the main test library *does* use. |
| 4804 checkHasDependency('a.dart'); |
| 4805 } |
| 4806 |
| 4807 test_dependencies_parts() { |
| 4808 addNamedSource( |
| 4809 '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}'); |
| 4810 addNamedSource('/b.dart', 'part of a;'); |
| 4811 addNamedSource('/c.dart', 'part of a;'); |
| 4812 serializeLibraryText('import "a.dart"; A a;'); |
| 4813 int dep = checkHasDependency('a.dart'); |
| 4814 checkDependencyParts(linked.dependencies[dep], ['b.dart', 'c.dart']); |
| 4815 } |
| 4816 |
| 4817 test_dependencies_parts_relative_to_importing_library() { |
| 4818 addNamedSource('/a/b.dart', 'export "c/d.dart";'); |
| 4819 addNamedSource('/a/c/d.dart', |
| 4820 'library d; part "e/f.dart"; part "g/h.dart"; class D {}'); |
| 4821 addNamedSource('/a/c/e/f.dart', 'part of d;'); |
| 4822 addNamedSource('/a/c/g/h.dart', 'part of d;'); |
| 4823 serializeLibraryText('import "a/b.dart"; D d;'); |
| 4824 int dep = checkHasDependency('a/c/d.dart'); |
| 4825 checkDependencyParts( |
| 4826 linked.dependencies[dep], ['a/c/e/f.dart', 'a/c/g/h.dart']); |
| 4827 } |
| 4828 |
| 4829 test_elements_in_part() { |
| 4830 addNamedSource( |
| 4831 '/part1.dart', |
| 4832 ''' |
| 4833 part of my.lib; |
| 4834 |
| 4835 class C {} |
| 4836 enum E { v } |
| 4837 var v; |
| 4838 f() {} |
| 4839 typedef F(); |
| 4840 '''); |
| 4841 serializeLibraryText('library my.lib; part "part1.dart";'); |
| 4842 UnlinkedUnit unit = unlinkedUnits[1]; |
| 4843 expect(findClass('C', unit: unit), isNotNull); |
| 4844 expect(findEnum('E', unit: unit), isNotNull); |
| 4845 expect(findVariable('v', variables: unit.variables), isNotNull); |
| 4846 expect(findExecutable('f', executables: unit.executables), isNotNull); |
| 4847 expect(findTypedef('F', unit: unit), isNotNull); |
| 4848 } |
| 4849 |
| 4850 test_enum() { |
| 4851 String text = 'enum E { v1 }'; |
| 4852 UnlinkedEnum e = serializeEnumText(text); |
| 4853 expect(e.name, 'E'); |
| 4854 expect(e.nameOffset, text.indexOf('E')); |
| 4855 expect(e.values, hasLength(1)); |
| 4856 expect(e.values[0].name, 'v1'); |
| 4857 expect(e.values[0].nameOffset, text.indexOf('v1')); |
| 4858 _assertCodeRange(e.codeRange, 0, 13); |
| 4859 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 4860 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 4861 ReferenceKind.classOrEnum); |
| 4862 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E'); |
| 4863 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 4864 expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(2)); |
| 4865 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind, |
| 4866 ReferenceKind.propertyAccessor); |
| 4867 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'values'); |
| 4868 expect( |
| 4869 unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters, |
| 4870 0); |
| 4871 expect(unlinkedUnits[0].publicNamespace.names[0].members[1].kind, |
| 4872 ReferenceKind.propertyAccessor); |
| 4873 expect(unlinkedUnits[0].publicNamespace.names[0].members[1].name, 'v1'); |
| 4874 expect( |
| 4875 unlinkedUnits[0].publicNamespace.names[0].members[1].numTypeParameters, |
| 4876 0); |
| 4877 } |
| 4878 |
| 4879 test_enum_documented() { |
| 4880 String text = ''' |
| 4881 // Extra comment so doc comment offset != 0 |
| 4882 /** |
| 4883 * Docs |
| 4884 */ |
| 4885 enum E { v }'''; |
| 4886 UnlinkedEnum enm = serializeEnumText(text); |
| 4887 expect(enm.documentationComment, isNotNull); |
| 4888 checkDocumentationComment(enm.documentationComment, text); |
| 4889 } |
| 4890 |
| 4891 test_enum_order() { |
| 4892 UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }'); |
| 4893 expect(e.values, hasLength(2)); |
| 4894 expect(e.values[0].name, 'v1'); |
| 4895 expect(e.values[1].name, 'v2'); |
| 4896 } |
| 4897 |
| 4898 test_enum_private() { |
| 4899 serializeEnumText('enum _E { v1 }', '_E'); |
| 4900 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 4901 } |
| 4902 |
| 4903 test_enum_value_documented() { |
| 4904 String text = ''' |
| 4905 enum E { |
| 4906 /** |
| 4907 * Docs |
| 4908 */ |
| 4909 v |
| 4910 }'''; |
| 4911 UnlinkedEnumValue value = serializeEnumText(text).values[0]; |
| 4912 expect(value.documentationComment, isNotNull); |
| 4913 checkDocumentationComment(value.documentationComment, text); |
| 4914 } |
| 4915 |
| 4916 test_enum_value_private() { |
| 4917 serializeEnumText('enum E { _v }', 'E'); |
| 4918 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 4919 expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1)); |
| 4920 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'values'); |
| 4921 } |
| 4922 |
| 4923 test_executable_abstract() { |
| 4924 UnlinkedExecutable executable = |
| 4925 serializeClassText('abstract class C { f(); }').executables[0]; |
| 4926 expect(executable.isAbstract, isTrue); |
| 4927 } |
| 4928 |
| 4929 test_executable_concrete() { |
| 4930 UnlinkedExecutable executable = |
| 4931 serializeClassText('abstract class C { f() {} }').executables[0]; |
| 4932 expect(executable.isAbstract, isFalse); |
| 4933 } |
| 4934 |
| 4935 test_executable_function() { |
| 4936 String text = ' f() {}'; |
| 4937 UnlinkedExecutable executable = serializeExecutableText(text); |
| 4938 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 4939 expect(executable.returnType, isNull); |
| 4940 expect(executable.isAsynchronous, isFalse); |
| 4941 expect(executable.isExternal, isFalse); |
| 4942 expect(executable.isGenerator, isFalse); |
| 4943 expect(executable.nameOffset, text.indexOf('f')); |
| 4944 expect(executable.visibleOffset, 0); |
| 4945 expect(executable.visibleLength, 0); |
| 4946 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 4947 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 4948 ReferenceKind.topLevelFunction); |
| 4949 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f'); |
| 4950 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 4951 } |
| 4952 |
| 4953 test_executable_function_async() { |
| 4954 UnlinkedExecutable executable = serializeExecutableText(r''' |
| 4955 import 'dart:async'; |
| 4956 Future f() async {} |
| 4957 '''); |
| 4958 expect(executable.isAsynchronous, isTrue); |
| 4959 expect(executable.isGenerator, isFalse); |
| 4960 } |
| 4961 |
| 4962 test_executable_function_asyncStar() { |
| 4963 UnlinkedExecutable executable = serializeExecutableText(r''' |
| 4964 import 'dart:async'; |
| 4965 Stream f() async* {} |
| 4966 '''); |
| 4967 expect(executable.isAsynchronous, isTrue); |
| 4968 expect(executable.isGenerator, isTrue); |
| 4969 } |
| 4970 |
| 4971 test_executable_function_explicit_return() { |
| 4972 UnlinkedExecutable executable = |
| 4973 serializeExecutableText('dynamic f() => null;'); |
| 4974 checkDynamicTypeRef(executable.returnType); |
| 4975 } |
| 4976 |
| 4977 test_executable_function_external() { |
| 4978 UnlinkedExecutable executable = serializeExecutableText('external f();'); |
| 4979 expect(executable.isExternal, isTrue); |
| 4980 } |
| 4981 |
| 4982 test_executable_function_private() { |
| 4983 serializeExecutableText('_f() {}', executableName: '_f'); |
| 4984 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 4985 } |
| 4986 |
| 4987 test_executable_getter() { |
| 4988 String text = 'int get f => 1;'; |
| 4989 UnlinkedExecutable executable = serializeExecutableText(text); |
| 4990 expect(executable.kind, UnlinkedExecutableKind.getter); |
| 4991 expect(executable.returnType, isNotNull); |
| 4992 expect(executable.isAsynchronous, isFalse); |
| 4993 expect(executable.isExternal, isFalse); |
| 4994 expect(executable.isGenerator, isFalse); |
| 4995 expect(executable.nameOffset, text.indexOf('f')); |
| 4996 expect(findVariable('f'), isNull); |
| 4997 expect(findExecutable('f='), isNull); |
| 4998 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 4999 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 5000 ReferenceKind.topLevelPropertyAccessor); |
| 5001 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f'); |
| 5002 } |
| 5003 |
| 5004 test_executable_getter_external() { |
| 5005 UnlinkedExecutable executable = |
| 5006 serializeExecutableText('external int get f;'); |
| 5007 expect(executable.isExternal, isTrue); |
| 5008 } |
| 5009 |
| 5010 test_executable_getter_private() { |
| 5011 serializeExecutableText('int get _f => 1;', executableName: '_f'); |
| 5012 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 5013 } |
| 5014 |
| 5015 test_executable_getter_type() { |
| 5016 UnlinkedExecutable executable = serializeExecutableText('int get f => 1;'); |
| 5017 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int'); |
| 5018 expect(executable.parameters, isEmpty); |
| 5019 } |
| 5020 |
| 5021 test_executable_getter_type_implicit() { |
| 5022 UnlinkedExecutable executable = serializeExecutableText('get f => 1;'); |
| 5023 expect(executable.returnType, isNull); |
| 5024 expect(executable.parameters, isEmpty); |
| 5025 } |
| 5026 |
| 5027 test_executable_localFunctions() { |
| 5028 String code = r''' |
| 5029 f() { // 1 |
| 5030 f1() {} |
| 5031 { // 2 |
| 5032 f2() {} |
| 5033 } // 3 |
| 5034 } // 4 |
| 5035 '''; |
| 5036 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5037 List<UnlinkedExecutable> functions = executable.localFunctions; |
| 5038 expect(functions, hasLength(2)); |
| 5039 { |
| 5040 UnlinkedExecutable f1 = functions.singleWhere((v) => v.name == 'f1'); |
| 5041 _assertExecutableVisible(code, f1, '{ // 1', '} // 4'); |
| 5042 } |
| 5043 { |
| 5044 UnlinkedExecutable f2 = functions.singleWhere((v) => v.name == 'f2'); |
| 5045 _assertExecutableVisible(code, f2, '{ // 2', '} // 3'); |
| 5046 } |
| 5047 } |
| 5048 |
| 5049 test_executable_localLabels_inMethod() { |
| 5050 String code = r''' |
| 5051 class C { |
| 5052 m() { |
| 5053 aaa: while (true) {} |
| 5054 bbb: while (true) {} |
| 5055 } |
| 5056 } |
| 5057 '''; |
| 5058 UnlinkedExecutable executable = |
| 5059 findExecutable('m', executables: serializeClassText(code).executables); |
| 5060 List<UnlinkedLabel> labels = executable.localLabels; |
| 5061 expect(labels, hasLength(2)); |
| 5062 { |
| 5063 UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa'); |
| 5064 expect(aaa, isNotNull); |
| 5065 expect(aaa.isOnSwitchMember, isFalse); |
| 5066 expect(aaa.isOnSwitchStatement, isFalse); |
| 5067 } |
| 5068 { |
| 5069 UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb'); |
| 5070 expect(bbb, isNotNull); |
| 5071 expect(bbb.isOnSwitchMember, isFalse); |
| 5072 expect(bbb.isOnSwitchStatement, isFalse); |
| 5073 } |
| 5074 } |
| 5075 |
| 5076 test_executable_localLabels_inTopLevelFunction() { |
| 5077 String code = r''' |
| 5078 f() { |
| 5079 aaa: while (true) {} |
| 5080 bbb: switch (42) { |
| 5081 ccc: case 0: |
| 5082 break; |
| 5083 ddd: default: |
| 5084 break; |
| 5085 } |
| 5086 } |
| 5087 '''; |
| 5088 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5089 List<UnlinkedLabel> labels = executable.localLabels; |
| 5090 expect(labels, hasLength(4)); |
| 5091 { |
| 5092 UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa'); |
| 5093 expect(aaa, isNotNull); |
| 5094 expect(aaa.isOnSwitchMember, isFalse); |
| 5095 expect(aaa.isOnSwitchStatement, isFalse); |
| 5096 } |
| 5097 { |
| 5098 UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb'); |
| 5099 expect(bbb, isNotNull); |
| 5100 expect(bbb.isOnSwitchMember, isFalse); |
| 5101 expect(bbb.isOnSwitchStatement, isTrue); |
| 5102 } |
| 5103 { |
| 5104 UnlinkedLabel ccc = labels.singleWhere((l) => l.name == 'ccc'); |
| 5105 expect(ccc, isNotNull); |
| 5106 expect(ccc.isOnSwitchMember, isTrue); |
| 5107 expect(ccc.isOnSwitchStatement, isFalse); |
| 5108 } |
| 5109 { |
| 5110 UnlinkedLabel ccc = labels.singleWhere((l) => l.name == 'ddd'); |
| 5111 expect(ccc, isNotNull); |
| 5112 expect(ccc.isOnSwitchMember, isTrue); |
| 5113 expect(ccc.isOnSwitchStatement, isFalse); |
| 5114 } |
| 5115 } |
| 5116 |
| 5117 test_executable_localLabels_inTopLevelGetter() { |
| 5118 String code = r''' |
| 5119 get g { |
| 5120 aaa: while (true) {} |
| 5121 bbb: while (true) {} |
| 5122 } |
| 5123 '''; |
| 5124 UnlinkedExecutable executable = |
| 5125 serializeExecutableText(code, executableName: 'g'); |
| 5126 List<UnlinkedLabel> labels = executable.localLabels; |
| 5127 expect(labels, hasLength(2)); |
| 5128 { |
| 5129 UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa'); |
| 5130 expect(aaa, isNotNull); |
| 5131 expect(aaa.isOnSwitchMember, isFalse); |
| 5132 expect(aaa.isOnSwitchStatement, isFalse); |
| 5133 } |
| 5134 { |
| 5135 UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb'); |
| 5136 expect(bbb, isNotNull); |
| 5137 expect(bbb.isOnSwitchMember, isFalse); |
| 5138 expect(bbb.isOnSwitchStatement, isFalse); |
| 5139 } |
| 5140 } |
| 5141 |
| 5142 test_executable_localLabels_namedExpressionLabel() { |
| 5143 String code = r''' |
| 5144 f() { |
| 5145 foo(p: 42); |
| 5146 } |
| 5147 foo({int p}) {} |
| 5148 '''; |
| 5149 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5150 List<UnlinkedLabel> labels = executable.localLabels; |
| 5151 expect(labels, isEmpty); |
| 5152 } |
| 5153 |
| 5154 test_executable_localVariables_catch() { |
| 5155 String code = r''' |
| 5156 f() { // 1 |
| 5157 try { |
| 5158 throw 42; |
| 5159 } on int catch (e, st) { // 2 |
| 5160 print(e); |
| 5161 print(st); |
| 5162 } // 3 |
| 5163 } // 4 |
| 5164 '''; |
| 5165 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5166 List<UnlinkedVariable> variables = executable.localVariables; |
| 5167 expect(variables, hasLength(2)); |
| 5168 { |
| 5169 UnlinkedVariable e = variables.singleWhere((v) => v.name == 'e'); |
| 5170 _assertVariableVisible(code, e, 'on int catch (', '} // 3'); |
| 5171 checkTypeRef(e.type, 'dart:core', 'dart:core', 'int'); |
| 5172 } |
| 5173 { |
| 5174 UnlinkedVariable st = variables.singleWhere((v) => v.name == 'st'); |
| 5175 _assertVariableVisible(code, st, 'on int catch (', '} // 3'); |
| 5176 } |
| 5177 } |
| 5178 |
| 5179 test_executable_localVariables_catch_noVariables() { |
| 5180 String code = r''' |
| 5181 f() { |
| 5182 try { |
| 5183 throw 42; |
| 5184 } on int {} |
| 5185 } |
| 5186 '''; |
| 5187 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5188 List<UnlinkedVariable> variables = executable.localVariables; |
| 5189 expect(variables, isEmpty); |
| 5190 } |
| 5191 |
| 5192 test_executable_localVariables_empty() { |
| 5193 UnlinkedExecutable executable = serializeExecutableText(r''' |
| 5194 f() { |
| 5195 } |
| 5196 '''); |
| 5197 expect(executable.localVariables, isEmpty); |
| 5198 } |
| 5199 |
| 5200 test_executable_localVariables_forEachLoop() { |
| 5201 String code = r''' |
| 5202 f() { // 1 |
| 5203 for (int i in <int>[]) { // 2 |
| 5204 print(i); |
| 5205 } // 3 |
| 5206 } // 4 |
| 5207 '''; |
| 5208 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5209 List<UnlinkedVariable> variables = executable.localVariables; |
| 5210 expect(variables, hasLength(1)); |
| 5211 { |
| 5212 UnlinkedVariable i = variables.singleWhere((v) => v.name == 'i'); |
| 5213 _assertVariableVisible(code, i, 'for', '} // 3'); |
| 5214 checkTypeRef(i.type, 'dart:core', 'dart:core', 'int'); |
| 5215 } |
| 5216 } |
| 5217 |
| 5218 test_executable_localVariables_forEachLoop_outside() { |
| 5219 String code = r''' |
| 5220 f() { // 1 |
| 5221 int i; |
| 5222 for (i in <int>[]) { |
| 5223 print(i); |
| 5224 } |
| 5225 } // 4 |
| 5226 '''; |
| 5227 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5228 List<UnlinkedVariable> variables = executable.localVariables; |
| 5229 expect(variables, hasLength(1)); |
| 5230 { |
| 5231 UnlinkedVariable i = variables.singleWhere((v) => v.name == 'i'); |
| 5232 _assertVariableVisible(code, i, '{ // 1', '} // 4'); |
| 5233 checkTypeRef(i.type, 'dart:core', 'dart:core', 'int'); |
| 5234 } |
| 5235 } |
| 5236 |
| 5237 test_executable_localVariables_forLoop() { |
| 5238 String code = r''' |
| 5239 f() { // 1 |
| 5240 for (int i = 0, j = 0; i < 10; i++, j++) { // 2 |
| 5241 print(i); |
| 5242 } // 3 |
| 5243 } // 4 |
| 5244 '''; |
| 5245 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5246 List<UnlinkedVariable> variables = executable.localVariables; |
| 5247 expect(variables, hasLength(2)); |
| 5248 { |
| 5249 UnlinkedVariable i = variables.singleWhere((v) => v.name == 'i'); |
| 5250 _assertVariableVisible(code, i, 'for', '} // 3'); |
| 5251 checkTypeRef(i.type, 'dart:core', 'dart:core', 'int'); |
| 5252 } |
| 5253 { |
| 5254 UnlinkedVariable i = variables.singleWhere((v) => v.name == 'j'); |
| 5255 _assertVariableVisible(code, i, 'for', '} // 3'); |
| 5256 checkTypeRef(i.type, 'dart:core', 'dart:core', 'int'); |
| 5257 } |
| 5258 } |
| 5259 |
| 5260 test_executable_localVariables_forLoop_noVariables() { |
| 5261 String code = r''' |
| 5262 f() { |
| 5263 for (; true;) {} |
| 5264 } |
| 5265 '''; |
| 5266 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5267 List<UnlinkedVariable> variables = executable.localVariables; |
| 5268 expect(variables, isEmpty); |
| 5269 } |
| 5270 |
| 5271 test_executable_localVariables_inConstructor() { |
| 5272 String code = r''' |
| 5273 class C { |
| 5274 C() { // 1 |
| 5275 int v; |
| 5276 } // 2 |
| 5277 } |
| 5278 '''; |
| 5279 UnlinkedExecutable executable = |
| 5280 findExecutable('', executables: serializeClassText(code).executables); |
| 5281 List<UnlinkedVariable> variables = executable.localVariables; |
| 5282 expect(variables, hasLength(1)); |
| 5283 { |
| 5284 UnlinkedVariable v = variables.singleWhere((v) => v.name == 'v'); |
| 5285 _assertVariableVisible(code, v, '{ // 1', '} // 2'); |
| 5286 checkTypeRef(v.type, 'dart:core', 'dart:core', 'int'); |
| 5287 } |
| 5288 } |
| 5289 |
| 5290 test_executable_localVariables_inLocalFunctions() { |
| 5291 String code = r''' |
| 5292 f() { |
| 5293 f1() { // 1 |
| 5294 int v1 = 1; |
| 5295 } // 2 |
| 5296 f2() { // 3 |
| 5297 int v1 = 1; |
| 5298 f3() { // 4 |
| 5299 int v2 = 1; |
| 5300 } // 5 |
| 5301 } // 6 |
| 5302 } // 7 |
| 5303 '''; |
| 5304 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5305 List<UnlinkedExecutable> functions = executable.localFunctions; |
| 5306 expect(functions, hasLength(2)); |
| 5307 // f - f1 |
| 5308 { |
| 5309 UnlinkedExecutable f1 = functions.singleWhere((v) => v.name == 'f1'); |
| 5310 List<UnlinkedVariable> variables = f1.localVariables; |
| 5311 expect(variables, hasLength(1)); |
| 5312 // f1 - v1 |
| 5313 UnlinkedVariable v1 = variables.singleWhere((v) => v.name == 'v1'); |
| 5314 _assertVariableVisible(code, v1, '{ // 1', '} // 2'); |
| 5315 checkTypeRef(v1.type, 'dart:core', 'dart:core', 'int'); |
| 5316 } |
| 5317 // f - f2 |
| 5318 { |
| 5319 UnlinkedExecutable f2 = functions.singleWhere((v) => v.name == 'f2'); |
| 5320 List<UnlinkedVariable> variables2 = f2.localVariables; |
| 5321 List<UnlinkedExecutable> functions2 = f2.localFunctions; |
| 5322 expect(variables2, hasLength(1)); |
| 5323 expect(functions2, hasLength(1)); |
| 5324 // f - f2 - v1 |
| 5325 UnlinkedVariable v1 = variables2.singleWhere((v) => v.name == 'v1'); |
| 5326 _assertVariableVisible(code, v1, '{ // 3', '} // 6'); |
| 5327 checkTypeRef(v1.type, 'dart:core', 'dart:core', 'int'); |
| 5328 // f - f2 - f3 |
| 5329 UnlinkedExecutable f3 = functions2.singleWhere((v) => v.name == 'f3'); |
| 5330 _assertExecutableVisible(code, f3, '{ // 3', '} // 6'); |
| 5331 List<UnlinkedVariable> variables3 = f3.localVariables; |
| 5332 List<UnlinkedExecutable> functions3 = f3.localFunctions; |
| 5333 expect(variables3, hasLength(1)); |
| 5334 expect(functions3, hasLength(0)); |
| 5335 // f - f3 - v2 |
| 5336 UnlinkedVariable v2 = variables3.singleWhere((v) => v.name == 'v2'); |
| 5337 _assertVariableVisible(code, v2, '{ // 4', '} // 5'); |
| 5338 checkTypeRef(v2.type, 'dart:core', 'dart:core', 'int'); |
| 5339 } |
| 5340 } |
| 5341 |
| 5342 test_executable_localVariables_inMethod() { |
| 5343 String code = r''' |
| 5344 class C { |
| 5345 m() { // 1 |
| 5346 int v; |
| 5347 f() {} |
| 5348 } // 2 |
| 5349 } |
| 5350 '''; |
| 5351 UnlinkedExecutable executable = |
| 5352 findExecutable('m', executables: serializeClassText(code).executables); |
| 5353 { |
| 5354 List<UnlinkedExecutable> functions = executable.localFunctions; |
| 5355 expect(functions, hasLength(1)); |
| 5356 UnlinkedExecutable f = functions.singleWhere((v) => v.name == 'f'); |
| 5357 _assertExecutableVisible(code, f, '{ // 1', '} // 2'); |
| 5358 } |
| 5359 { |
| 5360 List<UnlinkedVariable> variables = executable.localVariables; |
| 5361 expect(variables, hasLength(1)); |
| 5362 UnlinkedVariable v = variables.singleWhere((v) => v.name == 'v'); |
| 5363 _assertVariableVisible(code, v, '{ // 1', '} // 2'); |
| 5364 checkTypeRef(v.type, 'dart:core', 'dart:core', 'int'); |
| 5365 } |
| 5366 } |
| 5367 |
| 5368 test_executable_localVariables_inTopLevelFunction() { |
| 5369 String code = r''' |
| 5370 f() { // 1 |
| 5371 int v1 = 1; |
| 5372 { // 2 |
| 5373 int v2 = 2; |
| 5374 } // 3 |
| 5375 var v3 = 3; |
| 5376 } // 4 |
| 5377 '''; |
| 5378 UnlinkedExecutable executable = serializeExecutableText(code); |
| 5379 List<UnlinkedVariable> variables = executable.localVariables; |
| 5380 expect(variables, hasLength(3)); |
| 5381 { |
| 5382 UnlinkedVariable v1 = variables.singleWhere((v) => v.name == 'v1'); |
| 5383 _assertVariableVisible(code, v1, '{ // 1', '} // 4'); |
| 5384 checkTypeRef(v1.type, 'dart:core', 'dart:core', 'int'); |
| 5385 } |
| 5386 { |
| 5387 UnlinkedVariable v2 = variables.singleWhere((v) => v.name == 'v2'); |
| 5388 _assertVariableVisible(code, v2, '{ // 2', '} // 3'); |
| 5389 checkTypeRef(v2.type, 'dart:core', 'dart:core', 'int'); |
| 5390 } |
| 5391 { |
| 5392 UnlinkedVariable v3 = variables.singleWhere((v) => v.name == 'v3'); |
| 5393 _assertVariableVisible(code, v3, '{ // 1', '} // 4'); |
| 5394 expect(v3.type, isNull); |
| 5395 } |
| 5396 } |
| 5397 |
| 5398 test_executable_localVariables_inTopLevelGetter() { |
| 5399 String code = r''' |
| 5400 get g { // 1 |
| 5401 int v; |
| 5402 f() {} |
| 5403 } // 2 |
| 5404 '''; |
| 5405 UnlinkedExecutable executable = |
| 5406 serializeExecutableText(code, executableName: 'g'); |
| 5407 { |
| 5408 List<UnlinkedExecutable> functions = executable.localFunctions; |
| 5409 expect(functions, hasLength(1)); |
| 5410 UnlinkedExecutable f = functions.singleWhere((v) => v.name == 'f'); |
| 5411 _assertExecutableVisible(code, f, '{ // 1', '} // 2'); |
| 5412 } |
| 5413 { |
| 5414 List<UnlinkedVariable> variables = executable.localVariables; |
| 5415 expect(variables, hasLength(1)); |
| 5416 UnlinkedVariable v = variables.singleWhere((v) => v.name == 'v'); |
| 5417 _assertVariableVisible(code, v, '{ // 1', '} // 2'); |
| 5418 checkTypeRef(v.type, 'dart:core', 'dart:core', 'int'); |
| 5419 } |
| 5420 } |
| 5421 |
| 5422 test_executable_member_function() { |
| 5423 UnlinkedExecutable executable = findExecutable('f', |
| 5424 executables: serializeClassText('class C { f() {} }').executables); |
| 5425 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 5426 expect(executable.returnType, isNull); |
| 5427 expect(executable.isAsynchronous, isFalse); |
| 5428 expect(executable.isExternal, isFalse); |
| 5429 expect(executable.isGenerator, isFalse); |
| 5430 expect(executable.visibleOffset, 0); |
| 5431 expect(executable.visibleLength, 0); |
| 5432 _assertCodeRange(executable.codeRange, 10, 6); |
| 5433 } |
| 5434 |
| 5435 test_executable_member_function_async() { |
| 5436 UnlinkedExecutable executable = |
| 5437 findExecutable('f', executables: serializeClassText(r''' |
| 5438 import 'dart:async'; |
| 5439 class C { |
| 5440 Future f() async {} |
| 5441 } |
| 5442 ''').executables); |
| 5443 expect(executable.isAsynchronous, isTrue); |
| 5444 expect(executable.isGenerator, isFalse); |
| 5445 } |
| 5446 |
| 5447 test_executable_member_function_asyncStar() { |
| 5448 UnlinkedExecutable executable = |
| 5449 findExecutable('f', executables: serializeClassText(r''' |
| 5450 import 'dart:async'; |
| 5451 class C { |
| 5452 Stream f() async* {} |
| 5453 } |
| 5454 ''').executables); |
| 5455 expect(executable.isAsynchronous, isTrue); |
| 5456 expect(executable.isGenerator, isTrue); |
| 5457 } |
| 5458 |
| 5459 test_executable_member_function_explicit_return() { |
| 5460 UnlinkedExecutable executable = findExecutable('f', |
| 5461 executables: |
| 5462 serializeClassText('class C { dynamic f() => null; }').executables); |
| 5463 expect(executable.returnType, isNotNull); |
| 5464 } |
| 5465 |
| 5466 test_executable_member_function_external() { |
| 5467 UnlinkedExecutable executable = findExecutable('f', |
| 5468 executables: |
| 5469 serializeClassText('class C { external f(); }').executables); |
| 5470 expect(executable.isExternal, isTrue); |
| 5471 } |
| 5472 |
| 5473 test_executable_member_getter() { |
| 5474 UnlinkedClass cls = serializeClassText('class C { int get f => 1; }'); |
| 5475 UnlinkedExecutable executable = |
| 5476 findExecutable('f', executables: cls.executables, failIfAbsent: true); |
| 5477 expect(executable.kind, UnlinkedExecutableKind.getter); |
| 5478 expect(executable.returnType, isNotNull); |
| 5479 expect(executable.isAsynchronous, isFalse); |
| 5480 expect(executable.isExternal, isFalse); |
| 5481 expect(executable.isGenerator, isFalse); |
| 5482 expect(executable.isStatic, isFalse); |
| 5483 _assertCodeRange(executable.codeRange, 10, 15); |
| 5484 expect(findVariable('f', variables: cls.fields), isNull); |
| 5485 expect(findExecutable('f=', executables: cls.executables), isNull); |
| 5486 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 5487 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 5488 expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty); |
| 5489 } |
| 5490 |
| 5491 test_executable_member_getter_external() { |
| 5492 UnlinkedClass cls = serializeClassText('class C { external int get f; }'); |
| 5493 UnlinkedExecutable executable = |
| 5494 findExecutable('f', executables: cls.executables, failIfAbsent: true); |
| 5495 expect(executable.isExternal, isTrue); |
| 5496 } |
| 5497 |
| 5498 test_executable_member_getter_static() { |
| 5499 UnlinkedClass cls = |
| 5500 serializeClassText('class C { static int get f => 1; }'); |
| 5501 UnlinkedExecutable executable = |
| 5502 findExecutable('f', executables: cls.executables, failIfAbsent: true); |
| 5503 expect(executable.isStatic, isTrue); |
| 5504 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 5505 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 5506 expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1)); |
| 5507 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'f'); |
| 5508 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind, |
| 5509 ReferenceKind.propertyAccessor); |
| 5510 expect( |
| 5511 unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters, |
| 5512 0); |
| 5513 expect( |
| 5514 unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty); |
| 5515 } |
| 5516 |
| 5517 test_executable_member_setter() { |
| 5518 UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }'); |
| 5519 UnlinkedExecutable executable = |
| 5520 findExecutable('f=', executables: cls.executables, failIfAbsent: true); |
| 5521 expect(executable.kind, UnlinkedExecutableKind.setter); |
| 5522 expect(executable.returnType, isNotNull); |
| 5523 expect(executable.isAsynchronous, isFalse); |
| 5524 expect(executable.isExternal, isFalse); |
| 5525 expect(executable.isGenerator, isFalse); |
| 5526 _assertCodeRange(executable.codeRange, 10, 20); |
| 5527 expect(findVariable('f', variables: cls.fields), isNull); |
| 5528 expect(findExecutable('f', executables: cls.executables), isNull); |
| 5529 } |
| 5530 |
| 5531 test_executable_member_setter_external() { |
| 5532 UnlinkedClass cls = |
| 5533 serializeClassText('class C { external void set f(value); }'); |
| 5534 UnlinkedExecutable executable = |
| 5535 findExecutable('f=', executables: cls.executables, failIfAbsent: true); |
| 5536 expect(executable.isExternal, isTrue); |
| 5537 } |
| 5538 |
| 5539 test_executable_member_setter_implicit_return() { |
| 5540 UnlinkedClass cls = serializeClassText('class C { set f(value) {} }'); |
| 5541 UnlinkedExecutable executable = |
| 5542 findExecutable('f=', executables: cls.executables, failIfAbsent: true); |
| 5543 expect(executable.returnType, isNull); |
| 5544 } |
| 5545 |
| 5546 test_executable_name() { |
| 5547 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 5548 expect(executable.name, 'f'); |
| 5549 } |
| 5550 |
| 5551 test_executable_no_flags() { |
| 5552 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 5553 expect(executable.isAbstract, isFalse); |
| 5554 expect(executable.isConst, isFalse); |
| 5555 expect(executable.isFactory, isFalse); |
| 5556 expect(executable.isStatic, isFalse); |
| 5557 } |
| 5558 |
| 5559 test_executable_non_static() { |
| 5560 UnlinkedExecutable executable = |
| 5561 serializeClassText('class C { f() {} }').executables[0]; |
| 5562 expect(executable.isStatic, isFalse); |
| 5563 } |
| 5564 |
| 5565 test_executable_non_static_top_level() { |
| 5566 // Top level executables are considered non-static. |
| 5567 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 5568 expect(executable.isStatic, isFalse); |
| 5569 } |
| 5570 |
| 5571 test_executable_operator() { |
| 5572 UnlinkedExecutable executable = |
| 5573 serializeClassText('class C { C operator+(C c) => null; }').executables[ |
| 5574 0]; |
| 5575 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 5576 expect(executable.name, '+'); |
| 5577 expect(executable.returnType, isNotNull); |
| 5578 expect(executable.isAbstract, false); |
| 5579 expect(executable.isAsynchronous, isFalse); |
| 5580 expect(executable.isConst, false); |
| 5581 expect(executable.isFactory, false); |
| 5582 expect(executable.isGenerator, isFalse); |
| 5583 expect(executable.isStatic, false); |
| 5584 expect(executable.parameters, hasLength(1)); |
| 5585 checkTypeRef(executable.returnType, null, null, 'C'); |
| 5586 expect(executable.typeParameters, isEmpty); |
| 5587 expect(executable.isExternal, false); |
| 5588 } |
| 5589 |
| 5590 test_executable_operator_abstract() { |
| 5591 UnlinkedExecutable executable = |
| 5592 serializeClassText('class C { C operator+(C c); }', allowErrors: true) |
| 5593 .executables[0]; |
| 5594 expect(executable.isAbstract, true); |
| 5595 expect(executable.isAsynchronous, isFalse); |
| 5596 expect(executable.isExternal, false); |
| 5597 expect(executable.isGenerator, isFalse); |
| 5598 } |
| 5599 |
| 5600 test_executable_operator_equal() { |
| 5601 UnlinkedExecutable executable = serializeClassText( |
| 5602 'class C { bool operator==(Object other) => false; }') |
| 5603 .executables[0]; |
| 5604 expect(executable.name, '=='); |
| 5605 } |
| 5606 |
| 5607 test_executable_operator_external() { |
| 5608 UnlinkedExecutable executable = |
| 5609 serializeClassText('class C { external C operator+(C c); }') |
| 5610 .executables[0]; |
| 5611 expect(executable.isAbstract, false); |
| 5612 expect(executable.isAsynchronous, isFalse); |
| 5613 expect(executable.isExternal, true); |
| 5614 expect(executable.isGenerator, isFalse); |
| 5615 } |
| 5616 |
| 5617 test_executable_operator_greater_equal() { |
| 5618 UnlinkedExecutable executable = |
| 5619 serializeClassText('class C { bool operator>=(C other) => false; }') |
| 5620 .executables[0]; |
| 5621 expect(executable.name, '>='); |
| 5622 } |
| 5623 |
| 5624 test_executable_operator_index() { |
| 5625 UnlinkedExecutable executable = |
| 5626 serializeClassText('class C { bool operator[](int i) => null; }') |
| 5627 .executables[0]; |
| 5628 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 5629 expect(executable.name, '[]'); |
| 5630 expect(executable.returnType, isNotNull); |
| 5631 expect(executable.isAbstract, false); |
| 5632 expect(executable.isConst, false); |
| 5633 expect(executable.isFactory, false); |
| 5634 expect(executable.isStatic, false); |
| 5635 expect(executable.parameters, hasLength(1)); |
| 5636 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool'); |
| 5637 expect(executable.typeParameters, isEmpty); |
| 5638 } |
| 5639 |
| 5640 test_executable_operator_index_set() { |
| 5641 UnlinkedExecutable executable = serializeClassText( |
| 5642 'class C { void operator[]=(int i, bool v) => null; }') |
| 5643 .executables[0]; |
| 5644 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod); |
| 5645 expect(executable.name, '[]='); |
| 5646 expect(executable.returnType, isNotNull); |
| 5647 expect(executable.isAbstract, false); |
| 5648 expect(executable.isConst, false); |
| 5649 expect(executable.isFactory, false); |
| 5650 expect(executable.isStatic, false); |
| 5651 expect(executable.parameters, hasLength(2)); |
| 5652 checkVoidTypeRef(executable.returnType); |
| 5653 expect(executable.typeParameters, isEmpty); |
| 5654 } |
| 5655 |
| 5656 test_executable_operator_less_equal() { |
| 5657 UnlinkedExecutable executable = |
| 5658 serializeClassText('class C { bool operator<=(C other) => false; }') |
| 5659 .executables[0]; |
| 5660 expect(executable.name, '<='); |
| 5661 } |
| 5662 |
| 5663 test_executable_param_codeRange() { |
| 5664 UnlinkedExecutable executable = serializeExecutableText('f(int x) {}'); |
| 5665 UnlinkedParam parameter = executable.parameters[0]; |
| 5666 _assertCodeRange(parameter.codeRange, 2, 5); |
| 5667 } |
| 5668 |
| 5669 test_executable_param_function_typed() { |
| 5670 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 5671 expect(executable.parameters[0].isFunctionTyped, isTrue); |
| 5672 expect(executable.parameters[0].type, isNull); |
| 5673 } |
| 5674 |
| 5675 test_executable_param_function_typed_explicit_return_type() { |
| 5676 UnlinkedExecutable executable = |
| 5677 serializeExecutableText('f(dynamic g()) {}'); |
| 5678 expect(executable.parameters[0].type, isNotNull); |
| 5679 } |
| 5680 |
| 5681 test_executable_param_function_typed_param() { |
| 5682 UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}'); |
| 5683 expect(executable.parameters[0].parameters, hasLength(1)); |
| 5684 } |
| 5685 |
| 5686 test_executable_param_function_typed_param_none() { |
| 5687 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 5688 expect(executable.parameters[0].parameters, isEmpty); |
| 5689 } |
| 5690 |
| 5691 test_executable_param_function_typed_param_order() { |
| 5692 UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}'); |
| 5693 expect(executable.parameters[0].parameters, hasLength(2)); |
| 5694 expect(executable.parameters[0].parameters[0].name, 'x'); |
| 5695 expect(executable.parameters[0].parameters[1].name, 'y'); |
| 5696 } |
| 5697 |
| 5698 test_executable_param_function_typed_return_type() { |
| 5699 UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}'); |
| 5700 checkTypeRef( |
| 5701 executable.parameters[0].type, 'dart:core', 'dart:core', 'int'); |
| 5702 } |
| 5703 |
| 5704 test_executable_param_function_typed_return_type_implicit() { |
| 5705 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}'); |
| 5706 expect(executable.parameters[0].isFunctionTyped, isTrue); |
| 5707 expect(executable.parameters[0].type, isNull); |
| 5708 } |
| 5709 |
| 5710 test_executable_param_function_typed_return_type_void() { |
| 5711 UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}'); |
| 5712 checkVoidTypeRef(executable.parameters[0].type); |
| 5713 } |
| 5714 |
| 5715 test_executable_param_function_typed_withDefault() { |
| 5716 UnlinkedExecutable executable = serializeExecutableText(r''' |
| 5717 f([int p(int a2, String b2) = foo]) {} |
| 5718 int foo(int a, String b) => 0; |
| 5719 '''); |
| 5720 UnlinkedParam param = executable.parameters[0]; |
| 5721 expect(param.kind, UnlinkedParamKind.positional); |
| 5722 expect(param.initializer, isNotNull); |
| 5723 expect(param.defaultValueCode, 'foo'); |
| 5724 _assertUnlinkedConst(param.initializer.bodyExpr, operators: [ |
| 5725 UnlinkedConstOperation.pushReference |
| 5726 ], referenceValidators: [ |
| 5727 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 5728 expectedKind: ReferenceKind.topLevelFunction) |
| 5729 ]); |
| 5730 } |
| 5731 |
| 5732 test_executable_param_kind_named() { |
| 5733 UnlinkedExecutable executable = serializeExecutableText('f({x}) {}'); |
| 5734 UnlinkedParam param = executable.parameters[0]; |
| 5735 expect(param.kind, UnlinkedParamKind.named); |
| 5736 expect(param.initializer, isNull); |
| 5737 expect(param.defaultValueCode, isEmpty); |
| 5738 } |
| 5739 |
| 5740 test_executable_param_kind_named_withDefault() { |
| 5741 UnlinkedExecutable executable = serializeExecutableText('f({x: 42}) {}'); |
| 5742 UnlinkedParam param = executable.parameters[0]; |
| 5743 expect(param.kind, UnlinkedParamKind.named); |
| 5744 expect(param.initializer, isNotNull); |
| 5745 expect(param.defaultValueCode, '42'); |
| 5746 _assertCodeRange(param.codeRange, 3, 5); |
| 5747 _assertUnlinkedConst(param.initializer.bodyExpr, |
| 5748 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 5749 } |
| 5750 |
| 5751 test_executable_param_kind_positional() { |
| 5752 UnlinkedExecutable executable = serializeExecutableText('f([x]) {}'); |
| 5753 UnlinkedParam param = executable.parameters[0]; |
| 5754 expect(param.kind, UnlinkedParamKind.positional); |
| 5755 expect(param.initializer, isNull); |
| 5756 expect(param.defaultValueCode, isEmpty); |
| 5757 } |
| 5758 |
| 5759 test_executable_param_kind_positional_withDefault() { |
| 5760 UnlinkedExecutable executable = serializeExecutableText('f([x = 42]) {}'); |
| 5761 UnlinkedParam param = executable.parameters[0]; |
| 5762 expect(param.kind, UnlinkedParamKind.positional); |
| 5763 expect(param.initializer, isNotNull); |
| 5764 expect(param.defaultValueCode, '42'); |
| 5765 _assertCodeRange(param.codeRange, 3, 6); |
| 5766 _assertUnlinkedConst(param.initializer.bodyExpr, |
| 5767 operators: [UnlinkedConstOperation.pushInt], ints: [42]); |
| 5768 } |
| 5769 |
| 5770 test_executable_param_kind_required() { |
| 5771 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 5772 UnlinkedParam param = executable.parameters[0]; |
| 5773 expect(param.kind, UnlinkedParamKind.required); |
| 5774 expect(param.initializer, isNull); |
| 5775 expect(param.defaultValueCode, isEmpty); |
| 5776 } |
| 5777 |
| 5778 test_executable_param_name() { |
| 5779 String text = 'f(x) {}'; |
| 5780 UnlinkedExecutable executable = serializeExecutableText(text); |
| 5781 expect(executable.parameters, hasLength(1)); |
| 5782 expect(executable.parameters[0].name, 'x'); |
| 5783 expect(executable.parameters[0].nameOffset, text.indexOf('x')); |
| 5784 } |
| 5785 |
| 5786 test_executable_param_no_flags() { |
| 5787 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 5788 expect(executable.parameters[0].isFunctionTyped, isFalse); |
| 5789 expect(executable.parameters[0].isInitializingFormal, isFalse); |
| 5790 } |
| 5791 |
| 5792 test_executable_param_non_function_typed() { |
| 5793 UnlinkedExecutable executable = serializeExecutableText('f(g) {}'); |
| 5794 expect(executable.parameters[0].isFunctionTyped, isFalse); |
| 5795 } |
| 5796 |
| 5797 test_executable_param_none() { |
| 5798 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 5799 expect(executable.parameters, isEmpty); |
| 5800 } |
| 5801 |
| 5802 test_executable_param_of_constructor_no_covariance() { |
| 5803 UnlinkedExecutable executable = |
| 5804 serializeClassText('class C { C(x); }').executables[0]; |
| 5805 expect(executable.parameters[0].inheritsCovariantSlot, 0); |
| 5806 } |
| 5807 |
| 5808 test_executable_param_of_local_function_no_covariance() { |
| 5809 UnlinkedExecutable executable = |
| 5810 serializeClassText('class C { m() { f(x) {} } }') |
| 5811 .executables[0] |
| 5812 .localFunctions[0]; |
| 5813 expect(executable.parameters[0].inheritsCovariantSlot, 0); |
| 5814 } |
| 5815 |
| 5816 test_executable_param_of_method_covariance() { |
| 5817 UnlinkedExecutable executable = |
| 5818 serializeClassText('class C { m(x) {} }').executables[0]; |
| 5819 expect(executable.parameters[0].inheritsCovariantSlot, isNot(0)); |
| 5820 } |
| 5821 |
| 5822 test_executable_param_of_param_no_covariance() { |
| 5823 UnlinkedExecutable executable = |
| 5824 serializeClassText('class C { m(f(x)) {} }').executables[0]; |
| 5825 expect(executable.parameters[0].parameters[0].inheritsCovariantSlot, 0); |
| 5826 } |
| 5827 |
| 5828 test_executable_param_of_setter_covariance() { |
| 5829 UnlinkedExecutable executable = |
| 5830 serializeClassText('class C { void set s(x) {} }').executables[0]; |
| 5831 expect(executable.parameters[0].inheritsCovariantSlot, isNot(0)); |
| 5832 } |
| 5833 |
| 5834 test_executable_param_of_static_method_no_covariance() { |
| 5835 UnlinkedExecutable executable = |
| 5836 serializeClassText('class C { static m(x) {} }').executables[0]; |
| 5837 expect(executable.parameters[0].inheritsCovariantSlot, 0); |
| 5838 } |
| 5839 |
| 5840 test_executable_param_of_top_level_function_no_covariance() { |
| 5841 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 5842 expect(executable.parameters[0].inheritsCovariantSlot, 0); |
| 5843 } |
| 5844 |
| 5845 test_executable_param_order() { |
| 5846 UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}'); |
| 5847 expect(executable.parameters, hasLength(2)); |
| 5848 expect(executable.parameters[0].name, 'x'); |
| 5849 expect(executable.parameters[1].name, 'y'); |
| 5850 } |
| 5851 |
| 5852 test_executable_param_type_explicit() { |
| 5853 UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}'); |
| 5854 checkDynamicTypeRef(executable.parameters[0].type); |
| 5855 } |
| 5856 |
| 5857 test_executable_param_type_implicit() { |
| 5858 UnlinkedExecutable executable = serializeExecutableText('f(x) {}'); |
| 5859 expect(executable.parameters[0].type, isNull); |
| 5860 } |
| 5861 |
| 5862 test_executable_param_type_typedef() { |
| 5863 UnlinkedExecutable executable = serializeExecutableText(r''' |
| 5864 typedef MyFunction(int p); |
| 5865 f(MyFunction myFunction) {} |
| 5866 '''); |
| 5867 expect(executable.parameters[0].isFunctionTyped, isFalse); |
| 5868 checkTypeRef(executable.parameters[0].type, null, null, 'MyFunction', |
| 5869 expectedKind: ReferenceKind.typedef); |
| 5870 } |
| 5871 |
| 5872 test_executable_return_type() { |
| 5873 UnlinkedExecutable executable = serializeExecutableText('int f() => 1;'); |
| 5874 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int'); |
| 5875 } |
| 5876 |
| 5877 test_executable_return_type_implicit() { |
| 5878 UnlinkedExecutable executable = serializeExecutableText('f() {}'); |
| 5879 expect(executable.returnType, isNull); |
| 5880 } |
| 5881 |
| 5882 test_executable_return_type_void() { |
| 5883 UnlinkedExecutable executable = serializeExecutableText('void f() {}'); |
| 5884 checkVoidTypeRef(executable.returnType); |
| 5885 } |
| 5886 |
| 5887 test_executable_setter() { |
| 5888 String text = 'void set f(value) {}'; |
| 5889 UnlinkedExecutable executable = |
| 5890 serializeExecutableText(text, executableName: 'f='); |
| 5891 expect(executable.kind, UnlinkedExecutableKind.setter); |
| 5892 expect(executable.returnType, isNotNull); |
| 5893 expect(executable.isAsynchronous, isFalse); |
| 5894 expect(executable.isExternal, isFalse); |
| 5895 expect(executable.isGenerator, isFalse); |
| 5896 expect(executable.nameOffset, text.indexOf('f')); |
| 5897 expect(findVariable('f'), isNull); |
| 5898 expect(findExecutable('f'), isNull); |
| 5899 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 5900 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 5901 ReferenceKind.topLevelPropertyAccessor); |
| 5902 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f='); |
| 5903 } |
| 5904 |
| 5905 test_executable_setter_external() { |
| 5906 UnlinkedExecutable executable = serializeExecutableText( |
| 5907 'external void set f(value);', |
| 5908 executableName: 'f='); |
| 5909 expect(executable.isExternal, isTrue); |
| 5910 } |
| 5911 |
| 5912 test_executable_setter_implicit_return() { |
| 5913 UnlinkedExecutable executable = |
| 5914 serializeExecutableText('set f(value) {}', executableName: 'f='); |
| 5915 expect(executable.returnType, isNull); |
| 5916 } |
| 5917 |
| 5918 test_executable_setter_private() { |
| 5919 serializeExecutableText('void set _f(value) {}', executableName: '_f='); |
| 5920 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 5921 } |
| 5922 |
| 5923 test_executable_setter_type() { |
| 5924 UnlinkedExecutable executable = serializeExecutableText( |
| 5925 'void set f(int value) {}', |
| 5926 executableName: 'f='); |
| 5927 checkVoidTypeRef(executable.returnType); |
| 5928 expect(executable.parameters, hasLength(1)); |
| 5929 expect(executable.parameters[0].name, 'value'); |
| 5930 checkTypeRef( |
| 5931 executable.parameters[0].type, 'dart:core', 'dart:core', 'int'); |
| 5932 } |
| 5933 |
| 5934 test_executable_static() { |
| 5935 UnlinkedExecutable executable = |
| 5936 serializeClassText('class C { static f() {} }').executables[0]; |
| 5937 expect(executable.isStatic, isTrue); |
| 5938 } |
| 5939 |
| 5940 test_executable_type_param_f_bound_function() { |
| 5941 UnlinkedExecutable ex = |
| 5942 serializeExecutableText('void f<T, U extends List<T>>() {}'); |
| 5943 EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0]; |
| 5944 checkParamTypeRef(typeArgument, 2); |
| 5945 } |
| 5946 |
| 5947 test_executable_type_param_f_bound_method() { |
| 5948 UnlinkedExecutable ex = |
| 5949 serializeMethodText('void f<T, U extends List<T>>() {}'); |
| 5950 EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0]; |
| 5951 checkParamTypeRef(typeArgument, 2); |
| 5952 } |
| 5953 |
| 5954 test_executable_type_param_f_bound_self_ref_function() { |
| 5955 UnlinkedExecutable ex = |
| 5956 serializeExecutableText('void f<T, U extends List<U>>() {}'); |
| 5957 EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0]; |
| 5958 checkParamTypeRef(typeArgument, 1); |
| 5959 } |
| 5960 |
| 5961 test_executable_type_param_f_bound_self_ref_method() { |
| 5962 UnlinkedExecutable ex = |
| 5963 serializeMethodText('void f<T, U extends List<U>>() {}'); |
| 5964 EntityRef typeArgument = ex.typeParameters[1].bound.typeArguments[0]; |
| 5965 checkParamTypeRef(typeArgument, 1); |
| 5966 } |
| 5967 |
| 5968 test_executable_type_param_in_parameter_function() { |
| 5969 UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}'); |
| 5970 checkParamTypeRef(ex.parameters[0].type, 1); |
| 5971 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1); |
| 5972 } |
| 5973 |
| 5974 test_executable_type_param_in_parameter_method() { |
| 5975 UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}'); |
| 5976 checkParamTypeRef(ex.parameters[0].type, 1); |
| 5977 } |
| 5978 |
| 5979 test_executable_type_param_in_return_type_function() { |
| 5980 UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;'); |
| 5981 checkParamTypeRef(ex.returnType, 1); |
| 5982 } |
| 5983 |
| 5984 test_executable_type_param_in_return_type_method() { |
| 5985 UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;'); |
| 5986 checkParamTypeRef(ex.returnType, 1); |
| 5987 } |
| 5988 |
| 5989 test_export_class() { |
| 5990 addNamedSource('/a.dart', 'class C {}'); |
| 5991 serializeLibraryText('export "a.dart";'); |
| 5992 expect(linked.exportNames, hasLength(1)); |
| 5993 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C', |
| 5994 ReferenceKind.classOrEnum); |
| 5995 } |
| 5996 |
| 5997 test_export_class_alias() { |
| 5998 addNamedSource( |
| 5999 '/a.dart', 'class C extends _D with _E {} class _D {} class _E {}'); |
| 6000 serializeLibraryText('export "a.dart";'); |
| 6001 expect(linked.exportNames, hasLength(1)); |
| 6002 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C', |
| 6003 ReferenceKind.classOrEnum); |
| 6004 } |
| 6005 |
| 6006 test_export_configurations() { |
| 6007 addNamedSource('/foo.dart', 'class A {}'); |
| 6008 addNamedSource('/foo_io.dart', 'class A {}'); |
| 6009 addNamedSource('/foo_html.dart', 'class A {}'); |
| 6010 String libraryText = r''' |
| 6011 export 'foo.dart' |
| 6012 if (dart.library.io) 'foo_io.dart' |
| 6013 if (dart.flavor == 'html') 'foo_html.dart'; |
| 6014 |
| 6015 class B extends A {} |
| 6016 '''; |
| 6017 serializeLibraryText(libraryText); |
| 6018 UnlinkedExportPublic exp = unlinkedUnits[0].publicNamespace.exports[0]; |
| 6019 expect(exp.configurations, hasLength(2)); |
| 6020 { |
| 6021 UnlinkedConfiguration configuration = exp.configurations[0]; |
| 6022 expect(configuration.name, 'dart.library.io'); |
| 6023 expect(configuration.value, 'true'); |
| 6024 expect(configuration.uri, 'foo_io.dart'); |
| 6025 } |
| 6026 { |
| 6027 UnlinkedConfiguration configuration = exp.configurations[1]; |
| 6028 expect(configuration.name, 'dart.flavor'); |
| 6029 expect(configuration.value, 'html'); |
| 6030 expect(configuration.uri, 'foo_html.dart'); |
| 6031 } |
| 6032 } |
| 6033 |
| 6034 test_export_dependency() { |
| 6035 serializeLibraryText('export "dart:async";'); |
| 6036 expect(unlinkedUnits[0].exports, hasLength(1)); |
| 6037 checkDependency(linked.exportDependencies[0], 'dart:async', 'dart:async'); |
| 6038 } |
| 6039 |
| 6040 test_export_enum() { |
| 6041 addNamedSource('/a.dart', 'enum E { v }'); |
| 6042 serializeLibraryText('export "a.dart";'); |
| 6043 expect(linked.exportNames, hasLength(1)); |
| 6044 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'E', |
| 6045 ReferenceKind.classOrEnum); |
| 6046 } |
| 6047 |
| 6048 test_export_from_part() { |
| 6049 addNamedSource('/a.dart', 'library foo; part "b.dart";'); |
| 6050 addNamedSource('/b.dart', 'part of foo; f() {}'); |
| 6051 serializeLibraryText('export "a.dart";'); |
| 6052 expect(linked.exportNames, hasLength(1)); |
| 6053 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6054 ReferenceKind.topLevelFunction, |
| 6055 expectedTargetUnit: 1); |
| 6056 } |
| 6057 |
| 6058 test_export_function() { |
| 6059 addNamedSource('/a.dart', 'f() {}'); |
| 6060 serializeLibraryText('export "a.dart";'); |
| 6061 expect(linked.exportNames, hasLength(1)); |
| 6062 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6063 ReferenceKind.topLevelFunction); |
| 6064 } |
| 6065 |
| 6066 test_export_getter() { |
| 6067 addNamedSource('/a.dart', 'get f => null'); |
| 6068 serializeLibraryText('export "a.dart";'); |
| 6069 expect(linked.exportNames, hasLength(1)); |
| 6070 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6071 ReferenceKind.topLevelPropertyAccessor); |
| 6072 } |
| 6073 |
| 6074 test_export_hide() { |
| 6075 addNamedSource('/a.dart', 'f() {} g() {}'); |
| 6076 serializeLibraryText('export "a.dart" hide g;'); |
| 6077 expect(linked.exportNames, hasLength(1)); |
| 6078 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6079 ReferenceKind.topLevelFunction); |
| 6080 } |
| 6081 |
| 6082 test_export_hide_order() { |
| 6083 serializeLibraryText('export "dart:async" hide Future, Stream;'); |
| 6084 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1)); |
| 6085 expect( |
| 6086 unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1)); |
| 6087 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows, |
| 6088 isEmpty); |
| 6089 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides, |
| 6090 hasLength(2)); |
| 6091 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0], |
| 6092 'Future'); |
| 6093 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1], |
| 6094 'Stream'); |
| 6095 expect( |
| 6096 unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, 0); |
| 6097 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, 0); |
| 6098 expect(linked.exportNames, isNotEmpty); |
| 6099 } |
| 6100 |
| 6101 test_export_missing() { |
| 6102 // Unresolved exports are included since this is necessary for proper |
| 6103 // dependency tracking. |
| 6104 allowMissingFiles = true; |
| 6105 serializeLibraryText('export "foo.dart";', allowErrors: true); |
| 6106 expect(unlinkedUnits[0].imports, hasLength(1)); |
| 6107 checkDependency( |
| 6108 linked.exportDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 6109 } |
| 6110 |
| 6111 test_export_names_excludes_names_from_library() { |
| 6112 addNamedSource('/a.dart', 'part of my.lib; int y; int _y;'); |
| 6113 serializeLibraryText('library my.lib; part "a.dart"; int x; int _x;'); |
| 6114 expect(linked.exportNames, isEmpty); |
| 6115 } |
| 6116 |
| 6117 test_export_no_combinators() { |
| 6118 serializeLibraryText('export "dart:async";'); |
| 6119 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1)); |
| 6120 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty); |
| 6121 } |
| 6122 |
| 6123 test_export_not_shadowed_by_prefix() { |
| 6124 addNamedSource('/a.dart', 'f() {}'); |
| 6125 serializeLibraryText('export "a.dart"; import "dart:core" as f; f.int _x;'); |
| 6126 expect(linked.exportNames, hasLength(1)); |
| 6127 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6128 ReferenceKind.topLevelFunction); |
| 6129 } |
| 6130 |
| 6131 test_export_offset() { |
| 6132 String libraryText = ' export "dart:async";'; |
| 6133 serializeLibraryText(libraryText); |
| 6134 expect(unlinkedUnits[0].exports[0].uriOffset, |
| 6135 libraryText.indexOf('"dart:async"')); |
| 6136 expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';')); |
| 6137 expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export')); |
| 6138 } |
| 6139 |
| 6140 test_export_private() { |
| 6141 // Private names should not be exported. |
| 6142 addNamedSource('/a.dart', '_f() {}'); |
| 6143 serializeLibraryText('export "a.dart";'); |
| 6144 expect(linked.exportNames, isEmpty); |
| 6145 } |
| 6146 |
| 6147 test_export_setter() { |
| 6148 addNamedSource('/a.dart', 'void set f(value) {}'); |
| 6149 serializeLibraryText('export "a.dart";'); |
| 6150 expect(linked.exportNames, hasLength(1)); |
| 6151 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f=', |
| 6152 ReferenceKind.topLevelPropertyAccessor); |
| 6153 } |
| 6154 |
| 6155 test_export_shadowed() { |
| 6156 // f() is not shown in exportNames because it is already defined at top |
| 6157 // level in the library. |
| 6158 addNamedSource('/a.dart', 'f() {}'); |
| 6159 serializeLibraryText('export "a.dart"; f() {}'); |
| 6160 expect(linked.exportNames, isEmpty); |
| 6161 } |
| 6162 |
| 6163 test_export_shadowed_variable() { |
| 6164 // Neither `v` nor `v=` is shown in exportNames because both are defined at |
| 6165 // top level in the library by the declaration `var v;`. |
| 6166 addNamedSource('/a.dart', 'var v;'); |
| 6167 serializeLibraryText('export "a.dart"; var v;'); |
| 6168 expect(linked.exportNames, isEmpty); |
| 6169 } |
| 6170 |
| 6171 test_export_shadowed_variable_const() { |
| 6172 // `v=` is shown in exportNames because the top level declaration |
| 6173 // `const v = 0;` only shadows `v`, not `v=`. |
| 6174 addNamedSource('/a.dart', 'var v;'); |
| 6175 serializeLibraryText('export "a.dart"; const v = 0;'); |
| 6176 expect(linked.exportNames, hasLength(1)); |
| 6177 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=', |
| 6178 ReferenceKind.topLevelPropertyAccessor); |
| 6179 } |
| 6180 |
| 6181 test_export_shadowed_variable_final() { |
| 6182 // `v=` is shown in exportNames because the top level declaration |
| 6183 // `final v = 0;` only shadows `v`, not `v=`. |
| 6184 addNamedSource('/a.dart', 'var v;'); |
| 6185 serializeLibraryText('export "a.dart"; final v = 0;'); |
| 6186 expect(linked.exportNames, hasLength(1)); |
| 6187 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=', |
| 6188 ReferenceKind.topLevelPropertyAccessor); |
| 6189 } |
| 6190 |
| 6191 test_export_show() { |
| 6192 addNamedSource('/a.dart', 'f() {} g() {}'); |
| 6193 serializeLibraryText('export "a.dart" show f;'); |
| 6194 expect(linked.exportNames, hasLength(1)); |
| 6195 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f', |
| 6196 ReferenceKind.topLevelFunction); |
| 6197 } |
| 6198 |
| 6199 test_export_show_order() { |
| 6200 String libraryText = 'export "dart:async" show Future, Stream;'; |
| 6201 serializeLibraryText(libraryText); |
| 6202 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1)); |
| 6203 expect( |
| 6204 unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1)); |
| 6205 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows, |
| 6206 hasLength(2)); |
| 6207 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides, |
| 6208 isEmpty); |
| 6209 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0], |
| 6210 'Future'); |
| 6211 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1], |
| 6212 'Stream'); |
| 6213 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, |
| 6214 libraryText.indexOf('show')); |
| 6215 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, |
| 6216 libraryText.indexOf(';')); |
| 6217 } |
| 6218 |
| 6219 test_export_typedef() { |
| 6220 addNamedSource('/a.dart', 'typedef F();'); |
| 6221 serializeLibraryText('export "a.dart";'); |
| 6222 expect(linked.exportNames, hasLength(1)); |
| 6223 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'F', |
| 6224 ReferenceKind.typedef); |
| 6225 } |
| 6226 |
| 6227 test_export_uri() { |
| 6228 addNamedSource('/a.dart', 'library my.lib;'); |
| 6229 String uriString = '"a.dart"'; |
| 6230 String libraryText = 'export $uriString;'; |
| 6231 serializeLibraryText(libraryText); |
| 6232 var unlinkedExports = unlinkedUnits[0].publicNamespace.exports; |
| 6233 expect(unlinkedExports, hasLength(1)); |
| 6234 expect(unlinkedExports[0].uri, 'a.dart'); |
| 6235 expect(unlinkedExports[0].configurations, isEmpty); |
| 6236 } |
| 6237 |
| 6238 test_export_variable() { |
| 6239 addNamedSource('/a.dart', 'var v;'); |
| 6240 serializeLibraryText('export "a.dart";'); |
| 6241 expect(linked.exportNames, hasLength(2)); |
| 6242 LinkedExportName getter = |
| 6243 linked.exportNames.firstWhere((e) => e.name == 'v'); |
| 6244 expect(getter, isNotNull); |
| 6245 checkExportName(getter, absUri('/a.dart'), 'a.dart', 'v', |
| 6246 ReferenceKind.topLevelPropertyAccessor); |
| 6247 LinkedExportName setter = |
| 6248 linked.exportNames.firstWhere((e) => e.name == 'v='); |
| 6249 expect(setter, isNotNull); |
| 6250 checkExportName(setter, absUri('/a.dart'), 'a.dart', 'v=', |
| 6251 ReferenceKind.topLevelPropertyAccessor); |
| 6252 } |
| 6253 |
| 6254 test_expr_assignOperator_assign() { |
| 6255 _assertAssignmentOperator( |
| 6256 '(a = 1 + 2) + 3', UnlinkedExprAssignOperator.assign); |
| 6257 } |
| 6258 |
| 6259 test_expr_assignOperator_bitAnd() { |
| 6260 _assertAssignmentOperator( |
| 6261 '(a &= 1 + 2) + 3', UnlinkedExprAssignOperator.bitAnd); |
| 6262 } |
| 6263 |
| 6264 test_expr_assignOperator_bitOr() { |
| 6265 _assertAssignmentOperator( |
| 6266 '(a |= 1 + 2) + 3', UnlinkedExprAssignOperator.bitOr); |
| 6267 } |
| 6268 |
| 6269 test_expr_assignOperator_bitXor() { |
| 6270 _assertAssignmentOperator( |
| 6271 '(a ^= 1 + 2) + 3', UnlinkedExprAssignOperator.bitXor); |
| 6272 } |
| 6273 |
| 6274 test_expr_assignOperator_divide() { |
| 6275 _assertAssignmentOperator( |
| 6276 '(a /= 1 + 2) + 3', UnlinkedExprAssignOperator.divide); |
| 6277 } |
| 6278 |
| 6279 test_expr_assignOperator_floorDivide() { |
| 6280 _assertAssignmentOperator( |
| 6281 '(a ~/= 1 + 2) + 3', UnlinkedExprAssignOperator.floorDivide); |
| 6282 } |
| 6283 |
| 6284 test_expr_assignOperator_ifNull() { |
| 6285 _assertAssignmentOperator( |
| 6286 '(a ??= 1 + 2) + 3', UnlinkedExprAssignOperator.ifNull); |
| 6287 } |
| 6288 |
| 6289 test_expr_assignOperator_minus() { |
| 6290 _assertAssignmentOperator( |
| 6291 '(a -= 1 + 2) + 3', UnlinkedExprAssignOperator.minus); |
| 6292 } |
| 6293 |
| 6294 test_expr_assignOperator_modulo() { |
| 6295 _assertAssignmentOperator( |
| 6296 '(a %= 1 + 2) + 3', UnlinkedExprAssignOperator.modulo); |
| 6297 } |
| 6298 |
| 6299 test_expr_assignOperator_multiply() { |
| 6300 _assertAssignmentOperator( |
| 6301 '(a *= 1 + 2) + 3', UnlinkedExprAssignOperator.multiply); |
| 6302 } |
| 6303 |
| 6304 test_expr_assignOperator_plus() { |
| 6305 _assertAssignmentOperator( |
| 6306 '(a += 1 + 2) + 3', UnlinkedExprAssignOperator.plus); |
| 6307 } |
| 6308 |
| 6309 test_expr_assignOperator_shiftLeft() { |
| 6310 _assertAssignmentOperator( |
| 6311 '(a <<= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftLeft); |
| 6312 } |
| 6313 |
| 6314 test_expr_assignOperator_shiftRight() { |
| 6315 _assertAssignmentOperator( |
| 6316 '(a >>= 1 + 2) + 3', UnlinkedExprAssignOperator.shiftRight); |
| 6317 } |
| 6318 |
| 6319 test_expr_assignToIndex_ofFieldSequence() { |
| 6320 if (skipNonConstInitializers) { |
| 6321 return; |
| 6322 } |
| 6323 UnlinkedVariable variable = serializeVariableText(''' |
| 6324 class A { |
| 6325 B b; |
| 6326 } |
| 6327 class B { |
| 6328 C c; |
| 6329 } |
| 6330 class C { |
| 6331 List<int> f = <int>[0, 1, 2]; |
| 6332 } |
| 6333 A a = new A(); |
| 6334 final v = (a.b.c.f[1] = 5); |
| 6335 '''); |
| 6336 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6337 isValidConst: false, |
| 6338 operators: [ |
| 6339 UnlinkedConstOperation.pushInt, |
| 6340 UnlinkedConstOperation.pushReference, |
| 6341 UnlinkedConstOperation.pushInt, |
| 6342 UnlinkedConstOperation.assignToIndex, |
| 6343 ], |
| 6344 assignmentOperators: [ |
| 6345 (UnlinkedExprAssignOperator.assign) |
| 6346 ], |
| 6347 ints: [ |
| 6348 5, |
| 6349 1 |
| 6350 ], |
| 6351 strings: [], |
| 6352 referenceValidators: [ |
| 6353 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 6354 expectedKind: ReferenceKind.unresolved, |
| 6355 prefixExpectations: [ |
| 6356 new _PrefixExpectation(ReferenceKind.unresolved, 'c'), |
| 6357 new _PrefixExpectation(ReferenceKind.unresolved, 'b'), |
| 6358 new _PrefixExpectation( |
| 6359 ReferenceKind.topLevelPropertyAccessor, 'a') |
| 6360 ]) |
| 6361 ]); |
| 6362 } |
| 6363 |
| 6364 test_expr_assignToIndex_ofIndexExpression() { |
| 6365 if (skipNonConstInitializers) { |
| 6366 return; |
| 6367 } |
| 6368 UnlinkedVariable variable = serializeVariableText(''' |
| 6369 class A { |
| 6370 List<B> b; |
| 6371 } |
| 6372 class B { |
| 6373 List<C> c; |
| 6374 } |
| 6375 class C { |
| 6376 List<int> f = <int>[0, 1, 2]; |
| 6377 } |
| 6378 A a = new A(); |
| 6379 final v = (a.b[1].c[2].f[3] = 5); |
| 6380 '''); |
| 6381 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6382 isValidConst: false, |
| 6383 operators: [ |
| 6384 // 5 |
| 6385 UnlinkedConstOperation.pushInt, |
| 6386 // a.b[1] |
| 6387 UnlinkedConstOperation.pushReference, |
| 6388 UnlinkedConstOperation.pushInt, |
| 6389 UnlinkedConstOperation.extractIndex, |
| 6390 // c[2] |
| 6391 UnlinkedConstOperation.extractProperty, |
| 6392 UnlinkedConstOperation.pushInt, |
| 6393 UnlinkedConstOperation.extractIndex, |
| 6394 // f[3] = 5 |
| 6395 UnlinkedConstOperation.extractProperty, |
| 6396 UnlinkedConstOperation.pushInt, |
| 6397 UnlinkedConstOperation.assignToIndex, |
| 6398 ], |
| 6399 assignmentOperators: [ |
| 6400 (UnlinkedExprAssignOperator.assign) |
| 6401 ], |
| 6402 ints: [ |
| 6403 5, |
| 6404 1, |
| 6405 2, |
| 6406 3, |
| 6407 ], |
| 6408 strings: [ |
| 6409 'c', |
| 6410 'f' |
| 6411 ], |
| 6412 referenceValidators: [ |
| 6413 (EntityRef r) => checkTypeRef(r, null, null, 'b', |
| 6414 expectedKind: ReferenceKind.unresolved, |
| 6415 prefixExpectations: [ |
| 6416 new _PrefixExpectation( |
| 6417 ReferenceKind.topLevelPropertyAccessor, 'a') |
| 6418 ]) |
| 6419 ]); |
| 6420 } |
| 6421 |
| 6422 test_expr_assignToIndex_ofTopLevelVariable() { |
| 6423 if (skipNonConstInitializers) { |
| 6424 return; |
| 6425 } |
| 6426 UnlinkedVariable variable = serializeVariableText(''' |
| 6427 List<int> a = <int>[0, 1, 2]; |
| 6428 final v = (a[1] = 5); |
| 6429 '''); |
| 6430 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6431 isValidConst: false, |
| 6432 operators: [ |
| 6433 UnlinkedConstOperation.pushInt, |
| 6434 UnlinkedConstOperation.pushReference, |
| 6435 UnlinkedConstOperation.pushInt, |
| 6436 UnlinkedConstOperation.assignToIndex, |
| 6437 ], |
| 6438 assignmentOperators: [ |
| 6439 (UnlinkedExprAssignOperator.assign) |
| 6440 ], |
| 6441 ints: [ |
| 6442 5, |
| 6443 1, |
| 6444 ], |
| 6445 strings: [], |
| 6446 referenceValidators: [ |
| 6447 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 6448 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 6449 ]); |
| 6450 } |
| 6451 |
| 6452 test_expr_assignToProperty_ofInstanceCreation() { |
| 6453 if (skipNonConstInitializers) { |
| 6454 return; |
| 6455 } |
| 6456 UnlinkedVariable variable = serializeVariableText(''' |
| 6457 class C { |
| 6458 int f; |
| 6459 } |
| 6460 final v = (new C().f = 5); |
| 6461 '''); |
| 6462 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6463 isValidConst: false, |
| 6464 operators: [ |
| 6465 UnlinkedConstOperation.pushInt, |
| 6466 UnlinkedConstOperation.invokeConstructor, |
| 6467 UnlinkedConstOperation.assignToProperty, |
| 6468 ], |
| 6469 assignmentOperators: [ |
| 6470 (UnlinkedExprAssignOperator.assign) |
| 6471 ], |
| 6472 ints: [ |
| 6473 5, |
| 6474 0, |
| 6475 0, |
| 6476 ], |
| 6477 strings: [ |
| 6478 'f' |
| 6479 ], |
| 6480 referenceValidators: [ |
| 6481 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 6482 expectedKind: ReferenceKind.classOrEnum) |
| 6483 ]); |
| 6484 } |
| 6485 |
| 6486 test_expr_assignToRef_classStaticField() { |
| 6487 if (skipNonConstInitializers) { |
| 6488 return; |
| 6489 } |
| 6490 UnlinkedVariable variable = serializeVariableText(''' |
| 6491 class C { |
| 6492 static int f; |
| 6493 } |
| 6494 final v = (C.f = 1); |
| 6495 '''); |
| 6496 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6497 isValidConst: false, |
| 6498 operators: [ |
| 6499 UnlinkedConstOperation.pushInt, |
| 6500 UnlinkedConstOperation.assignToRef, |
| 6501 ], |
| 6502 assignmentOperators: [ |
| 6503 (UnlinkedExprAssignOperator.assign) |
| 6504 ], |
| 6505 ints: [ |
| 6506 1, |
| 6507 ], |
| 6508 strings: [], |
| 6509 referenceValidators: [ |
| 6510 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 6511 expectedKind: ReferenceKind.unresolved, |
| 6512 prefixExpectations: [ |
| 6513 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 6514 ]) |
| 6515 ]); |
| 6516 } |
| 6517 |
| 6518 test_expr_assignToRef_fieldSequence() { |
| 6519 if (skipNonConstInitializers) { |
| 6520 return; |
| 6521 } |
| 6522 UnlinkedVariable variable = serializeVariableText(''' |
| 6523 class A { |
| 6524 B b; |
| 6525 } |
| 6526 class B { |
| 6527 C c; |
| 6528 } |
| 6529 class C { |
| 6530 int f; |
| 6531 } |
| 6532 A a = new A(); |
| 6533 final v = (a.b.c.f = 1); |
| 6534 '''); |
| 6535 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6536 isValidConst: false, |
| 6537 operators: [ |
| 6538 UnlinkedConstOperation.pushInt, |
| 6539 UnlinkedConstOperation.assignToRef, |
| 6540 ], |
| 6541 assignmentOperators: [ |
| 6542 (UnlinkedExprAssignOperator.assign) |
| 6543 ], |
| 6544 ints: [ |
| 6545 1, |
| 6546 ], |
| 6547 strings: [], |
| 6548 referenceValidators: [ |
| 6549 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 6550 expectedKind: ReferenceKind.unresolved, |
| 6551 prefixExpectations: [ |
| 6552 new _PrefixExpectation(ReferenceKind.unresolved, 'c'), |
| 6553 new _PrefixExpectation(ReferenceKind.unresolved, 'b'), |
| 6554 new _PrefixExpectation( |
| 6555 ReferenceKind.topLevelPropertyAccessor, 'a') |
| 6556 ]) |
| 6557 ]); |
| 6558 } |
| 6559 |
| 6560 test_expr_assignToRef_postfixDecrement() { |
| 6561 _assertRefPrefixPostfixIncrementDecrement( |
| 6562 'a-- + 2', UnlinkedExprAssignOperator.postfixDecrement); |
| 6563 } |
| 6564 |
| 6565 test_expr_assignToRef_postfixIncrement() { |
| 6566 _assertRefPrefixPostfixIncrementDecrement( |
| 6567 'a++ + 2', UnlinkedExprAssignOperator.postfixIncrement); |
| 6568 } |
| 6569 |
| 6570 test_expr_assignToRef_prefixDecrement() { |
| 6571 _assertRefPrefixPostfixIncrementDecrement( |
| 6572 '--a + 2', UnlinkedExprAssignOperator.prefixDecrement); |
| 6573 } |
| 6574 |
| 6575 test_expr_assignToRef_prefixIncrement() { |
| 6576 _assertRefPrefixPostfixIncrementDecrement( |
| 6577 '++a + 2', UnlinkedExprAssignOperator.prefixIncrement); |
| 6578 } |
| 6579 |
| 6580 test_expr_assignToRef_topLevelVariable() { |
| 6581 if (skipNonConstInitializers) { |
| 6582 return; |
| 6583 } |
| 6584 UnlinkedVariable variable = serializeVariableText(''' |
| 6585 int a = 0; |
| 6586 final v = (a = 1); |
| 6587 '''); |
| 6588 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6589 isValidConst: false, |
| 6590 operators: [ |
| 6591 UnlinkedConstOperation.pushInt, |
| 6592 UnlinkedConstOperation.assignToRef, |
| 6593 ], |
| 6594 assignmentOperators: [ |
| 6595 (UnlinkedExprAssignOperator.assign) |
| 6596 ], |
| 6597 ints: [ |
| 6598 1, |
| 6599 ], |
| 6600 strings: [], |
| 6601 referenceValidators: [ |
| 6602 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 6603 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 6604 ]); |
| 6605 } |
| 6606 |
| 6607 test_expr_assignToRef_topLevelVariable_imported() { |
| 6608 if (skipNonConstInitializers) { |
| 6609 return; |
| 6610 } |
| 6611 addNamedSource( |
| 6612 '/a.dart', |
| 6613 ''' |
| 6614 int a = 0; |
| 6615 '''); |
| 6616 UnlinkedVariable variable = serializeVariableText(''' |
| 6617 import 'a.dart'; |
| 6618 final v = (a = 1); |
| 6619 '''); |
| 6620 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6621 isValidConst: false, |
| 6622 operators: [ |
| 6623 UnlinkedConstOperation.pushInt, |
| 6624 UnlinkedConstOperation.assignToRef, |
| 6625 ], |
| 6626 assignmentOperators: [ |
| 6627 (UnlinkedExprAssignOperator.assign) |
| 6628 ], |
| 6629 ints: [ |
| 6630 1, |
| 6631 ], |
| 6632 strings: [], |
| 6633 referenceValidators: [ |
| 6634 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a', |
| 6635 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 6636 ]); |
| 6637 } |
| 6638 |
| 6639 test_expr_assignToRef_topLevelVariable_imported_withPrefix() { |
| 6640 if (skipNonConstInitializers) { |
| 6641 return; |
| 6642 } |
| 6643 addNamedSource( |
| 6644 '/a.dart', |
| 6645 ''' |
| 6646 int a = 0; |
| 6647 '''); |
| 6648 UnlinkedVariable variable = serializeVariableText(''' |
| 6649 import 'a.dart' as p; |
| 6650 final v = (p.a = 1); |
| 6651 '''); |
| 6652 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6653 isValidConst: false, |
| 6654 operators: [ |
| 6655 UnlinkedConstOperation.pushInt, |
| 6656 UnlinkedConstOperation.assignToRef, |
| 6657 ], |
| 6658 assignmentOperators: [ |
| 6659 (UnlinkedExprAssignOperator.assign) |
| 6660 ], |
| 6661 ints: [ |
| 6662 1, |
| 6663 ], |
| 6664 strings: [], |
| 6665 referenceValidators: [ |
| 6666 (EntityRef r) { |
| 6667 return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a', |
| 6668 expectedKind: ReferenceKind.topLevelPropertyAccessor, |
| 6669 expectedPrefix: 'p'); |
| 6670 } |
| 6671 ]); |
| 6672 } |
| 6673 |
| 6674 test_expr_cascadeSection_assignToIndex() { |
| 6675 if (skipNonConstInitializers) { |
| 6676 return; |
| 6677 } |
| 6678 UnlinkedVariable variable = serializeVariableText(''' |
| 6679 class C { |
| 6680 List<int> items; |
| 6681 } |
| 6682 final C c = new C(); |
| 6683 final v = c.items..[1] = 2; |
| 6684 '''); |
| 6685 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6686 isValidConst: false, |
| 6687 operators: [ |
| 6688 UnlinkedConstOperation.pushReference, |
| 6689 // ..[1] = 2 |
| 6690 UnlinkedConstOperation.cascadeSectionBegin, |
| 6691 UnlinkedConstOperation.pushInt, |
| 6692 UnlinkedConstOperation.pushInt, |
| 6693 UnlinkedConstOperation.assignToIndex, |
| 6694 // c |
| 6695 UnlinkedConstOperation.cascadeSectionEnd, |
| 6696 ], |
| 6697 assignmentOperators: [ |
| 6698 UnlinkedExprAssignOperator.assign, |
| 6699 ], |
| 6700 ints: [ |
| 6701 2, |
| 6702 1 |
| 6703 ], |
| 6704 strings: [], |
| 6705 referenceValidators: [ |
| 6706 (EntityRef r) => checkTypeRef(r, null, null, 'items', |
| 6707 expectedKind: ReferenceKind.unresolved, |
| 6708 prefixExpectations: [ |
| 6709 new _PrefixExpectation( |
| 6710 ReferenceKind.topLevelPropertyAccessor, 'c'), |
| 6711 ]) |
| 6712 ]); |
| 6713 } |
| 6714 |
| 6715 test_expr_cascadeSection_assignToProperty() { |
| 6716 if (skipNonConstInitializers) { |
| 6717 return; |
| 6718 } |
| 6719 UnlinkedVariable variable = serializeVariableText(''' |
| 6720 class C { |
| 6721 int f1 = 0; |
| 6722 int f2 = 0; |
| 6723 } |
| 6724 final v = new C()..f1 = 1..f2 += 2; |
| 6725 '''); |
| 6726 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6727 isValidConst: false, |
| 6728 operators: [ |
| 6729 // new C() |
| 6730 UnlinkedConstOperation.invokeConstructor, |
| 6731 // ..f1 = 1 |
| 6732 UnlinkedConstOperation.cascadeSectionBegin, |
| 6733 UnlinkedConstOperation.pushInt, |
| 6734 UnlinkedConstOperation.assignToProperty, |
| 6735 // C |
| 6736 UnlinkedConstOperation.cascadeSectionEnd, |
| 6737 // ..f2 += 2 |
| 6738 UnlinkedConstOperation.cascadeSectionBegin, |
| 6739 UnlinkedConstOperation.pushInt, |
| 6740 UnlinkedConstOperation.assignToProperty, |
| 6741 // C |
| 6742 UnlinkedConstOperation.cascadeSectionEnd, |
| 6743 ], |
| 6744 assignmentOperators: [ |
| 6745 UnlinkedExprAssignOperator.assign, |
| 6746 UnlinkedExprAssignOperator.plus, |
| 6747 ], |
| 6748 ints: [ |
| 6749 0, 0, // new C() |
| 6750 1, // f1 = 1 |
| 6751 2, // f2 += 2 |
| 6752 ], |
| 6753 strings: [ |
| 6754 'f1', |
| 6755 'f2', |
| 6756 ], |
| 6757 referenceValidators: [ |
| 6758 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 6759 expectedKind: ReferenceKind.classOrEnum) |
| 6760 ]); |
| 6761 } |
| 6762 |
| 6763 test_expr_cascadeSection_embedded() { |
| 6764 if (skipNonConstInitializers) { |
| 6765 return; |
| 6766 } |
| 6767 UnlinkedVariable variable = serializeVariableText(''' |
| 6768 class A { |
| 6769 int fa1; |
| 6770 B b; |
| 6771 int fa2; |
| 6772 } |
| 6773 class B { |
| 6774 int fb; |
| 6775 } |
| 6776 final v = new A() |
| 6777 ..fa1 = 1 |
| 6778 ..b = (new B()..fb = 2) |
| 6779 ..fa2 = 3; |
| 6780 '''); |
| 6781 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6782 isValidConst: false, |
| 6783 operators: [ |
| 6784 // new A() |
| 6785 UnlinkedConstOperation.invokeConstructor, |
| 6786 // ..fa1 = 1 |
| 6787 UnlinkedConstOperation.cascadeSectionBegin, |
| 6788 UnlinkedConstOperation.pushInt, |
| 6789 UnlinkedConstOperation.assignToProperty, |
| 6790 UnlinkedConstOperation.cascadeSectionEnd, |
| 6791 // ..b |
| 6792 UnlinkedConstOperation.cascadeSectionBegin, |
| 6793 // new B() |
| 6794 UnlinkedConstOperation.invokeConstructor, |
| 6795 // ..fb = 2 |
| 6796 UnlinkedConstOperation.cascadeSectionBegin, |
| 6797 UnlinkedConstOperation.pushInt, |
| 6798 UnlinkedConstOperation.assignToProperty, |
| 6799 UnlinkedConstOperation.cascadeSectionEnd, |
| 6800 // ..b = <pop value> |
| 6801 UnlinkedConstOperation.assignToProperty, |
| 6802 UnlinkedConstOperation.cascadeSectionEnd, |
| 6803 // ..fa2 = 3 |
| 6804 UnlinkedConstOperation.cascadeSectionBegin, |
| 6805 UnlinkedConstOperation.pushInt, |
| 6806 UnlinkedConstOperation.assignToProperty, |
| 6807 UnlinkedConstOperation.cascadeSectionEnd, |
| 6808 ], |
| 6809 assignmentOperators: [ |
| 6810 UnlinkedExprAssignOperator.assign, |
| 6811 UnlinkedExprAssignOperator.assign, |
| 6812 UnlinkedExprAssignOperator.assign, |
| 6813 UnlinkedExprAssignOperator.assign, |
| 6814 ], |
| 6815 ints: [ |
| 6816 0, |
| 6817 0, |
| 6818 1, |
| 6819 0, |
| 6820 0, |
| 6821 2, |
| 6822 3, |
| 6823 ], |
| 6824 strings: [ |
| 6825 'fa1', |
| 6826 'fb', |
| 6827 'b', |
| 6828 'fa2', |
| 6829 ], |
| 6830 referenceValidators: [ |
| 6831 (EntityRef r) => checkTypeRef(r, null, null, 'A', |
| 6832 expectedKind: ReferenceKind.classOrEnum), |
| 6833 (EntityRef r) => checkTypeRef(r, null, null, 'B', |
| 6834 expectedKind: ReferenceKind.classOrEnum), |
| 6835 ]); |
| 6836 } |
| 6837 |
| 6838 test_expr_cascadeSection_invokeMethod() { |
| 6839 if (skipNonConstInitializers) { |
| 6840 return; |
| 6841 } |
| 6842 UnlinkedVariable variable = serializeVariableText(''' |
| 6843 class A { |
| 6844 int m(int _) => 0; |
| 6845 } |
| 6846 final A a = new A(); |
| 6847 final v = a..m(5).abs()..m(6); |
| 6848 '''); |
| 6849 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6850 isValidConst: false, |
| 6851 operators: [ |
| 6852 // a |
| 6853 UnlinkedConstOperation.pushReference, |
| 6854 // ..m(5) |
| 6855 UnlinkedConstOperation.cascadeSectionBegin, |
| 6856 UnlinkedConstOperation.pushInt, |
| 6857 UnlinkedConstOperation.invokeMethod, |
| 6858 // ..abs() |
| 6859 UnlinkedConstOperation.invokeMethod, |
| 6860 // a |
| 6861 UnlinkedConstOperation.cascadeSectionEnd, |
| 6862 // ..m(6) |
| 6863 UnlinkedConstOperation.cascadeSectionBegin, |
| 6864 UnlinkedConstOperation.pushInt, |
| 6865 UnlinkedConstOperation.invokeMethod, |
| 6866 // a |
| 6867 UnlinkedConstOperation.cascadeSectionEnd, |
| 6868 ], |
| 6869 ints: [ |
| 6870 5, 0, 1, 0, // m(5) |
| 6871 0, 0, 0, // abs() |
| 6872 6, 0, 1, 0, // m(5) |
| 6873 ], |
| 6874 strings: [ |
| 6875 'm', |
| 6876 'abs', |
| 6877 'm', |
| 6878 ], |
| 6879 referenceValidators: [ |
| 6880 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 6881 expectedKind: ReferenceKind.topLevelPropertyAccessor), |
| 6882 ]); |
| 6883 } |
| 6884 |
| 6885 test_expr_extractIndex_ofClassField() { |
| 6886 if (skipNonConstInitializers) { |
| 6887 return; |
| 6888 } |
| 6889 UnlinkedVariable variable = serializeVariableText(''' |
| 6890 class C { |
| 6891 List<int> get items => null; |
| 6892 } |
| 6893 final v = new C().items[5]; |
| 6894 '''); |
| 6895 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6896 isValidConst: false, |
| 6897 operators: [ |
| 6898 UnlinkedConstOperation.invokeConstructor, |
| 6899 UnlinkedConstOperation.extractProperty, |
| 6900 UnlinkedConstOperation.pushInt, |
| 6901 UnlinkedConstOperation.extractIndex, |
| 6902 ], |
| 6903 ints: [ |
| 6904 0, |
| 6905 0, |
| 6906 5 |
| 6907 ], |
| 6908 strings: [ |
| 6909 'items' |
| 6910 ], |
| 6911 referenceValidators: [ |
| 6912 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 6913 expectedKind: ReferenceKind.classOrEnum) |
| 6914 ]); |
| 6915 } |
| 6916 |
| 6917 test_expr_extractProperty_ofInvokeConstructor() { |
| 6918 if (skipNonConstInitializers) { |
| 6919 return; |
| 6920 } |
| 6921 UnlinkedVariable variable = serializeVariableText(''' |
| 6922 class C { |
| 6923 int f = 0; |
| 6924 } |
| 6925 final v = new C().f; |
| 6926 '''); |
| 6927 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6928 isValidConst: false, |
| 6929 operators: [ |
| 6930 UnlinkedConstOperation.invokeConstructor, |
| 6931 UnlinkedConstOperation.extractProperty, |
| 6932 ], |
| 6933 ints: [ |
| 6934 0, |
| 6935 0 |
| 6936 ], |
| 6937 strings: [ |
| 6938 'f' |
| 6939 ], |
| 6940 referenceValidators: [ |
| 6941 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 6942 expectedKind: ReferenceKind.classOrEnum) |
| 6943 ]); |
| 6944 } |
| 6945 |
| 6946 test_expr_functionExpression_asArgument() { |
| 6947 if (skipNonConstInitializers) { |
| 6948 return; |
| 6949 } |
| 6950 UnlinkedVariable variable = serializeVariableText(''' |
| 6951 final v = foo(5, () => 42); |
| 6952 foo(a, b) {} |
| 6953 '''); |
| 6954 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6955 isValidConst: false, |
| 6956 operators: [ |
| 6957 UnlinkedConstOperation.pushInt, |
| 6958 UnlinkedConstOperation.pushLocalFunctionReference, |
| 6959 UnlinkedConstOperation.invokeMethodRef |
| 6960 ], |
| 6961 ints: [ |
| 6962 5, |
| 6963 0, |
| 6964 0, |
| 6965 0, |
| 6966 2, |
| 6967 0 |
| 6968 ], |
| 6969 referenceValidators: [ |
| 6970 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 6971 expectedKind: ReferenceKind.topLevelFunction) |
| 6972 ]); |
| 6973 } |
| 6974 |
| 6975 test_expr_functionExpression_asArgument_multiple() { |
| 6976 if (skipNonConstInitializers) { |
| 6977 return; |
| 6978 } |
| 6979 UnlinkedVariable variable = serializeVariableText(''' |
| 6980 final v = foo(5, () => 42, () => 43); |
| 6981 foo(a, b, c) {} |
| 6982 '''); |
| 6983 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 6984 isValidConst: false, |
| 6985 operators: [ |
| 6986 UnlinkedConstOperation.pushInt, |
| 6987 UnlinkedConstOperation.pushLocalFunctionReference, |
| 6988 UnlinkedConstOperation.pushLocalFunctionReference, |
| 6989 UnlinkedConstOperation.invokeMethodRef |
| 6990 ], |
| 6991 ints: [ |
| 6992 5, |
| 6993 0, |
| 6994 0, |
| 6995 0, |
| 6996 1, |
| 6997 0, |
| 6998 3, |
| 6999 0 |
| 7000 ], |
| 7001 referenceValidators: [ |
| 7002 (EntityRef r) => checkTypeRef(r, null, null, 'foo', |
| 7003 expectedKind: ReferenceKind.topLevelFunction) |
| 7004 ]); |
| 7005 } |
| 7006 |
| 7007 test_expr_functionExpression_withBlockBody() { |
| 7008 if (skipNonConstInitializers) { |
| 7009 return; |
| 7010 } |
| 7011 UnlinkedVariable variable = serializeVariableText(''' |
| 7012 final v = () { return 42; }; |
| 7013 '''); |
| 7014 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7015 isValidConst: false, |
| 7016 operators: [UnlinkedConstOperation.pushLocalFunctionReference], |
| 7017 ints: [0, 0]); |
| 7018 } |
| 7019 |
| 7020 test_expr_functionExpression_withExpressionBody() { |
| 7021 if (skipNonConstInitializers) { |
| 7022 return; |
| 7023 } |
| 7024 UnlinkedVariable variable = serializeVariableText(''' |
| 7025 final v = () => 42; |
| 7026 '''); |
| 7027 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7028 isValidConst: false, |
| 7029 operators: [UnlinkedConstOperation.pushLocalFunctionReference], |
| 7030 ints: [0, 0]); |
| 7031 } |
| 7032 |
| 7033 test_expr_functionExpressionInvocation_withBlockBody() { |
| 7034 if (skipNonConstInitializers) { |
| 7035 return; |
| 7036 } |
| 7037 UnlinkedVariable variable = serializeVariableText(''' |
| 7038 final v = ((a, b) {return 42;})(1, 2); |
| 7039 '''); |
| 7040 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7041 isValidConst: false, operators: [UnlinkedConstOperation.pushNull]); |
| 7042 } |
| 7043 |
| 7044 test_expr_functionExpressionInvocation_withExpressionBody() { |
| 7045 if (skipNonConstInitializers) { |
| 7046 return; |
| 7047 } |
| 7048 UnlinkedVariable variable = serializeVariableText(''' |
| 7049 final v = ((a, b) => 42)(1, 2); |
| 7050 '''); |
| 7051 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7052 isValidConst: false, operators: [UnlinkedConstOperation.pushNull]); |
| 7053 } |
| 7054 |
| 7055 test_expr_inClosure() { |
| 7056 if (skipNonConstInitializers) { |
| 7057 return; |
| 7058 } |
| 7059 UnlinkedVariable variable = serializeVariableText('var v = () => 1;'); |
| 7060 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7061 operators: [UnlinkedConstOperation.pushInt], ints: [1]); |
| 7062 } |
| 7063 |
| 7064 test_expr_inClosure_noTypeInferenceNeeded() { |
| 7065 // We don't serialize closure body expressions for closures that don't need |
| 7066 // to participate in type inference. |
| 7067 UnlinkedVariable variable = serializeVariableText('Object v = () => 1;'); |
| 7068 expect(variable.initializer.localFunctions[0].bodyExpr, isNull); |
| 7069 } |
| 7070 |
| 7071 test_expr_inClosure_refersToOuterParam() { |
| 7072 if (skipNonConstInitializers) { |
| 7073 return; |
| 7074 } |
| 7075 UnlinkedVariable variable = |
| 7076 serializeVariableText('var v = (x) => (y) => x;'); |
| 7077 _assertUnlinkedConst( |
| 7078 variable.initializer.localFunctions[0].localFunctions[0].bodyExpr, |
| 7079 operators: [UnlinkedConstOperation.pushParameter], |
| 7080 strings: ['x']); |
| 7081 } |
| 7082 |
| 7083 test_expr_inClosure_refersToParam() { |
| 7084 if (skipNonConstInitializers) { |
| 7085 return; |
| 7086 } |
| 7087 UnlinkedVariable variable = serializeVariableText('var v = (x) => x;'); |
| 7088 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7089 operators: [UnlinkedConstOperation.pushParameter], strings: ['x']); |
| 7090 } |
| 7091 |
| 7092 test_expr_inClosure_refersToParam_methodCall() { |
| 7093 if (skipNonConstInitializers) { |
| 7094 return; |
| 7095 } |
| 7096 UnlinkedVariable variable = serializeVariableText('var v = (x) => x.f();'); |
| 7097 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7098 isValidConst: false, |
| 7099 operators: [ |
| 7100 UnlinkedConstOperation.pushParameter, |
| 7101 UnlinkedConstOperation.invokeMethod |
| 7102 ], |
| 7103 strings: [ |
| 7104 'x', |
| 7105 'f' |
| 7106 ], |
| 7107 ints: [ |
| 7108 0, |
| 7109 0, |
| 7110 0 |
| 7111 ]); |
| 7112 } |
| 7113 |
| 7114 test_expr_inClosure_refersToParam_methodCall_prefixed() { |
| 7115 if (skipNonConstInitializers) { |
| 7116 return; |
| 7117 } |
| 7118 UnlinkedVariable variable = |
| 7119 serializeVariableText('var v = (x) => x.y.f();'); |
| 7120 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7121 isValidConst: false, |
| 7122 operators: [ |
| 7123 UnlinkedConstOperation.pushParameter, |
| 7124 UnlinkedConstOperation.extractProperty, |
| 7125 UnlinkedConstOperation.invokeMethod |
| 7126 ], |
| 7127 strings: [ |
| 7128 'x', |
| 7129 'y', |
| 7130 'f' |
| 7131 ], |
| 7132 ints: [ |
| 7133 0, |
| 7134 0, |
| 7135 0 |
| 7136 ]); |
| 7137 } |
| 7138 |
| 7139 test_expr_inClosure_refersToParam_outOfScope() { |
| 7140 if (skipNonConstInitializers) { |
| 7141 return; |
| 7142 } |
| 7143 UnlinkedVariable variable = |
| 7144 serializeVariableText('var x; var v = (b) => (b ? (x) => x : x);'); |
| 7145 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7146 isValidConst: false, |
| 7147 operators: [ |
| 7148 UnlinkedConstOperation.pushParameter, |
| 7149 UnlinkedConstOperation.pushLocalFunctionReference, |
| 7150 UnlinkedConstOperation.pushReference, |
| 7151 UnlinkedConstOperation.conditional, |
| 7152 ], |
| 7153 strings: [ |
| 7154 'b' |
| 7155 ], |
| 7156 ints: [ |
| 7157 0, |
| 7158 0 |
| 7159 ], |
| 7160 referenceValidators: [ |
| 7161 (EntityRef r) => checkTypeRef(r, null, null, 'x', |
| 7162 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 7163 ]); |
| 7164 } |
| 7165 |
| 7166 test_expr_inClosure_refersToParam_prefixedIdentifier() { |
| 7167 if (skipNonConstInitializers) { |
| 7168 return; |
| 7169 } |
| 7170 UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y;'); |
| 7171 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7172 operators: [ |
| 7173 UnlinkedConstOperation.pushParameter, |
| 7174 UnlinkedConstOperation.extractProperty |
| 7175 ], |
| 7176 strings: [ |
| 7177 'x', |
| 7178 'y' |
| 7179 ]); |
| 7180 } |
| 7181 |
| 7182 test_expr_inClosure_refersToParam_prefixedIdentifier_assign() { |
| 7183 if (skipNonConstInitializers) { |
| 7184 return; |
| 7185 } |
| 7186 UnlinkedVariable variable = |
| 7187 serializeVariableText('var v = (x) => x.y = null;'); |
| 7188 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7189 isValidConst: false, |
| 7190 operators: [ |
| 7191 UnlinkedConstOperation.pushNull, |
| 7192 UnlinkedConstOperation.pushParameter, |
| 7193 UnlinkedConstOperation.assignToProperty |
| 7194 ], |
| 7195 strings: [ |
| 7196 'x', |
| 7197 'y' |
| 7198 ], |
| 7199 assignmentOperators: [ |
| 7200 UnlinkedExprAssignOperator.assign |
| 7201 ]); |
| 7202 } |
| 7203 |
| 7204 test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier() { |
| 7205 if (skipNonConstInitializers) { |
| 7206 return; |
| 7207 } |
| 7208 UnlinkedVariable variable = serializeVariableText('var v = (x) => x.y.z;'); |
| 7209 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7210 operators: [ |
| 7211 UnlinkedConstOperation.pushParameter, |
| 7212 UnlinkedConstOperation.extractProperty, |
| 7213 UnlinkedConstOperation.extractProperty |
| 7214 ], |
| 7215 strings: [ |
| 7216 'x', |
| 7217 'y', |
| 7218 'z' |
| 7219 ]); |
| 7220 } |
| 7221 |
| 7222 test_expr_inClosure_refersToParam_prefixedPrefixedIdentifier_assign() { |
| 7223 if (skipNonConstInitializers) { |
| 7224 return; |
| 7225 } |
| 7226 UnlinkedVariable variable = |
| 7227 serializeVariableText('var v = (x) => x.y.z = null;'); |
| 7228 _assertUnlinkedConst(variable.initializer.localFunctions[0].bodyExpr, |
| 7229 isValidConst: false, |
| 7230 operators: [ |
| 7231 UnlinkedConstOperation.pushNull, |
| 7232 UnlinkedConstOperation.pushParameter, |
| 7233 UnlinkedConstOperation.extractProperty, |
| 7234 UnlinkedConstOperation.assignToProperty |
| 7235 ], |
| 7236 strings: [ |
| 7237 'x', |
| 7238 'y', |
| 7239 'z' |
| 7240 ], |
| 7241 assignmentOperators: [ |
| 7242 UnlinkedExprAssignOperator.assign |
| 7243 ]); |
| 7244 } |
| 7245 |
| 7246 test_expr_invokeMethod_instance() { |
| 7247 if (skipNonConstInitializers) { |
| 7248 return; |
| 7249 } |
| 7250 UnlinkedVariable variable = serializeVariableText(''' |
| 7251 class C { |
| 7252 int m(a, {b, c}) => 42; |
| 7253 } |
| 7254 final v = new C().m(1, b: 2, c: 3); |
| 7255 '''); |
| 7256 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7257 isValidConst: false, |
| 7258 operators: [ |
| 7259 UnlinkedConstOperation.invokeConstructor, |
| 7260 UnlinkedConstOperation.pushInt, |
| 7261 UnlinkedConstOperation.pushInt, |
| 7262 UnlinkedConstOperation.pushInt, |
| 7263 UnlinkedConstOperation.invokeMethod, |
| 7264 ], |
| 7265 ints: [ |
| 7266 0, |
| 7267 0, |
| 7268 1, |
| 7269 2, |
| 7270 3, |
| 7271 2, |
| 7272 1, |
| 7273 0 |
| 7274 ], |
| 7275 strings: [ |
| 7276 'b', |
| 7277 'c', |
| 7278 'm' |
| 7279 ], |
| 7280 referenceValidators: [ |
| 7281 (EntityRef r) => checkTypeRef(r, null, null, 'C', |
| 7282 expectedKind: ReferenceKind.classOrEnum) |
| 7283 ]); |
| 7284 } |
| 7285 |
| 7286 test_expr_invokeMethod_withTypeParameters() { |
| 7287 if (skipNonConstInitializers) { |
| 7288 return; |
| 7289 } |
| 7290 UnlinkedVariable variable = serializeVariableText(''' |
| 7291 class C { |
| 7292 f<T, U>() => null; |
| 7293 } |
| 7294 final v = new C().f<int, String>(); |
| 7295 '''); |
| 7296 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7297 isValidConst: false, |
| 7298 operators: [ |
| 7299 UnlinkedConstOperation.invokeConstructor, |
| 7300 UnlinkedConstOperation.invokeMethod |
| 7301 ], |
| 7302 ints: [ |
| 7303 0, |
| 7304 0, |
| 7305 0, |
| 7306 0, |
| 7307 2 |
| 7308 ], |
| 7309 strings: [ |
| 7310 'f' |
| 7311 ], |
| 7312 referenceValidators: [ |
| 7313 (EntityRef r) => checkTypeRef(r, null, null, 'C'), |
| 7314 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int'), |
| 7315 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String') |
| 7316 ]); |
| 7317 } |
| 7318 |
| 7319 test_expr_invokeMethodRef_instance() { |
| 7320 if (skipNonConstInitializers) { |
| 7321 return; |
| 7322 } |
| 7323 UnlinkedVariable variable = serializeVariableText(''' |
| 7324 class A { |
| 7325 B b; |
| 7326 } |
| 7327 class B { |
| 7328 C c; |
| 7329 } |
| 7330 class C { |
| 7331 int m(int a, int b) => a + b; |
| 7332 } |
| 7333 A a = new A(); |
| 7334 final v = a.b.c.m(10, 20); |
| 7335 '''); |
| 7336 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7337 isValidConst: false, |
| 7338 operators: [ |
| 7339 UnlinkedConstOperation.pushInt, |
| 7340 UnlinkedConstOperation.pushInt, |
| 7341 UnlinkedConstOperation.invokeMethodRef, |
| 7342 ], |
| 7343 ints: [ |
| 7344 10, |
| 7345 20, |
| 7346 0, |
| 7347 2, |
| 7348 0 |
| 7349 ], |
| 7350 strings: [], |
| 7351 referenceValidators: [ |
| 7352 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 7353 expectedKind: ReferenceKind.unresolved, |
| 7354 prefixExpectations: [ |
| 7355 new _PrefixExpectation(ReferenceKind.unresolved, 'c'), |
| 7356 new _PrefixExpectation(ReferenceKind.unresolved, 'b'), |
| 7357 new _PrefixExpectation( |
| 7358 ReferenceKind.topLevelPropertyAccessor, 'a') |
| 7359 ]) |
| 7360 ]); |
| 7361 } |
| 7362 |
| 7363 test_expr_invokeMethodRef_static_importedWithPrefix() { |
| 7364 if (skipNonConstInitializers) { |
| 7365 return; |
| 7366 } |
| 7367 addNamedSource( |
| 7368 '/a.dart', |
| 7369 ''' |
| 7370 class C { |
| 7371 static int m() => 42; |
| 7372 } |
| 7373 '''); |
| 7374 UnlinkedVariable variable = serializeVariableText(''' |
| 7375 import 'a.dart' as p; |
| 7376 final v = p.C.m(); |
| 7377 '''); |
| 7378 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7379 isValidConst: false, |
| 7380 operators: [ |
| 7381 UnlinkedConstOperation.invokeMethodRef, |
| 7382 ], |
| 7383 ints: [ |
| 7384 0, |
| 7385 0, |
| 7386 0 |
| 7387 ], |
| 7388 strings: [], |
| 7389 referenceValidators: [ |
| 7390 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 7391 expectedKind: ReferenceKind.method, |
| 7392 prefixExpectations: [ |
| 7393 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C', |
| 7394 absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'), |
| 7395 new _PrefixExpectation(ReferenceKind.prefix, 'p') |
| 7396 ]) |
| 7397 ]); |
| 7398 } |
| 7399 |
| 7400 test_expr_invokeMethodRef_with_reference_arg() { |
| 7401 if (skipNonConstInitializers) { |
| 7402 return; |
| 7403 } |
| 7404 UnlinkedVariable variable = serializeVariableText(''' |
| 7405 f(x) => null; |
| 7406 final u = null; |
| 7407 final v = f(u); |
| 7408 '''); |
| 7409 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7410 isValidConst: false, |
| 7411 operators: [ |
| 7412 UnlinkedConstOperation.pushReference, |
| 7413 UnlinkedConstOperation.invokeMethodRef |
| 7414 ], |
| 7415 ints: [ |
| 7416 0, |
| 7417 1, |
| 7418 0 |
| 7419 ], |
| 7420 referenceValidators: [ |
| 7421 (EntityRef r) => checkTypeRef(r, null, null, 'u', |
| 7422 expectedKind: ReferenceKind.topLevelPropertyAccessor), |
| 7423 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 7424 expectedKind: ReferenceKind.topLevelFunction) |
| 7425 ]); |
| 7426 } |
| 7427 |
| 7428 test_expr_invokeMethodRef_withTypeParameters() { |
| 7429 if (skipNonConstInitializers) { |
| 7430 return; |
| 7431 } |
| 7432 UnlinkedVariable variable = serializeVariableText(''' |
| 7433 f<T, U>() => null; |
| 7434 final v = f<int, String>(); |
| 7435 '''); |
| 7436 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7437 isValidConst: false, |
| 7438 operators: [ |
| 7439 UnlinkedConstOperation.invokeMethodRef |
| 7440 ], |
| 7441 ints: [ |
| 7442 0, |
| 7443 0, |
| 7444 2 |
| 7445 ], |
| 7446 referenceValidators: [ |
| 7447 (EntityRef r) => checkTypeRef(r, null, null, 'f', |
| 7448 expectedKind: ReferenceKind.topLevelFunction, |
| 7449 numTypeParameters: 2), |
| 7450 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int'), |
| 7451 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String') |
| 7452 ]); |
| 7453 } |
| 7454 |
| 7455 test_expr_throwException() { |
| 7456 if (skipNonConstInitializers) { |
| 7457 return; |
| 7458 } |
| 7459 UnlinkedVariable variable = serializeVariableText(''' |
| 7460 final v = throw 1 + 2; |
| 7461 '''); |
| 7462 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7463 isValidConst: false, |
| 7464 operators: [ |
| 7465 UnlinkedConstOperation.pushInt, |
| 7466 UnlinkedConstOperation.pushInt, |
| 7467 UnlinkedConstOperation.add, |
| 7468 UnlinkedConstOperation.throwException, |
| 7469 ], |
| 7470 ints: [ |
| 7471 1, |
| 7472 2 |
| 7473 ]); |
| 7474 } |
| 7475 |
| 7476 test_expr_typeCast() { |
| 7477 if (skipNonConstInitializers) { |
| 7478 return; |
| 7479 } |
| 7480 UnlinkedVariable variable = serializeVariableText(''' |
| 7481 final v = 42 as num; |
| 7482 '''); |
| 7483 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7484 isValidConst: false, |
| 7485 operators: [ |
| 7486 UnlinkedConstOperation.pushInt, |
| 7487 UnlinkedConstOperation.typeCast, |
| 7488 ], |
| 7489 ints: [ |
| 7490 42 |
| 7491 ], |
| 7492 referenceValidators: [ |
| 7493 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num', |
| 7494 expectedKind: ReferenceKind.classOrEnum) |
| 7495 ]); |
| 7496 } |
| 7497 |
| 7498 test_expr_typeCheck() { |
| 7499 if (skipNonConstInitializers) { |
| 7500 return; |
| 7501 } |
| 7502 UnlinkedVariable variable = serializeVariableText(''' |
| 7503 final v = 42 is num; |
| 7504 '''); |
| 7505 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7506 isValidConst: false, |
| 7507 operators: [ |
| 7508 UnlinkedConstOperation.pushInt, |
| 7509 UnlinkedConstOperation.typeCheck, |
| 7510 ], |
| 7511 ints: [ |
| 7512 42 |
| 7513 ], |
| 7514 referenceValidators: [ |
| 7515 (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num', |
| 7516 expectedKind: ReferenceKind.classOrEnum) |
| 7517 ]); |
| 7518 } |
| 7519 |
| 7520 test_field() { |
| 7521 UnlinkedClass cls = serializeClassText('class C { int i; }'); |
| 7522 UnlinkedVariable variable = findVariable('i', variables: cls.fields); |
| 7523 expect(variable, isNotNull); |
| 7524 expect(variable.isConst, isFalse); |
| 7525 expect(variable.isStatic, isFalse); |
| 7526 expect(variable.isFinal, isFalse); |
| 7527 expect(variable.initializer, isNull); |
| 7528 expect(findExecutable('i', executables: cls.executables), isNull); |
| 7529 expect(findExecutable('i=', executables: cls.executables), isNull); |
| 7530 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 7531 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 7532 expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty); |
| 7533 } |
| 7534 |
| 7535 test_field_const() { |
| 7536 UnlinkedVariable variable = |
| 7537 serializeClassText('class C { static const int i = 0; }').fields[0]; |
| 7538 expect(variable.isConst, isTrue); |
| 7539 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7540 operators: [UnlinkedConstOperation.pushInt], ints: [0]); |
| 7541 } |
| 7542 |
| 7543 test_field_documented() { |
| 7544 String text = ''' |
| 7545 class C { |
| 7546 /** |
| 7547 * Docs |
| 7548 */ |
| 7549 var v; |
| 7550 }'''; |
| 7551 UnlinkedVariable variable = serializeClassText(text).fields[0]; |
| 7552 expect(variable.documentationComment, isNotNull); |
| 7553 checkDocumentationComment(variable.documentationComment, text); |
| 7554 } |
| 7555 |
| 7556 test_field_final() { |
| 7557 UnlinkedVariable variable = |
| 7558 serializeClassText('class C { final int i = 0; }').fields[0]; |
| 7559 expect(variable.isFinal, isTrue); |
| 7560 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7561 operators: [UnlinkedConstOperation.pushInt], ints: [0]); |
| 7562 } |
| 7563 |
| 7564 test_field_final_notConstExpr() { |
| 7565 UnlinkedVariable variable = serializeClassText(r''' |
| 7566 class C { |
| 7567 final int f = 1 + m(); |
| 7568 static int m() => 42; |
| 7569 }''').fields[0]; |
| 7570 expect(variable.isFinal, isTrue); |
| 7571 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7572 isValidConst: false, |
| 7573 operators: [ |
| 7574 UnlinkedConstOperation.pushInt, |
| 7575 UnlinkedConstOperation.invokeMethodRef, |
| 7576 UnlinkedConstOperation.add, |
| 7577 ], |
| 7578 ints: [ |
| 7579 1, |
| 7580 0, |
| 7581 0, |
| 7582 0 |
| 7583 ], |
| 7584 strings: [], |
| 7585 referenceValidators: [ |
| 7586 (EntityRef r) => checkTypeRef(r, null, null, 'm', |
| 7587 expectedKind: ReferenceKind.method, |
| 7588 prefixExpectations: [ |
| 7589 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C') |
| 7590 ]) |
| 7591 ]); |
| 7592 } |
| 7593 |
| 7594 test_field_final_typeParameter() { |
| 7595 UnlinkedVariable variable = serializeClassText(r''' |
| 7596 class C<T> { |
| 7597 final f = <T>[]; |
| 7598 }''').fields[0]; |
| 7599 expect(variable.isFinal, isTrue); |
| 7600 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 7601 operators: [UnlinkedConstOperation.makeTypedList], |
| 7602 ints: [0], |
| 7603 referenceValidators: [(EntityRef r) => checkParamTypeRef(r, 1)]); |
| 7604 } |
| 7605 |
| 7606 test_field_formal_param_inferred_type_explicit() { |
| 7607 UnlinkedClass cls = serializeClassText( |
| 7608 'class C extends D { var v; C(int this.v); }' |
| 7609 ' abstract class D { num get v; }', |
| 7610 className: 'C'); |
| 7611 checkInferredTypeSlot( |
| 7612 cls.fields[0].inferredTypeSlot, 'dart:core', 'dart:core', 'num'); |
| 7613 expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor); |
| 7614 expect(cls.executables[0].parameters[0].inferredTypeSlot, 0); |
| 7615 } |
| 7616 |
| 7617 test_field_formal_param_inferred_type_implicit() { |
| 7618 // Both the field `v` and the constructor argument `this.v` will have their |
| 7619 // type inferred by strong mode. But only the field should have its |
| 7620 // inferred type stored in the summary, since the standard rules for field |
| 7621 // formal parameters will take care of the rest (they implicitly inherit |
| 7622 // the type of the associated field). |
| 7623 UnlinkedClass cls = serializeClassText( |
| 7624 'class C extends D { var v; C(this.v); }' |
| 7625 ' abstract class D { int get v; }', |
| 7626 className: 'C'); |
| 7627 checkInferredTypeSlot( |
| 7628 cls.fields[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 7629 expect(cls.executables[0].kind, UnlinkedExecutableKind.constructor); |
| 7630 expect(cls.executables[0].parameters[0].inferredTypeSlot, 0); |
| 7631 } |
| 7632 |
| 7633 test_field_inferred_type_nonstatic_explicit_initialized() { |
| 7634 UnlinkedVariable v = serializeClassText('class C { num v = 0; }').fields[0]; |
| 7635 expect(v.inferredTypeSlot, 0); |
| 7636 } |
| 7637 |
| 7638 test_field_inferred_type_nonstatic_explicit_uninitialized() { |
| 7639 UnlinkedVariable v = serializeClassText( |
| 7640 'class C extends D { num v; } abstract class D { int get v; }', |
| 7641 className: 'C', |
| 7642 allowErrors: true) |
| 7643 .fields[0]; |
| 7644 expect(v.inferredTypeSlot, 0); |
| 7645 } |
| 7646 |
| 7647 test_field_inferred_type_nonstatic_implicit_initialized() { |
| 7648 UnlinkedVariable v = serializeClassText('class C { var v = 0; }').fields[0]; |
| 7649 checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 7650 } |
| 7651 |
| 7652 test_field_inferred_type_nonstatic_implicit_uninitialized() { |
| 7653 UnlinkedVariable v = serializeClassText( |
| 7654 'class C extends D { var v; } abstract class D { int get v; }', |
| 7655 className: 'C') |
| 7656 .fields[0]; |
| 7657 checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 7658 } |
| 7659 |
| 7660 test_field_inferred_type_static_explicit_initialized() { |
| 7661 UnlinkedVariable v = |
| 7662 serializeClassText('class C { static int v = 0; }').fields[0]; |
| 7663 expect(v.inferredTypeSlot, 0); |
| 7664 } |
| 7665 |
| 7666 test_field_inferred_type_static_implicit_initialized() { |
| 7667 UnlinkedVariable v = |
| 7668 serializeClassText('class C { static var v = 0; }').fields[0]; |
| 7669 checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 7670 } |
| 7671 |
| 7672 test_field_inferred_type_static_implicit_uninitialized() { |
| 7673 UnlinkedVariable v = |
| 7674 serializeClassText('class C { static var v; }').fields[0]; |
| 7675 expect(v.inferredTypeSlot, 0); |
| 7676 } |
| 7677 |
| 7678 test_field_static() { |
| 7679 UnlinkedVariable variable = |
| 7680 serializeClassText('class C { static int i; }').fields[0]; |
| 7681 expect(variable.isStatic, isTrue); |
| 7682 expect(variable.initializer, isNull); |
| 7683 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 7684 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C'); |
| 7685 expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1)); |
| 7686 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'i'); |
| 7687 expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind, |
| 7688 ReferenceKind.propertyAccessor); |
| 7689 expect( |
| 7690 unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters, |
| 7691 0); |
| 7692 expect( |
| 7693 unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty); |
| 7694 } |
| 7695 |
| 7696 test_field_static_final() { |
| 7697 UnlinkedVariable variable = |
| 7698 serializeClassText('class C { static final int i = 0; }').fields[0]; |
| 7699 expect(variable.isStatic, isTrue); |
| 7700 expect(variable.isFinal, isTrue); |
| 7701 expect(variable.initializer.bodyExpr, isNull); |
| 7702 } |
| 7703 |
| 7704 test_field_static_final_untyped() { |
| 7705 UnlinkedVariable variable = |
| 7706 serializeClassText('class C { static final x = 0; }').fields[0]; |
| 7707 expect(variable.initializer.bodyExpr, isNotNull); |
| 7708 } |
| 7709 |
| 7710 test_field_untyped() { |
| 7711 UnlinkedVariable variable = |
| 7712 serializeClassText('class C { var x = 0; }').fields[0]; |
| 7713 expect(variable.initializer.bodyExpr, isNotNull); |
| 7714 } |
| 7715 |
| 7716 test_fully_linked_references_follow_other_references() { |
| 7717 if (!strongMode || skipFullyLinkedData) { |
| 7718 return; |
| 7719 } |
| 7720 serializeLibraryText('final x = 0; String y;'); |
| 7721 checkLinkedTypeSlot(unlinkedUnits[0].variables[0].inferredTypeSlot, |
| 7722 'dart:core', 'dart:core', 'int'); |
| 7723 checkTypeRef( |
| 7724 unlinkedUnits[0].variables[1].type, 'dart:core', 'dart:core', 'String'); |
| 7725 // Even though the definition of y follows the definition of x, the linked |
| 7726 // type reference for x should use a higher numbered reference than the |
| 7727 // unlinked type reference for y. |
| 7728 EntityRef propagatedType = |
| 7729 getTypeRefForSlot(unlinkedUnits[0].variables[0].inferredTypeSlot); |
| 7730 expect(unlinkedUnits[0].variables[1].type.reference, |
| 7731 lessThan(propagatedType.reference)); |
| 7732 } |
| 7733 |
| 7734 test_function_documented() { |
| 7735 String text = ''' |
| 7736 // Extra comment so doc comment offset != 0 |
| 7737 /** |
| 7738 * Docs |
| 7739 */ |
| 7740 f() {}'''; |
| 7741 UnlinkedExecutable executable = serializeExecutableText(text); |
| 7742 expect(executable.documentationComment, isNotNull); |
| 7743 checkDocumentationComment(executable.documentationComment, text); |
| 7744 } |
| 7745 |
| 7746 test_function_inferred_type_implicit_param() { |
| 7747 UnlinkedExecutable f = serializeExecutableText('void f(value) {}'); |
| 7748 expect(f.parameters[0].inferredTypeSlot, 0); |
| 7749 } |
| 7750 |
| 7751 test_function_inferred_type_implicit_return() { |
| 7752 UnlinkedExecutable f = serializeExecutableText('f() => null;'); |
| 7753 expect(f.inferredReturnTypeSlot, 0); |
| 7754 } |
| 7755 |
| 7756 test_generic_gClass_gMethodStatic() { |
| 7757 UnlinkedClass cls = serializeClassText(''' |
| 7758 class C<T, U> { |
| 7759 static void m<V, W>(V v, W w) { |
| 7760 void f<X, Y>(V v, W w, X x, Y y) { |
| 7761 } |
| 7762 } |
| 7763 } |
| 7764 '''); |
| 7765 UnlinkedExecutable m = cls.executables[0]; |
| 7766 UnlinkedExecutable f = m.localFunctions[0]; |
| 7767 checkParamTypeRef(m.parameters[0].type, 2); |
| 7768 checkParamTypeRef(m.parameters[1].type, 1); |
| 7769 checkParamTypeRef(f.parameters[0].type, 4); |
| 7770 checkParamTypeRef(f.parameters[1].type, 3); |
| 7771 checkParamTypeRef(f.parameters[2].type, 2); |
| 7772 checkParamTypeRef(f.parameters[3].type, 1); |
| 7773 } |
| 7774 |
| 7775 test_generic_method_in_generic_class() { |
| 7776 UnlinkedClass cls = serializeClassText( |
| 7777 'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }'); |
| 7778 List<UnlinkedParam> params = cls.executables[0].parameters; |
| 7779 checkParamTypeRef(params[0].type, 4); |
| 7780 checkParamTypeRef(params[1].type, 3); |
| 7781 checkParamTypeRef(params[2].type, 2); |
| 7782 checkParamTypeRef(params[3].type, 1); |
| 7783 } |
| 7784 |
| 7785 test_getter_documented() { |
| 7786 String text = ''' |
| 7787 // Extra comment so doc comment offset != 0 |
| 7788 /** |
| 7789 * Docs |
| 7790 */ |
| 7791 get f => null;'''; |
| 7792 UnlinkedExecutable executable = serializeExecutableText(text); |
| 7793 expect(executable.documentationComment, isNotNull); |
| 7794 checkDocumentationComment(executable.documentationComment, text); |
| 7795 } |
| 7796 |
| 7797 test_getter_inferred_type_nonstatic_explicit_return() { |
| 7798 UnlinkedExecutable f = serializeClassText( |
| 7799 'class C extends D { num get f => null; }' |
| 7800 ' abstract class D { int get f; }', |
| 7801 className: 'C', |
| 7802 allowErrors: true) |
| 7803 .executables[0]; |
| 7804 expect(f.inferredReturnTypeSlot, 0); |
| 7805 } |
| 7806 |
| 7807 test_getter_inferred_type_nonstatic_implicit_return() { |
| 7808 UnlinkedExecutable f = serializeClassText( |
| 7809 'class C extends D { get f => null; } abstract class D { int get f;
}', |
| 7810 className: 'C') |
| 7811 .executables[0]; |
| 7812 checkInferredTypeSlot( |
| 7813 f.inferredReturnTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 7814 } |
| 7815 |
| 7816 test_getter_inferred_type_static_implicit_return() { |
| 7817 UnlinkedExecutable f = serializeClassText( |
| 7818 'class C extends D { static get f => null; }' |
| 7819 ' class D { static int get f => null; }', |
| 7820 className: 'C') |
| 7821 .executables[0]; |
| 7822 expect(f.inferredReturnTypeSlot, 0); |
| 7823 } |
| 7824 |
| 7825 test_implicit_dependencies_follow_other_dependencies() { |
| 7826 if (skipFullyLinkedData) { |
| 7827 return; |
| 7828 } |
| 7829 addNamedSource('/a.dart', 'import "b.dart"; class C {} D f() => null;'); |
| 7830 addNamedSource('/b.dart', 'class D {}'); |
| 7831 serializeLibraryText('import "a.dart"; final x = f(); C y;'); |
| 7832 // The dependency on b.dart is implicit, so it should be placed at the end |
| 7833 // of the dependency list, after a.dart, even though the code that refers |
| 7834 // to b.dart comes before the code that refers to a.dart. |
| 7835 int aDep = checkHasDependency('a.dart', fullyLinked: false); |
| 7836 int bDep = checkHasDependency('b.dart', fullyLinked: true); |
| 7837 expect(aDep, lessThan(bDep)); |
| 7838 } |
| 7839 |
| 7840 test_import_configurations() { |
| 7841 addNamedSource('/foo.dart', 'bar() {}'); |
| 7842 addNamedSource('/foo_io.dart', 'bar() {}'); |
| 7843 addNamedSource('/foo_html.dart', 'bar() {}'); |
| 7844 String libraryText = r''' |
| 7845 import 'foo.dart' |
| 7846 if (dart.library.io) 'foo_io.dart' |
| 7847 if (dart.flavor == 'html') 'foo_html.dart'; |
| 7848 '''; |
| 7849 serializeLibraryText(libraryText); |
| 7850 UnlinkedImport imp = unlinkedUnits[0].imports[0]; |
| 7851 expect(imp.configurations, hasLength(2)); |
| 7852 { |
| 7853 UnlinkedConfiguration configuration = imp.configurations[0]; |
| 7854 expect(configuration.name, 'dart.library.io'); |
| 7855 expect(configuration.value, 'true'); |
| 7856 expect(configuration.uri, 'foo_io.dart'); |
| 7857 } |
| 7858 { |
| 7859 UnlinkedConfiguration configuration = imp.configurations[1]; |
| 7860 expect(configuration.name, 'dart.flavor'); |
| 7861 expect(configuration.value, 'html'); |
| 7862 expect(configuration.uri, 'foo_html.dart'); |
| 7863 } |
| 7864 } |
| 7865 |
| 7866 test_import_deferred() { |
| 7867 serializeLibraryText( |
| 7868 'import "dart:async" deferred as a; main() { print(a.Future); }'); |
| 7869 expect(unlinkedUnits[0].imports[0].isDeferred, isTrue); |
| 7870 } |
| 7871 |
| 7872 test_import_dependency() { |
| 7873 serializeLibraryText('import "dart:async"; Future x;'); |
| 7874 // Second import is the implicit import of dart:core |
| 7875 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7876 checkDependency(linked.importDependencies[0], 'dart:async', 'dart:async'); |
| 7877 } |
| 7878 |
| 7879 test_import_explicit() { |
| 7880 serializeLibraryText('import "dart:core"; int i;'); |
| 7881 expect(unlinkedUnits[0].imports, hasLength(1)); |
| 7882 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse); |
| 7883 } |
| 7884 |
| 7885 test_import_hide_order() { |
| 7886 serializeLibraryText( |
| 7887 'import "dart:async" hide Future, Stream; Completer c;'); |
| 7888 // Second import is the implicit import of dart:core |
| 7889 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7890 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1)); |
| 7891 expect(unlinkedUnits[0].imports[0].combinators[0].shows, isEmpty); |
| 7892 expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2)); |
| 7893 expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future'); |
| 7894 expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream'); |
| 7895 expect(unlinkedUnits[0].imports[0].combinators[0].offset, 0); |
| 7896 expect(unlinkedUnits[0].imports[0].combinators[0].end, 0); |
| 7897 } |
| 7898 |
| 7899 test_import_implicit() { |
| 7900 // The implicit import of dart:core is represented in the model. |
| 7901 serializeLibraryText(''); |
| 7902 expect(unlinkedUnits[0].imports, hasLength(1)); |
| 7903 checkDependency(linked.importDependencies[0], 'dart:core', 'dart:core'); |
| 7904 expect(unlinkedUnits[0].imports[0].uri, isEmpty); |
| 7905 expect(unlinkedUnits[0].imports[0].uriOffset, 0); |
| 7906 expect(unlinkedUnits[0].imports[0].uriEnd, 0); |
| 7907 expect(unlinkedUnits[0].imports[0].prefixReference, 0); |
| 7908 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); |
| 7909 expect(unlinkedUnits[0].imports[0].isImplicit, isTrue); |
| 7910 } |
| 7911 |
| 7912 test_import_missing() { |
| 7913 // Unresolved imports are included since this is necessary for proper |
| 7914 // dependency tracking. |
| 7915 allowMissingFiles = true; |
| 7916 serializeLibraryText('import "foo.dart";', allowErrors: true); |
| 7917 // Second import is the implicit import of dart:core |
| 7918 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7919 checkDependency( |
| 7920 linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 7921 } |
| 7922 |
| 7923 test_import_no_combinators() { |
| 7924 serializeLibraryText('import "dart:async"; Future x;'); |
| 7925 // Second import is the implicit import of dart:core |
| 7926 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7927 expect(unlinkedUnits[0].imports[0].combinators, isEmpty); |
| 7928 } |
| 7929 |
| 7930 test_import_no_flags() { |
| 7931 serializeLibraryText('import "dart:async"; Future x;'); |
| 7932 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse); |
| 7933 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse); |
| 7934 } |
| 7935 |
| 7936 test_import_non_deferred() { |
| 7937 serializeLibraryText( |
| 7938 'import "dart:async" as a; main() { print(a.Future); }'); |
| 7939 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse); |
| 7940 } |
| 7941 |
| 7942 test_import_of_file_with_missing_part() { |
| 7943 // Other references in foo.dart should be resolved even though foo.dart's |
| 7944 // part declaration for bar.dart refers to a non-existent file. |
| 7945 allowMissingFiles = true; |
| 7946 addNamedSource('/foo.dart', 'part "bar.dart"; class C {}'); |
| 7947 serializeLibraryText('import "foo.dart"; C x;'); |
| 7948 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); |
| 7949 } |
| 7950 |
| 7951 test_import_of_missing_export() { |
| 7952 // Other references in foo.dart should be resolved even though foo.dart's |
| 7953 // re-export of bar.dart refers to a non-existent file. |
| 7954 allowMissingFiles = true; |
| 7955 addNamedSource('/foo.dart', 'export "bar.dart"; class C {}'); |
| 7956 serializeLibraryText('import "foo.dart"; C x;'); |
| 7957 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C'); |
| 7958 } |
| 7959 |
| 7960 test_import_offset() { |
| 7961 String libraryText = ' import "dart:async"; Future x;'; |
| 7962 serializeLibraryText(libraryText); |
| 7963 expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import')); |
| 7964 expect(unlinkedUnits[0].imports[0].uriOffset, |
| 7965 libraryText.indexOf('"dart:async"')); |
| 7966 expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future')); |
| 7967 } |
| 7968 |
| 7969 test_import_prefix_name() { |
| 7970 String libraryText = 'import "dart:async" as a; a.Future x;'; |
| 7971 serializeLibraryText(libraryText); |
| 7972 // Second import is the implicit import of dart:core |
| 7973 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7974 checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a'); |
| 7975 expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;')); |
| 7976 } |
| 7977 |
| 7978 test_import_prefix_none() { |
| 7979 serializeLibraryText('import "dart:async"; Future x;'); |
| 7980 // Second import is the implicit import of dart:core |
| 7981 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 7982 expect(unlinkedUnits[0].imports[0].prefixReference, 0); |
| 7983 } |
| 7984 |
| 7985 test_import_prefix_not_in_public_namespace() { |
| 7986 serializeLibraryText('import "dart:async" as a; a.Future v;'); |
| 7987 expect(unlinkedUnits[0].publicNamespace.names, hasLength(2)); |
| 7988 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v'); |
| 7989 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v='); |
| 7990 } |
| 7991 |
| 7992 test_import_prefix_reference() { |
| 7993 UnlinkedVariable variable = |
| 7994 serializeVariableText('import "dart:async" as a; a.Future v;'); |
| 7995 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', |
| 7996 expectedPrefix: 'a', numTypeParameters: 1); |
| 7997 } |
| 7998 |
| 7999 test_import_prefixes_take_precedence_over_imported_names() { |
| 8000 addNamedSource('/a.dart', 'class b {} class A'); |
| 8001 addNamedSource('/b.dart', 'class Cls {}'); |
| 8002 addNamedSource('/c.dart', 'class Cls {}'); |
| 8003 addNamedSource('/d.dart', 'class c {} class D'); |
| 8004 serializeLibraryText(''' |
| 8005 import 'a.dart'; |
| 8006 import 'b.dart' as b; |
| 8007 import 'c.dart' as c; |
| 8008 import 'd.dart'; |
| 8009 A aCls; |
| 8010 b.Cls bCls; |
| 8011 c.Cls cCls; |
| 8012 D dCls; |
| 8013 '''); |
| 8014 checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A'); |
| 8015 checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls', |
| 8016 expectedPrefix: 'b'); |
| 8017 checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls', |
| 8018 expectedPrefix: 'c'); |
| 8019 checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D'); |
| 8020 } |
| 8021 |
| 8022 test_import_reference() { |
| 8023 UnlinkedVariable variable = |
| 8024 serializeVariableText('import "dart:async"; Future v;'); |
| 8025 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future', |
| 8026 numTypeParameters: 1); |
| 8027 } |
| 8028 |
| 8029 test_import_reference_merged_no_prefix() { |
| 8030 serializeLibraryText(''' |
| 8031 import "dart:async" show Future; |
| 8032 import "dart:async" show Stream; |
| 8033 |
| 8034 Future f; |
| 8035 Stream s; |
| 8036 '''); |
| 8037 { |
| 8038 EntityRef typeRef = findVariable('f').type; |
| 8039 checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future', |
| 8040 numTypeParameters: 1); |
| 8041 } |
| 8042 { |
| 8043 EntityRef typeRef = findVariable('s').type; |
| 8044 checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream', |
| 8045 expectedTargetUnit: 1, numTypeParameters: 1); |
| 8046 } |
| 8047 } |
| 8048 |
| 8049 test_import_reference_merged_prefixed() { |
| 8050 serializeLibraryText(''' |
| 8051 import "dart:async" as a show Future; |
| 8052 import "dart:async" as a show Stream; |
| 8053 |
| 8054 a.Future f; |
| 8055 a.Stream s; |
| 8056 '''); |
| 8057 { |
| 8058 EntityRef typeRef = findVariable('f').type; |
| 8059 checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future', |
| 8060 expectedPrefix: 'a', numTypeParameters: 1); |
| 8061 } |
| 8062 { |
| 8063 EntityRef typeRef = findVariable('s').type; |
| 8064 checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream', |
| 8065 expectedTargetUnit: 1, expectedPrefix: 'a', numTypeParameters: 1); |
| 8066 } |
| 8067 } |
| 8068 |
| 8069 test_import_reference_merged_prefixed_separate_libraries() { |
| 8070 addNamedSource('/a.dart', 'class A {}'); |
| 8071 addNamedSource('/b.dart', 'class B {}'); |
| 8072 serializeLibraryText(''' |
| 8073 import 'a.dart' as p; |
| 8074 import 'b.dart' as p; |
| 8075 |
| 8076 p.A a; |
| 8077 p.B b; |
| 8078 '''); |
| 8079 checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A', |
| 8080 expectedPrefix: 'p'); |
| 8081 checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B', |
| 8082 expectedPrefix: 'p'); |
| 8083 } |
| 8084 |
| 8085 test_import_self() { |
| 8086 serializeLibraryText(''' |
| 8087 import 'test.dart' as p; |
| 8088 class C {} |
| 8089 class D extends p.C {} // Prevent "unused import" warning |
| 8090 '''); |
| 8091 expect(unlinkedUnits[0].imports[0].uri, 'test.dart'); |
| 8092 checkDependency( |
| 8093 linked.importDependencies[0], absUri('/test.dart'), 'test.dart'); |
| 8094 checkTypeRef(unlinkedUnits[0].classes[1].supertype, absUri('/test.dart'), |
| 8095 'test.dart', 'C', |
| 8096 expectedPrefix: 'p'); |
| 8097 } |
| 8098 |
| 8099 test_import_show_order() { |
| 8100 String libraryText = |
| 8101 'import "dart:async" show Future, Stream; Future x; Stream y;'; |
| 8102 serializeLibraryText(libraryText); |
| 8103 // Second import is the implicit import of dart:core |
| 8104 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 8105 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1)); |
| 8106 expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2)); |
| 8107 expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty); |
| 8108 expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future'); |
| 8109 expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream'); |
| 8110 expect(unlinkedUnits[0].imports[0].combinators[0].offset, |
| 8111 libraryText.indexOf('show')); |
| 8112 expect(unlinkedUnits[0].imports[0].combinators[0].end, |
| 8113 libraryText.indexOf('; Future')); |
| 8114 } |
| 8115 |
| 8116 test_import_uri() { |
| 8117 String uriString = '"dart:async"'; |
| 8118 String libraryText = 'import $uriString; Future x;'; |
| 8119 serializeLibraryText(libraryText); |
| 8120 // Second import is the implicit import of dart:core |
| 8121 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 8122 expect(unlinkedUnits[0].imports[0].uri, 'dart:async'); |
| 8123 } |
| 8124 |
| 8125 test_inferred_function_type_parameter_type_with_unrelated_type_param() { |
| 8126 if (!strongMode || skipFullyLinkedData) { |
| 8127 return; |
| 8128 } |
| 8129 // The type that is inferred for C.f's parameter g is "() -> void". |
| 8130 // Since the associated element for that function type is B.f's parameter g, |
| 8131 // and B has a type parameter, the inferred type will record a type |
| 8132 // parameter. |
| 8133 UnlinkedClass c = serializeClassText(''' |
| 8134 abstract class B<T> { |
| 8135 void f(void g()); |
| 8136 } |
| 8137 class C<T> extends B<T> { |
| 8138 void f(g) {} |
| 8139 } |
| 8140 '''); |
| 8141 expect(c.executables, hasLength(1)); |
| 8142 UnlinkedExecutable f = c.executables[0]; |
| 8143 expect(f.parameters, hasLength(1)); |
| 8144 UnlinkedParam g = f.parameters[0]; |
| 8145 expect(g.name, 'g'); |
| 8146 EntityRef typeRef = getTypeRefForSlot(g.inferredTypeSlot); |
| 8147 checkLinkedTypeRef(typeRef, null, null, 'f', |
| 8148 expectedKind: ReferenceKind.method, numTypeArguments: 1); |
| 8149 checkParamTypeRef(typeRef.typeArguments[0], 1); |
| 8150 } |
| 8151 |
| 8152 test_inferred_type_keeps_leading_dynamic() { |
| 8153 if (!strongMode || skipFullyLinkedData) { |
| 8154 return; |
| 8155 } |
| 8156 UnlinkedClass cls = |
| 8157 serializeClassText('class C { final x = <dynamic, int>{}; }'); |
| 8158 EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot); |
| 8159 // Check that x has inferred type `Map<dynamic, int>`. |
| 8160 checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map', |
| 8161 numTypeParameters: 2, numTypeArguments: 2); |
| 8162 checkLinkedTypeRef(type.typeArguments[0], null, null, 'dynamic'); |
| 8163 checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int'); |
| 8164 } |
| 8165 |
| 8166 test_inferred_type_reference_shared_prefixed() { |
| 8167 if (!strongMode || skipFullyLinkedData) { |
| 8168 return; |
| 8169 } |
| 8170 // Variable `y` has an inferred type of `p.C`. Verify that the reference |
| 8171 // used by the explicit type of `x` is re-used for the inferred type. |
| 8172 addNamedSource('/a.dart', 'class C {}'); |
| 8173 serializeLibraryText('import "a.dart" as p; p.C x; var y = new p.C();'); |
| 8174 EntityRef xType = findVariable('x').type; |
| 8175 EntityRef yType = getTypeRefForSlot(findVariable('y').inferredTypeSlot); |
| 8176 expect(yType.reference, xType.reference); |
| 8177 } |
| 8178 |
| 8179 test_inferred_type_refers_to_bound_type_param() { |
| 8180 if (!strongMode || skipFullyLinkedData) { |
| 8181 return; |
| 8182 } |
| 8183 UnlinkedClass cls = serializeClassText( |
| 8184 'class C<T> extends D<int, T> { var v; }' |
| 8185 ' abstract class D<U, V> { Map<V, U> get v; }', |
| 8186 className: 'C'); |
| 8187 EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot); |
| 8188 // Check that v has inferred type Map<T, int>. |
| 8189 checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map', |
| 8190 numTypeParameters: 2, numTypeArguments: 2); |
| 8191 checkParamTypeRef(type.typeArguments[0], 1); |
| 8192 checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int'); |
| 8193 } |
| 8194 |
| 8195 test_inferred_type_refers_to_function_typed_param_of_typedef() { |
| 8196 if (!strongMode || skipFullyLinkedData) { |
| 8197 return; |
| 8198 } |
| 8199 UnlinkedVariable v = serializeVariableText(''' |
| 8200 typedef void F(int g(String s)); |
| 8201 h(F f) => null; |
| 8202 var v = h((y) {}); |
| 8203 '''); |
| 8204 expect(v.initializer.localFunctions, hasLength(1)); |
| 8205 UnlinkedExecutable closure = v.initializer.localFunctions[0]; |
| 8206 expect(closure.parameters, hasLength(1)); |
| 8207 UnlinkedParam y = closure.parameters[0]; |
| 8208 expect(y.name, 'y'); |
| 8209 EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot); |
| 8210 checkLinkedTypeRef(typeRef, null, null, 'F', |
| 8211 expectedKind: ReferenceKind.typedef); |
| 8212 expect(typeRef.implicitFunctionTypeIndices, [0]); |
| 8213 } |
| 8214 |
| 8215 test_inferred_type_refers_to_function_typed_parameter_type_generic_class() { |
| 8216 if (!strongMode || skipFullyLinkedData) { |
| 8217 return; |
| 8218 } |
| 8219 UnlinkedClass cls = serializeClassText( |
| 8220 'class C<T, U> extends D<U, int> { void f(int x, g) {} }' |
| 8221 ' abstract class D<V, W> { void f(int x, W g(V s)); }', |
| 8222 className: 'C'); |
| 8223 EntityRef type = |
| 8224 getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot); |
| 8225 // Check that parameter g's inferred type is the type implied by D.f's 1st |
| 8226 // (zero-based) parameter. |
| 8227 expect(type.implicitFunctionTypeIndices, [1]); |
| 8228 expect(type.paramReference, 0); |
| 8229 expect(type.typeArguments, hasLength(2)); |
| 8230 checkParamTypeRef(type.typeArguments[0], 1); |
| 8231 checkTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int'); |
| 8232 expect(type.reference, |
| 8233 greaterThanOrEqualTo(unlinkedUnits[0].references.length)); |
| 8234 LinkedReference linkedReference = |
| 8235 linked.units[0].references[type.reference]; |
| 8236 expect(linkedReference.dependency, 0); |
| 8237 expect(linkedReference.kind, ReferenceKind.method); |
| 8238 expect(linkedReference.name, 'f'); |
| 8239 expect(linkedReference.numTypeParameters, 0); |
| 8240 expect(linkedReference.unit, 0); |
| 8241 expect(linkedReference.containingReference, isNot(0)); |
| 8242 expect(linkedReference.containingReference, lessThan(type.reference)); |
| 8243 checkReferenceIndex(linkedReference.containingReference, null, null, 'D', |
| 8244 numTypeParameters: 2); |
| 8245 } |
| 8246 |
| 8247 test_inferred_type_refers_to_function_typed_parameter_type_other_lib() { |
| 8248 if (!strongMode || skipFullyLinkedData) { |
| 8249 return; |
| 8250 } |
| 8251 addNamedSource('/a.dart', 'import "b.dart"; abstract class D extends E {}'); |
| 8252 addNamedSource( |
| 8253 '/b.dart', 'abstract class E { void f(int x, int g(String s)); }'); |
| 8254 UnlinkedClass cls = serializeClassText( |
| 8255 'import "a.dart"; class C extends D { void f(int x, g) {} }'); |
| 8256 EntityRef type = |
| 8257 getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot); |
| 8258 // Check that parameter g's inferred type is the type implied by D.f's 1st |
| 8259 // (zero-based) parameter. |
| 8260 expect(type.implicitFunctionTypeIndices, [1]); |
| 8261 expect(type.paramReference, 0); |
| 8262 expect(type.typeArguments, isEmpty); |
| 8263 expect(type.reference, |
| 8264 greaterThanOrEqualTo(unlinkedUnits[0].references.length)); |
| 8265 LinkedReference linkedReference = |
| 8266 linked.units[0].references[type.reference]; |
| 8267 expect(linkedReference.dependency, 0); |
| 8268 expect(linkedReference.kind, ReferenceKind.method); |
| 8269 expect(linkedReference.name, 'f'); |
| 8270 expect(linkedReference.numTypeParameters, 0); |
| 8271 expect(linkedReference.unit, 0); |
| 8272 expect(linkedReference.containingReference, isNot(0)); |
| 8273 expect(linkedReference.containingReference, lessThan(type.reference)); |
| 8274 checkReferenceIndex( |
| 8275 linkedReference.containingReference, absUri('/b.dart'), 'b.dart', 'E'); |
| 8276 } |
| 8277 |
| 8278 test_inferred_type_refers_to_method_function_typed_parameter_type() { |
| 8279 if (!strongMode || skipFullyLinkedData) { |
| 8280 return; |
| 8281 } |
| 8282 UnlinkedClass cls = serializeClassText( |
| 8283 'class C extends D { void f(int x, g) {} }' |
| 8284 ' abstract class D { void f(int x, int g(String s)); }', |
| 8285 className: 'C'); |
| 8286 EntityRef type = |
| 8287 getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot); |
| 8288 // Check that parameter g's inferred type is the type implied by D.f's 1st |
| 8289 // (zero-based) parameter. |
| 8290 expect(type.implicitFunctionTypeIndices, [1]); |
| 8291 expect(type.paramReference, 0); |
| 8292 expect(type.typeArguments, isEmpty); |
| 8293 expect(type.reference, |
| 8294 greaterThanOrEqualTo(unlinkedUnits[0].references.length)); |
| 8295 LinkedReference linkedReference = |
| 8296 linked.units[0].references[type.reference]; |
| 8297 expect(linkedReference.dependency, 0); |
| 8298 expect(linkedReference.kind, ReferenceKind.method); |
| 8299 expect(linkedReference.name, 'f'); |
| 8300 expect(linkedReference.numTypeParameters, 0); |
| 8301 expect(linkedReference.unit, 0); |
| 8302 expect(linkedReference.containingReference, isNot(0)); |
| 8303 expect(linkedReference.containingReference, lessThan(type.reference)); |
| 8304 checkReferenceIndex(linkedReference.containingReference, null, null, 'D'); |
| 8305 } |
| 8306 |
| 8307 test_inferred_type_refers_to_nested_function_typed_param() { |
| 8308 if (!strongMode || skipFullyLinkedData) { |
| 8309 return; |
| 8310 } |
| 8311 UnlinkedVariable v = serializeVariableText(''' |
| 8312 f(void g(int x, void h())) => null; |
| 8313 var v = f((x, y) {}); |
| 8314 '''); |
| 8315 expect(v.initializer.localFunctions, hasLength(1)); |
| 8316 UnlinkedExecutable closure = v.initializer.localFunctions[0]; |
| 8317 expect(closure.parameters, hasLength(2)); |
| 8318 UnlinkedParam y = closure.parameters[1]; |
| 8319 expect(y.name, 'y'); |
| 8320 EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot); |
| 8321 checkLinkedTypeRef(typeRef, null, null, 'f', |
| 8322 expectedKind: ReferenceKind.topLevelFunction); |
| 8323 expect(typeRef.implicitFunctionTypeIndices, [0, 1]); |
| 8324 } |
| 8325 |
| 8326 test_inferred_type_refers_to_nested_function_typed_param_named() { |
| 8327 if (!strongMode || skipFullyLinkedData) { |
| 8328 return; |
| 8329 } |
| 8330 UnlinkedVariable v = serializeVariableText(''' |
| 8331 f({void g(int x, void h())}) => null; |
| 8332 var v = f(g: (x, y) {}); |
| 8333 '''); |
| 8334 expect(v.initializer.localFunctions, hasLength(1)); |
| 8335 UnlinkedExecutable closure = v.initializer.localFunctions[0]; |
| 8336 expect(closure.parameters, hasLength(2)); |
| 8337 UnlinkedParam y = closure.parameters[1]; |
| 8338 expect(y.name, 'y'); |
| 8339 EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot); |
| 8340 checkLinkedTypeRef(typeRef, null, null, 'f', |
| 8341 expectedKind: ReferenceKind.topLevelFunction); |
| 8342 expect(typeRef.implicitFunctionTypeIndices, [0, 1]); |
| 8343 } |
| 8344 |
| 8345 test_inferred_type_refers_to_setter_function_typed_parameter_type() { |
| 8346 if (!strongMode || skipFullyLinkedData) { |
| 8347 return; |
| 8348 } |
| 8349 UnlinkedClass cls = serializeClassText( |
| 8350 'class C extends D { void set f(g) {} }' |
| 8351 ' abstract class D { void set f(int g(String s)); }', |
| 8352 className: 'C'); |
| 8353 EntityRef type = |
| 8354 getTypeRefForSlot(cls.executables[0].parameters[0].inferredTypeSlot); |
| 8355 // Check that parameter g's inferred type is the type implied by D.f's 1st |
| 8356 // (zero-based) parameter. |
| 8357 expect(type.implicitFunctionTypeIndices, [0]); |
| 8358 expect(type.paramReference, 0); |
| 8359 expect(type.typeArguments, isEmpty); |
| 8360 expect(type.reference, |
| 8361 greaterThanOrEqualTo(unlinkedUnits[0].references.length)); |
| 8362 LinkedReference linkedReference = |
| 8363 linked.units[0].references[type.reference]; |
| 8364 expect(linkedReference.dependency, 0); |
| 8365 expect(linkedReference.kind, ReferenceKind.propertyAccessor); |
| 8366 expect(linkedReference.name, 'f='); |
| 8367 expect(linkedReference.numTypeParameters, 0); |
| 8368 expect(linkedReference.unit, 0); |
| 8369 expect(linkedReference.containingReference, isNot(0)); |
| 8370 expect(linkedReference.containingReference, lessThan(type.reference)); |
| 8371 checkReferenceIndex(linkedReference.containingReference, null, null, 'D'); |
| 8372 } |
| 8373 |
| 8374 test_inferred_type_skips_trailing_dynamic() { |
| 8375 if (!strongMode || skipFullyLinkedData) { |
| 8376 return; |
| 8377 } |
| 8378 UnlinkedClass cls = |
| 8379 serializeClassText('class C { final x = <int, dynamic>{}; }'); |
| 8380 EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot); |
| 8381 // Check that x has inferred type `Map<int, dynamic>`. |
| 8382 checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map', |
| 8383 numTypeParameters: 2, numTypeArguments: 2); |
| 8384 checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 8385 checkLinkedDynamicTypeRef(type.typeArguments[1]); |
| 8386 } |
| 8387 |
| 8388 test_inferred_type_skips_unnecessary_dynamic() { |
| 8389 if (!strongMode || skipFullyLinkedData) { |
| 8390 return; |
| 8391 } |
| 8392 UnlinkedClass cls = serializeClassText('class C { final x = []; }'); |
| 8393 EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot); |
| 8394 // Check that x has inferred type `List<dynamic>`. |
| 8395 checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'List', |
| 8396 numTypeParameters: 1, numTypeArguments: 1); |
| 8397 } |
| 8398 |
| 8399 test_initializer_executable_with_bottom_return_type() { |
| 8400 // The synthetic executable for `v` has type `() => Bottom`. |
| 8401 UnlinkedVariable variable = serializeVariableText('int v = null;'); |
| 8402 expect(variable.initializer.returnType, isNull); |
| 8403 checkInferredTypeSlot( |
| 8404 variable.initializer.inferredReturnTypeSlot, null, null, '*bottom*', |
| 8405 onlyInStrongMode: false); |
| 8406 } |
| 8407 |
| 8408 test_initializer_executable_with_imported_return_type() { |
| 8409 addNamedSource('/a.dart', 'class C { D d; } class D {}'); |
| 8410 // The synthetic executable for `v` has type `() => D`; `D` is defined in |
| 8411 // a library that is imported. Note: `v` is mis-typed as `int` to prevent |
| 8412 // type propagation, which would complicate the test. |
| 8413 UnlinkedVariable variable = serializeVariableText( |
| 8414 'import "a.dart"; int v = new C().d;', |
| 8415 allowErrors: true); |
| 8416 expect(variable.initializer.returnType, isNull); |
| 8417 checkInferredTypeSlot(variable.initializer.inferredReturnTypeSlot, |
| 8418 absUri('/a.dart'), 'a.dart', 'D', |
| 8419 onlyInStrongMode: false); |
| 8420 checkHasDependency('a.dart', fullyLinked: false); |
| 8421 } |
| 8422 |
| 8423 test_initializer_executable_with_return_type_from_closure() { |
| 8424 if (skipFullyLinkedData) { |
| 8425 return; |
| 8426 } |
| 8427 // The synthetic executable for `v` has type `() => () => int`, where the |
| 8428 // `() => int` part refers to the closure declared inside the initializer |
| 8429 // for v. Note: `v` is mis-typed as `int` to prevent type propagation, |
| 8430 // which would complicate the test. |
| 8431 UnlinkedVariable variable = |
| 8432 serializeVariableText('int v = () => 0;', allowErrors: true); |
| 8433 EntityRef closureType = |
| 8434 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 8435 checkLinkedTypeRef(closureType, null, null, '', |
| 8436 expectedKind: ReferenceKind.function); |
| 8437 int initializerIndex = |
| 8438 definingUnit.references[closureType.reference].containingReference; |
| 8439 checkReferenceIndex(initializerIndex, null, null, '', |
| 8440 expectedKind: ReferenceKind.function); |
| 8441 int variableIndex = |
| 8442 definingUnit.references[initializerIndex].containingReference; |
| 8443 checkReferenceIndex(variableIndex, null, null, 'v', |
| 8444 expectedKind: ReferenceKind.topLevelPropertyAccessor); |
| 8445 expect(definingUnit.references[variableIndex].containingReference, 0); |
| 8446 } |
| 8447 |
| 8448 test_initializer_executable_with_return_type_from_closure_field() { |
| 8449 if (skipFullyLinkedData) { |
| 8450 return; |
| 8451 } |
| 8452 // The synthetic executable for `v` has type `() => () => int`, where the |
| 8453 // `() => int` part refers to the closure declared inside the initializer |
| 8454 // for v. Note: `v` is mis-typed as `int` to prevent type propagation, |
| 8455 // which would complicate the test. |
| 8456 UnlinkedClass cls = serializeClassText( |
| 8457 ''' |
| 8458 class C { |
| 8459 int v = () => 0; |
| 8460 } |
| 8461 ''', |
| 8462 allowErrors: true); |
| 8463 UnlinkedVariable variable = cls.fields[0]; |
| 8464 EntityRef closureType = |
| 8465 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 8466 checkLinkedTypeRef(closureType, null, null, '', |
| 8467 expectedKind: ReferenceKind.function); |
| 8468 int initializerIndex = |
| 8469 definingUnit.references[closureType.reference].containingReference; |
| 8470 checkReferenceIndex(initializerIndex, null, null, '', |
| 8471 expectedKind: ReferenceKind.function); |
| 8472 int variableIndex = |
| 8473 definingUnit.references[initializerIndex].containingReference; |
| 8474 checkReferenceIndex(variableIndex, null, null, 'v', |
| 8475 expectedKind: ReferenceKind.propertyAccessor); |
| 8476 int classIndex = definingUnit.references[variableIndex].containingReference; |
| 8477 checkReferenceIndex(classIndex, null, null, 'C'); |
| 8478 expect(definingUnit.references[classIndex].containingReference, 0); |
| 8479 } |
| 8480 |
| 8481 test_initializer_executable_with_return_type_from_closure_local() { |
| 8482 if (skipFullyLinkedData) { |
| 8483 return; |
| 8484 } |
| 8485 // The synthetic executable for `v` has type `() => () => int`, where the |
| 8486 // `() => int` part refers to the closure declared inside the initializer |
| 8487 // for v. Note: `v` is mis-typed as `int` to prevent type propagation, |
| 8488 // which would complicate the test. |
| 8489 UnlinkedExecutable executable = serializeExecutableText( |
| 8490 ''' |
| 8491 void f() { |
| 8492 int u = 0; // force the variable below to have index 1 |
| 8493 int v = () => 0; |
| 8494 }''', |
| 8495 allowErrors: true); |
| 8496 UnlinkedVariable variable = executable.localVariables[1]; |
| 8497 EntityRef closureType = |
| 8498 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 8499 checkLinkedTypeRef(closureType, null, null, '', |
| 8500 expectedKind: ReferenceKind.function); |
| 8501 int initializerIndex = |
| 8502 definingUnit.references[closureType.reference].containingReference; |
| 8503 checkReferenceIndex(initializerIndex, null, null, '', |
| 8504 expectedKind: ReferenceKind.function); |
| 8505 int variableIndex = |
| 8506 definingUnit.references[initializerIndex].containingReference; |
| 8507 checkReferenceIndex(variableIndex, null, null, 'v', |
| 8508 expectedKind: ReferenceKind.variable, localIndex: 1); |
| 8509 int topLevelFunctionIndex = |
| 8510 definingUnit.references[variableIndex].containingReference; |
| 8511 checkReferenceIndex(topLevelFunctionIndex, null, null, 'f', |
| 8512 expectedKind: ReferenceKind.topLevelFunction); |
| 8513 expect( |
| 8514 definingUnit.references[topLevelFunctionIndex].containingReference, 0); |
| 8515 } |
| 8516 |
| 8517 test_initializer_executable_with_unimported_return_type() { |
| 8518 addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }'); |
| 8519 addNamedSource('/b.dart', 'class D {}'); |
| 8520 // The synthetic executable for `v` has type `() => D`; `D` is defined in |
| 8521 // a library that is not imported. Note: `v` is mis-typed as `int` to |
| 8522 // prevent type propagation, which would complicate the test. |
| 8523 UnlinkedVariable variable = serializeVariableText( |
| 8524 'import "a.dart"; int v = new C().d;', |
| 8525 allowErrors: true); |
| 8526 expect(variable.initializer.returnType, isNull); |
| 8527 checkInferredTypeSlot(variable.initializer.inferredReturnTypeSlot, |
| 8528 absUri('/b.dart'), 'b.dart', 'D', |
| 8529 onlyInStrongMode: false); |
| 8530 if (!skipFullyLinkedData) { |
| 8531 checkHasDependency('b.dart', fullyLinked: true); |
| 8532 } |
| 8533 } |
| 8534 |
| 8535 test_library_documented() { |
| 8536 String text = ''' |
| 8537 // Extra comment so doc comment offset != 0 |
| 8538 /** |
| 8539 * Docs |
| 8540 */ |
| 8541 library foo;'''; |
| 8542 serializeLibraryText(text); |
| 8543 expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull); |
| 8544 checkDocumentationComment( |
| 8545 unlinkedUnits[0].libraryDocumentationComment, text); |
| 8546 } |
| 8547 |
| 8548 test_library_name_with_spaces() { |
| 8549 String text = 'library foo . bar ;'; |
| 8550 serializeLibraryText(text); |
| 8551 expect(unlinkedUnits[0].libraryName, 'foo.bar'); |
| 8552 expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar')); |
| 8553 expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length); |
| 8554 } |
| 8555 |
| 8556 test_library_named() { |
| 8557 String text = 'library foo.bar;'; |
| 8558 serializeLibraryText(text); |
| 8559 expect(unlinkedUnits[0].libraryName, 'foo.bar'); |
| 8560 expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar')); |
| 8561 expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length); |
| 8562 } |
| 8563 |
| 8564 test_library_unnamed() { |
| 8565 serializeLibraryText(''); |
| 8566 expect(unlinkedUnits[0].libraryName, isEmpty); |
| 8567 expect(unlinkedUnits[0].libraryNameOffset, 0); |
| 8568 expect(unlinkedUnits[0].libraryNameLength, 0); |
| 8569 } |
| 8570 |
| 8571 test_library_with_missing_part() { |
| 8572 // References to other parts should still be resolved. |
| 8573 allowMissingFiles = true; |
| 8574 addNamedSource('/bar.dart', 'part of my.lib; class C {}'); |
| 8575 serializeLibraryText( |
| 8576 'library my.lib; part "foo.dart"; part "bar.dart"; C c;', |
| 8577 allowErrors: true); |
| 8578 checkTypeRef(findVariable('c').type, null, null, 'C', |
| 8579 expectedTargetUnit: 2); |
| 8580 } |
| 8581 |
| 8582 test_lineStarts() { |
| 8583 String text = ''' |
| 8584 int foo; |
| 8585 class Test {} |
| 8586 |
| 8587 int bar;''' |
| 8588 .replaceAll('\r\n', '\n'); |
| 8589 serializeLibraryText(text); |
| 8590 expect(unlinkedUnits[0].lineStarts, [0, 9, 23, 24]); |
| 8591 } |
| 8592 |
| 8593 test_linked_reference_reuse() { |
| 8594 if (!strongMode || skipFullyLinkedData) { |
| 8595 return; |
| 8596 } |
| 8597 // When the reference for a linked type is the same as an explicitly |
| 8598 // referenced type, the explicit reference should be re-used. |
| 8599 addNamedSource('/a.dart', 'class C {}'); |
| 8600 addNamedSource('/b.dart', 'import "a.dart"; C f() => null;'); |
| 8601 serializeLibraryText( |
| 8602 'import "a.dart"; import "b.dart"; C c1; final c2 = f();'); |
| 8603 int explicitReference = findVariable('c1').type.reference; |
| 8604 expect(getTypeRefForSlot(findVariable('c2').inferredTypeSlot).reference, |
| 8605 explicitReference); |
| 8606 } |
| 8607 |
| 8608 test_linked_type_dependency_reuse() { |
| 8609 if (!strongMode || skipFullyLinkedData) { |
| 8610 return; |
| 8611 } |
| 8612 // When the dependency for a linked type is the same as an explicit |
| 8613 // dependency, the explicit dependency should be re-used. |
| 8614 addNamedSource('/a.dart', 'class C {} class D {}'); |
| 8615 addNamedSource('/b.dart', 'import "a.dart"; D f() => null;'); |
| 8616 serializeLibraryText( |
| 8617 'import "a.dart"; import "b.dart"; C c; final d = f();'); |
| 8618 int cReference = findVariable('c').type.reference; |
| 8619 int explicitDependency = linked.units[0].references[cReference].dependency; |
| 8620 int dReference = |
| 8621 getTypeRefForSlot(findVariable('d').inferredTypeSlot).reference; |
| 8622 expect( |
| 8623 linked.units[0].references[dReference].dependency, explicitDependency); |
| 8624 } |
| 8625 |
| 8626 test_local_names_take_precedence_over_imported_names() { |
| 8627 addNamedSource('/a.dart', 'class C {} class D {}'); |
| 8628 serializeLibraryText(''' |
| 8629 import 'a.dart'; |
| 8630 class C {} |
| 8631 C c; |
| 8632 D d;'''); |
| 8633 checkTypeRef(findVariable('c').type, null, null, 'C'); |
| 8634 checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D'); |
| 8635 } |
| 8636 |
| 8637 test_metadata_classDeclaration() { |
| 8638 checkAnnotationA( |
| 8639 serializeClassText('const a = null; @a class C {}').annotations); |
| 8640 } |
| 8641 |
| 8642 test_metadata_classTypeAlias() { |
| 8643 checkAnnotationA(serializeClassText( |
| 8644 'const a = null; @a class C = D with E; class D {} class E {}', |
| 8645 className: 'C') |
| 8646 .annotations); |
| 8647 } |
| 8648 |
| 8649 test_metadata_constructor_call_named() { |
| 8650 UnlinkedClass cls = serializeClassText( |
| 8651 'class A { const A.named(); } @A.named() class C {}'); |
| 8652 expect(cls.annotations, hasLength(1)); |
| 8653 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8654 UnlinkedConstOperation.invokeConstructor, |
| 8655 ], ints: [ |
| 8656 0, |
| 8657 0 |
| 8658 ], referenceValidators: [ |
| 8659 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8660 expectedKind: ReferenceKind.constructor, |
| 8661 prefixExpectations: [ |
| 8662 new _PrefixExpectation(ReferenceKind.classOrEnum, 'A') |
| 8663 ]) |
| 8664 ]); |
| 8665 } |
| 8666 |
| 8667 test_metadata_constructor_call_named_prefixed() { |
| 8668 addNamedSource('/foo.dart', 'class A { const A.named(); }'); |
| 8669 UnlinkedClass cls = serializeClassText( |
| 8670 'import "foo.dart" as foo; @foo.A.named() class C {}'); |
| 8671 expect(cls.annotations, hasLength(1)); |
| 8672 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8673 UnlinkedConstOperation.invokeConstructor, |
| 8674 ], ints: [ |
| 8675 0, |
| 8676 0 |
| 8677 ], referenceValidators: [ |
| 8678 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8679 expectedKind: ReferenceKind.constructor, |
| 8680 prefixExpectations: [ |
| 8681 new _PrefixExpectation(ReferenceKind.classOrEnum, 'A', |
| 8682 absoluteUri: absUri('/foo.dart'), relativeUri: 'foo.dart'), |
| 8683 new _PrefixExpectation(ReferenceKind.prefix, 'foo') |
| 8684 ]) |
| 8685 ]); |
| 8686 } |
| 8687 |
| 8688 test_metadata_constructor_call_named_prefixed_unresolved_class() { |
| 8689 addNamedSource('/foo.dart', ''); |
| 8690 UnlinkedClass cls = serializeClassText( |
| 8691 'import "foo.dart" as foo; @foo.A.named() class C {}', |
| 8692 allowErrors: true); |
| 8693 expect(cls.annotations, hasLength(1)); |
| 8694 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8695 UnlinkedConstOperation.invokeConstructor, |
| 8696 ], ints: [ |
| 8697 0, |
| 8698 0 |
| 8699 ], referenceValidators: [ |
| 8700 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8701 expectedKind: ReferenceKind.unresolved, |
| 8702 prefixExpectations: [ |
| 8703 new _PrefixExpectation(ReferenceKind.unresolved, 'A'), |
| 8704 new _PrefixExpectation(ReferenceKind.prefix, 'foo') |
| 8705 ]) |
| 8706 ]); |
| 8707 } |
| 8708 |
| 8709 test_metadata_constructor_call_named_prefixed_unresolved_constructor() { |
| 8710 addNamedSource('/foo.dart', 'class A {}'); |
| 8711 UnlinkedClass cls = serializeClassText( |
| 8712 'import "foo.dart" as foo; @foo.A.named() class C {}', |
| 8713 allowErrors: true); |
| 8714 expect(cls.annotations, hasLength(1)); |
| 8715 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8716 UnlinkedConstOperation.invokeConstructor, |
| 8717 ], ints: [ |
| 8718 0, |
| 8719 0 |
| 8720 ], referenceValidators: [ |
| 8721 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8722 expectedKind: ReferenceKind.unresolved, |
| 8723 prefixExpectations: [ |
| 8724 new _PrefixExpectation(ReferenceKind.classOrEnum, 'A', |
| 8725 absoluteUri: absUri('/foo.dart'), relativeUri: 'foo.dart'), |
| 8726 new _PrefixExpectation(ReferenceKind.prefix, 'foo') |
| 8727 ]) |
| 8728 ]); |
| 8729 } |
| 8730 |
| 8731 test_metadata_constructor_call_named_unresolved_class() { |
| 8732 UnlinkedClass cls = |
| 8733 serializeClassText('@A.named() class C {}', allowErrors: true); |
| 8734 expect(cls.annotations, hasLength(1)); |
| 8735 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8736 UnlinkedConstOperation.invokeConstructor, |
| 8737 ], ints: [ |
| 8738 0, |
| 8739 0 |
| 8740 ], referenceValidators: [ |
| 8741 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8742 expectedKind: ReferenceKind.unresolved, |
| 8743 prefixExpectations: [ |
| 8744 new _PrefixExpectation(ReferenceKind.unresolved, 'A') |
| 8745 ]) |
| 8746 ]); |
| 8747 } |
| 8748 |
| 8749 test_metadata_constructor_call_named_unresolved_constructor() { |
| 8750 UnlinkedClass cls = serializeClassText('class A {} @A.named() class C {}', |
| 8751 allowErrors: true); |
| 8752 expect(cls.annotations, hasLength(1)); |
| 8753 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8754 UnlinkedConstOperation.invokeConstructor, |
| 8755 ], ints: [ |
| 8756 0, |
| 8757 0 |
| 8758 ], referenceValidators: [ |
| 8759 (EntityRef r) => checkTypeRef(r, null, null, 'named', |
| 8760 expectedKind: ReferenceKind.unresolved, |
| 8761 prefixExpectations: [ |
| 8762 new _PrefixExpectation(ReferenceKind.classOrEnum, 'A') |
| 8763 ]) |
| 8764 ]); |
| 8765 } |
| 8766 |
| 8767 test_metadata_constructor_call_unnamed() { |
| 8768 UnlinkedClass cls = |
| 8769 serializeClassText('class A { const A(); } @A() class C {}'); |
| 8770 expect(cls.annotations, hasLength(1)); |
| 8771 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8772 UnlinkedConstOperation.invokeConstructor, |
| 8773 ], ints: [ |
| 8774 0, |
| 8775 0 |
| 8776 ], referenceValidators: [ |
| 8777 (EntityRef r) => checkTypeRef(r, null, null, 'A', |
| 8778 expectedKind: ReferenceKind.classOrEnum) |
| 8779 ]); |
| 8780 } |
| 8781 |
| 8782 test_metadata_constructor_call_unnamed_prefixed() { |
| 8783 addNamedSource('/foo.dart', 'class A { const A(); }'); |
| 8784 UnlinkedClass cls = |
| 8785 serializeClassText('import "foo.dart" as foo; @foo.A() class C {}'); |
| 8786 expect(cls.annotations, hasLength(1)); |
| 8787 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8788 UnlinkedConstOperation.invokeConstructor, |
| 8789 ], ints: [ |
| 8790 0, |
| 8791 0 |
| 8792 ], referenceValidators: [ |
| 8793 (EntityRef r) => checkTypeRef(r, absUri('/foo.dart'), 'foo.dart', 'A', |
| 8794 expectedKind: ReferenceKind.classOrEnum, expectedPrefix: 'foo') |
| 8795 ]); |
| 8796 } |
| 8797 |
| 8798 test_metadata_constructor_call_unnamed_prefixed_unresolved() { |
| 8799 addNamedSource('/foo.dart', ''); |
| 8800 UnlinkedClass cls = serializeClassText( |
| 8801 'import "foo.dart" as foo; @foo.A() class C {}', |
| 8802 allowErrors: true); |
| 8803 expect(cls.annotations, hasLength(1)); |
| 8804 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8805 UnlinkedConstOperation.invokeConstructor, |
| 8806 ], ints: [ |
| 8807 0, |
| 8808 0 |
| 8809 ], referenceValidators: [ |
| 8810 (EntityRef r) => checkTypeRef(r, null, null, 'A', |
| 8811 expectedKind: ReferenceKind.unresolved, expectedPrefix: 'foo') |
| 8812 ]); |
| 8813 } |
| 8814 |
| 8815 test_metadata_constructor_call_unnamed_unresolved() { |
| 8816 UnlinkedClass cls = |
| 8817 serializeClassText('@A() class C {}', allowErrors: true); |
| 8818 expect(cls.annotations, hasLength(1)); |
| 8819 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8820 UnlinkedConstOperation.invokeConstructor, |
| 8821 ], ints: [ |
| 8822 0, |
| 8823 0 |
| 8824 ], referenceValidators: [ |
| 8825 (EntityRef r) => checkTypeRef(r, null, null, 'A', |
| 8826 expectedKind: ReferenceKind.unresolved) |
| 8827 ]); |
| 8828 } |
| 8829 |
| 8830 test_metadata_constructor_call_with_args() { |
| 8831 UnlinkedClass cls = |
| 8832 serializeClassText('class A { const A(x); } @A(null) class C {}'); |
| 8833 expect(cls.annotations, hasLength(1)); |
| 8834 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8835 UnlinkedConstOperation.pushNull, |
| 8836 UnlinkedConstOperation.invokeConstructor, |
| 8837 ], ints: [ |
| 8838 0, |
| 8839 1 |
| 8840 ], referenceValidators: [ |
| 8841 (EntityRef r) => checkTypeRef(r, null, null, 'A', |
| 8842 expectedKind: ReferenceKind.classOrEnum) |
| 8843 ]); |
| 8844 } |
| 8845 |
| 8846 test_metadata_constructorDeclaration_named() { |
| 8847 checkAnnotationA( |
| 8848 serializeClassText('const a = null; class C { @a C.named(); }') |
| 8849 .executables[0] |
| 8850 .annotations); |
| 8851 } |
| 8852 |
| 8853 test_metadata_constructorDeclaration_unnamed() { |
| 8854 checkAnnotationA(serializeClassText('const a = null; class C { @a C(); }') |
| 8855 .executables[0] |
| 8856 .annotations); |
| 8857 } |
| 8858 |
| 8859 test_metadata_enumDeclaration() { |
| 8860 checkAnnotationA( |
| 8861 serializeEnumText('const a = null; @a enum E { v }').annotations); |
| 8862 } |
| 8863 |
| 8864 test_metadata_exportDirective() { |
| 8865 addNamedSource('/foo.dart', ''); |
| 8866 serializeLibraryText('@a export "foo.dart"; const a = null;'); |
| 8867 checkAnnotationA(unlinkedUnits[0].exports[0].annotations); |
| 8868 } |
| 8869 |
| 8870 test_metadata_fieldDeclaration() { |
| 8871 checkAnnotationA(serializeClassText('const a = null; class C { @a int x; }') |
| 8872 .fields[0] |
| 8873 .annotations); |
| 8874 } |
| 8875 |
| 8876 test_metadata_fieldFormalParameter() { |
| 8877 checkAnnotationA( |
| 8878 serializeClassText('const a = null; class C { var x; C(@a this.x); }') |
| 8879 .executables[0] |
| 8880 .parameters[0] |
| 8881 .annotations); |
| 8882 } |
| 8883 |
| 8884 test_metadata_fieldFormalParameter_withDefault() { |
| 8885 checkAnnotationA(serializeClassText( |
| 8886 'const a = null; class C { var x; C([@a this.x = null]); }') |
| 8887 .executables[0] |
| 8888 .parameters[0] |
| 8889 .annotations); |
| 8890 } |
| 8891 |
| 8892 test_metadata_functionDeclaration_function() { |
| 8893 checkAnnotationA( |
| 8894 serializeExecutableText('const a = null; @a f() {}').annotations); |
| 8895 } |
| 8896 |
| 8897 test_metadata_functionDeclaration_getter() { |
| 8898 checkAnnotationA( |
| 8899 serializeExecutableText('const a = null; @a get f => null;') |
| 8900 .annotations); |
| 8901 } |
| 8902 |
| 8903 test_metadata_functionDeclaration_setter() { |
| 8904 checkAnnotationA(serializeExecutableText( |
| 8905 'const a = null; @a set f(value) {}', |
| 8906 executableName: 'f=') |
| 8907 .annotations); |
| 8908 } |
| 8909 |
| 8910 test_metadata_functionTypeAlias() { |
| 8911 checkAnnotationA( |
| 8912 serializeTypedefText('const a = null; @a typedef F();').annotations); |
| 8913 } |
| 8914 |
| 8915 test_metadata_functionTypedFormalParameter() { |
| 8916 checkAnnotationA(serializeExecutableText('const a = null; f(@a g()) {}') |
| 8917 .parameters[0] |
| 8918 .annotations); |
| 8919 } |
| 8920 |
| 8921 test_metadata_functionTypedFormalParameter_withDefault() { |
| 8922 checkAnnotationA( |
| 8923 serializeExecutableText('const a = null; f([@a g() = null]) {}') |
| 8924 .parameters[0] |
| 8925 .annotations); |
| 8926 } |
| 8927 |
| 8928 test_metadata_importDirective() { |
| 8929 addNamedSource('/foo.dart', 'const b = null;'); |
| 8930 serializeLibraryText('@a import "foo.dart"; const a = b;'); |
| 8931 checkAnnotationA(unlinkedUnits[0].imports[0].annotations); |
| 8932 } |
| 8933 |
| 8934 test_metadata_libraryDirective() { |
| 8935 serializeLibraryText('@a library L; const a = null;'); |
| 8936 checkAnnotationA(unlinkedUnits[0].libraryAnnotations); |
| 8937 } |
| 8938 |
| 8939 test_metadata_methodDeclaration_getter() { |
| 8940 checkAnnotationA( |
| 8941 serializeClassText('const a = null; class C { @a get m => null; }') |
| 8942 .executables[0] |
| 8943 .annotations); |
| 8944 } |
| 8945 |
| 8946 test_metadata_methodDeclaration_method() { |
| 8947 checkAnnotationA(serializeClassText('const a = null; class C { @a m() {} }') |
| 8948 .executables[0] |
| 8949 .annotations); |
| 8950 } |
| 8951 |
| 8952 test_metadata_methodDeclaration_setter() { |
| 8953 checkAnnotationA( |
| 8954 serializeClassText('const a = null; class C { @a set m(value) {} }') |
| 8955 .executables[0] |
| 8956 .annotations); |
| 8957 } |
| 8958 |
| 8959 test_metadata_multiple_annotations() { |
| 8960 UnlinkedClass cls = |
| 8961 serializeClassText('const a = null, b = null; @a @b class C {}'); |
| 8962 List<UnlinkedConst> annotations = cls.annotations; |
| 8963 expect(annotations, hasLength(2)); |
| 8964 _assertUnlinkedConst(annotations[0], operators: [ |
| 8965 UnlinkedConstOperation.pushReference |
| 8966 ], referenceValidators: [ |
| 8967 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 8968 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 8969 ]); |
| 8970 _assertUnlinkedConst(annotations[1], operators: [ |
| 8971 UnlinkedConstOperation.pushReference |
| 8972 ], referenceValidators: [ |
| 8973 (EntityRef r) => checkTypeRef(r, null, null, 'b', |
| 8974 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 8975 ]); |
| 8976 } |
| 8977 |
| 8978 test_metadata_partDirective() { |
| 8979 addNamedSource('/foo.dart', 'part of L;'); |
| 8980 serializeLibraryText('library L; @a part "foo.dart"; const a = null;'); |
| 8981 checkAnnotationA(unlinkedUnits[0].parts[0].annotations); |
| 8982 } |
| 8983 |
| 8984 test_metadata_prefixed_variable() { |
| 8985 addNamedSource('/a.dart', 'const b = null;'); |
| 8986 UnlinkedClass cls = |
| 8987 serializeClassText('import "a.dart" as a; @a.b class C {}'); |
| 8988 expect(cls.annotations, hasLength(1)); |
| 8989 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 8990 UnlinkedConstOperation.pushReference |
| 8991 ], referenceValidators: [ |
| 8992 (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'b', |
| 8993 expectedKind: ReferenceKind.topLevelPropertyAccessor, |
| 8994 expectedPrefix: 'a') |
| 8995 ]); |
| 8996 } |
| 8997 |
| 8998 test_metadata_prefixed_variable_unresolved() { |
| 8999 addNamedSource('/a.dart', ''); |
| 9000 UnlinkedClass cls = serializeClassText( |
| 9001 'import "a.dart" as a; @a.b class C {}', |
| 9002 allowErrors: true); |
| 9003 expect(cls.annotations, hasLength(1)); |
| 9004 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 9005 UnlinkedConstOperation.pushReference |
| 9006 ], referenceValidators: [ |
| 9007 (EntityRef r) => checkTypeRef(r, null, null, 'b', |
| 9008 expectedKind: ReferenceKind.unresolved, expectedPrefix: 'a') |
| 9009 ]); |
| 9010 } |
| 9011 |
| 9012 test_metadata_simpleFormalParameter() { |
| 9013 checkAnnotationA(serializeExecutableText('const a = null; f(@a x) {}') |
| 9014 .parameters[0] |
| 9015 .annotations); |
| 9016 } |
| 9017 |
| 9018 test_metadata_simpleFormalParameter_withDefault() { |
| 9019 checkAnnotationA( |
| 9020 serializeExecutableText('const a = null; f([@a x = null]) {}') |
| 9021 .parameters[0] |
| 9022 .annotations); |
| 9023 } |
| 9024 |
| 9025 test_metadata_topLevelVariableDeclaration() { |
| 9026 checkAnnotationA( |
| 9027 serializeVariableText('const a = null; @a int v;').annotations); |
| 9028 } |
| 9029 |
| 9030 test_metadata_typeParameter_ofClass() { |
| 9031 checkAnnotationA(serializeClassText('const a = null; class C<@a T> {}') |
| 9032 .typeParameters[0] |
| 9033 .annotations); |
| 9034 } |
| 9035 |
| 9036 test_metadata_typeParameter_ofClassTypeAlias() { |
| 9037 checkAnnotationA(serializeClassText( |
| 9038 'const a = null; class C<@a T> = D with E; class D {} class E {}', |
| 9039 className: 'C') |
| 9040 .typeParameters[0] |
| 9041 .annotations); |
| 9042 } |
| 9043 |
| 9044 test_metadata_typeParameter_ofFunction() { |
| 9045 checkAnnotationA(serializeExecutableText('const a = null; f<@a T>() {}') |
| 9046 .typeParameters[0] |
| 9047 .annotations); |
| 9048 } |
| 9049 |
| 9050 test_metadata_typeParameter_ofTypedef() { |
| 9051 checkAnnotationA(serializeTypedefText('const a = null; typedef F<@a T>();') |
| 9052 .typeParameters[0] |
| 9053 .annotations); |
| 9054 } |
| 9055 |
| 9056 test_metadata_variable_unresolved() { |
| 9057 UnlinkedClass cls = serializeClassText('@a class C {}', allowErrors: true); |
| 9058 expect(cls.annotations, hasLength(1)); |
| 9059 _assertUnlinkedConst(cls.annotations[0], operators: [ |
| 9060 UnlinkedConstOperation.pushReference |
| 9061 ], referenceValidators: [ |
| 9062 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 9063 expectedKind: ReferenceKind.unresolved) |
| 9064 ]); |
| 9065 } |
| 9066 |
| 9067 test_method_documented() { |
| 9068 String text = ''' |
| 9069 class C { |
| 9070 /** |
| 9071 * Docs |
| 9072 */ |
| 9073 f() {} |
| 9074 }'''; |
| 9075 UnlinkedExecutable executable = serializeClassText(text).executables[0]; |
| 9076 expect(executable.documentationComment, isNotNull); |
| 9077 checkDocumentationComment(executable.documentationComment, text); |
| 9078 } |
| 9079 |
| 9080 test_method_inferred_type_nonstatic_explicit_param() { |
| 9081 UnlinkedExecutable f = serializeClassText( |
| 9082 'class C extends D { void f(num value) {} }' |
| 9083 ' abstract class D { void f(int value); }', |
| 9084 className: 'C') |
| 9085 .executables[0]; |
| 9086 expect(f.parameters[0].inferredTypeSlot, 0); |
| 9087 } |
| 9088 |
| 9089 test_method_inferred_type_nonstatic_explicit_return() { |
| 9090 UnlinkedExecutable f = serializeClassText( |
| 9091 'class C extends D { num f() => null; } abstract class D { int f();
}', |
| 9092 className: 'C', |
| 9093 allowErrors: true) |
| 9094 .executables[0]; |
| 9095 expect(f.inferredReturnTypeSlot, 0); |
| 9096 } |
| 9097 |
| 9098 test_method_inferred_type_nonstatic_implicit_param() { |
| 9099 UnlinkedExecutable f = serializeClassText( |
| 9100 'class C extends D { void f(value) {} }' |
| 9101 ' abstract class D { void f(int value); }', |
| 9102 className: 'C') |
| 9103 .executables[0]; |
| 9104 checkInferredTypeSlot( |
| 9105 f.parameters[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 9106 } |
| 9107 |
| 9108 test_method_inferred_type_nonstatic_implicit_return() { |
| 9109 UnlinkedExecutable f = serializeClassText( |
| 9110 'class C extends D { f() => null; } abstract class D { int f(); }', |
| 9111 className: 'C') |
| 9112 .executables[0]; |
| 9113 checkInferredTypeSlot( |
| 9114 f.inferredReturnTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 9115 } |
| 9116 |
| 9117 test_method_inferred_type_static_implicit_param() { |
| 9118 UnlinkedExecutable f = serializeClassText( |
| 9119 'class C extends D { static void f(value) {} }' |
| 9120 ' class D { static void f(int value) {} }', |
| 9121 className: 'C') |
| 9122 .executables[0]; |
| 9123 expect(f.parameters[0].inferredTypeSlot, 0); |
| 9124 } |
| 9125 |
| 9126 test_method_inferred_type_static_implicit_return() { |
| 9127 UnlinkedExecutable f = serializeClassText( |
| 9128 'class C extends D { static f() => null; }' |
| 9129 ' class D { static int f() => null; }', |
| 9130 className: 'C') |
| 9131 .executables[0]; |
| 9132 expect(f.inferredReturnTypeSlot, 0); |
| 9133 } |
| 9134 |
| 9135 test_nested_generic_functions() { |
| 9136 UnlinkedExecutable executable = serializeExecutableText(''' |
| 9137 void f<T, U>() { |
| 9138 void g<V, W>() { |
| 9139 void h<X, Y>() { |
| 9140 T t; |
| 9141 U u; |
| 9142 V v; |
| 9143 W w; |
| 9144 X x; |
| 9145 Y y; |
| 9146 } |
| 9147 } |
| 9148 } |
| 9149 '''); |
| 9150 expect(executable.typeParameters, hasLength(2)); |
| 9151 expect(executable.localFunctions[0].typeParameters, hasLength(2)); |
| 9152 expect(executable.localFunctions[0].localFunctions[0].typeParameters, |
| 9153 hasLength(2)); |
| 9154 List<UnlinkedVariable> localVariables = |
| 9155 executable.localFunctions[0].localFunctions[0].localVariables; |
| 9156 checkParamTypeRef(findVariable('t', variables: localVariables).type, 6); |
| 9157 checkParamTypeRef(findVariable('u', variables: localVariables).type, 5); |
| 9158 checkParamTypeRef(findVariable('v', variables: localVariables).type, 4); |
| 9159 checkParamTypeRef(findVariable('w', variables: localVariables).type, 3); |
| 9160 checkParamTypeRef(findVariable('x', variables: localVariables).type, 2); |
| 9161 checkParamTypeRef(findVariable('y', variables: localVariables).type, 1); |
| 9162 } |
| 9163 |
| 9164 test_nested_generic_functions_in_generic_class() { |
| 9165 UnlinkedClass cls = serializeClassText(''' |
| 9166 class C<T, U> { |
| 9167 void g<V, W>() { |
| 9168 void h<X, Y>() { |
| 9169 T t; |
| 9170 U u; |
| 9171 V v; |
| 9172 W w; |
| 9173 X x; |
| 9174 Y y; |
| 9175 } |
| 9176 } |
| 9177 } |
| 9178 '''); |
| 9179 expect(cls.typeParameters, hasLength(2)); |
| 9180 expect(cls.executables[0].typeParameters, hasLength(2)); |
| 9181 expect(cls.executables[0].localFunctions[0].typeParameters, hasLength(2)); |
| 9182 List<UnlinkedVariable> localVariables = |
| 9183 cls.executables[0].localFunctions[0].localVariables; |
| 9184 checkParamTypeRef(findVariable('t', variables: localVariables).type, 6); |
| 9185 checkParamTypeRef(findVariable('u', variables: localVariables).type, 5); |
| 9186 checkParamTypeRef(findVariable('v', variables: localVariables).type, 4); |
| 9187 checkParamTypeRef(findVariable('w', variables: localVariables).type, 3); |
| 9188 checkParamTypeRef(findVariable('x', variables: localVariables).type, 2); |
| 9189 checkParamTypeRef(findVariable('y', variables: localVariables).type, 1); |
| 9190 } |
| 9191 |
| 9192 test_parameter_visibleRange_abstractMethod() { |
| 9193 UnlinkedExecutable m = findExecutable('m', |
| 9194 executables: |
| 9195 serializeClassText('abstract class C { m(p); }').executables, |
| 9196 failIfAbsent: true); |
| 9197 _assertParameterZeroVisibleRange(m.parameters[0]); |
| 9198 } |
| 9199 |
| 9200 test_parameter_visibleRange_function_blockBody() { |
| 9201 String text = r''' |
| 9202 f(x) { // 1 |
| 9203 f2(y) { // 2 |
| 9204 } // 3 |
| 9205 } // 4 |
| 9206 '''; |
| 9207 UnlinkedExecutable f = serializeExecutableText(text); |
| 9208 UnlinkedExecutable f2 = f.localFunctions[0]; |
| 9209 _assertParameterVisible(text, f.parameters[0], '{ // 1', '} // 4'); |
| 9210 _assertParameterVisible(text, f2.parameters[0], '{ // 2', '} // 3'); |
| 9211 } |
| 9212 |
| 9213 test_parameter_visibleRange_function_emptyBody() { |
| 9214 UnlinkedExecutable f = serializeExecutableText('external f(x);'); |
| 9215 _assertParameterZeroVisibleRange(f.parameters[0]); |
| 9216 } |
| 9217 |
| 9218 test_parameter_visibleRange_function_expressionBody() { |
| 9219 String text = r''' |
| 9220 f(x) => 42; |
| 9221 '''; |
| 9222 UnlinkedExecutable f = serializeExecutableText(text); |
| 9223 _assertParameterVisible(text, f.parameters[0], '=>', ';'); |
| 9224 } |
| 9225 |
| 9226 test_parameter_visibleRange_inFunctionTypedParameter() { |
| 9227 String text = 'f(g(p)) {}'; |
| 9228 UnlinkedExecutable f = serializeExecutableText(text); |
| 9229 UnlinkedParam g = f.parameters[0]; |
| 9230 UnlinkedParam p = g.parameters[0]; |
| 9231 expect(g.name, 'g'); |
| 9232 expect(p.name, 'p'); |
| 9233 _assertParameterVisible(text, g, '{', '}'); |
| 9234 _assertParameterZeroVisibleRange(p); |
| 9235 } |
| 9236 |
| 9237 test_parameter_visibleRange_typedef() { |
| 9238 UnlinkedTypedef type = serializeTypedefText('typedef F(x);'); |
| 9239 _assertParameterZeroVisibleRange(type.parameters[0]); |
| 9240 } |
| 9241 |
| 9242 test_part_declaration() { |
| 9243 addNamedSource('/a.dart', 'part of my.lib;'); |
| 9244 String text = 'library my.lib; part "a.dart"; // <-part'; |
| 9245 serializeLibraryText(text); |
| 9246 expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1)); |
| 9247 expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart'); |
| 9248 expect(unlinkedUnits[0].parts, hasLength(1)); |
| 9249 expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"')); |
| 9250 expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part')); |
| 9251 } |
| 9252 |
| 9253 test_parts_defining_compilation_unit() { |
| 9254 serializeLibraryText(''); |
| 9255 expect(linked.units, hasLength(1)); |
| 9256 expect(unlinkedUnits[0].publicNamespace.parts, isEmpty); |
| 9257 } |
| 9258 |
| 9259 test_parts_included() { |
| 9260 addNamedSource('/part1.dart', 'part of my.lib;'); |
| 9261 String partString = '"part1.dart"'; |
| 9262 String libraryText = 'library my.lib; part $partString;'; |
| 9263 serializeLibraryText(libraryText); |
| 9264 expect(linked.units, hasLength(2)); |
| 9265 expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1)); |
| 9266 expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart'); |
| 9267 } |
| 9268 |
| 9269 test_public_namespace_of_part() { |
| 9270 addNamedSource('/a.dart', 'part of foo; class C {}'); |
| 9271 serializeLibraryText('library foo; part "a.dart";'); |
| 9272 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 9273 expect(unlinkedUnits[1].publicNamespace.names, hasLength(1)); |
| 9274 expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C'); |
| 9275 } |
| 9276 |
| 9277 test_reference_zero() { |
| 9278 // Element zero of the references table should be populated in a standard |
| 9279 // way. |
| 9280 serializeLibraryText(''); |
| 9281 UnlinkedReference unlinkedReference0 = unlinkedUnits[0].references[0]; |
| 9282 expect(unlinkedReference0.name, ''); |
| 9283 expect(unlinkedReference0.prefixReference, 0); |
| 9284 LinkedReference linkedReference0 = linked.units[0].references[0]; |
| 9285 expect(linkedReference0.containingReference, 0); |
| 9286 expect(linkedReference0.dependency, 0); |
| 9287 expect(linkedReference0.kind, ReferenceKind.unresolved); |
| 9288 expect(linkedReference0.localIndex, 0); |
| 9289 expect(linkedReference0.name, ''); |
| 9290 expect(linkedReference0.numTypeParameters, 0); |
| 9291 expect(linkedReference0.unit, 0); |
| 9292 } |
| 9293 |
| 9294 test_setter_documented() { |
| 9295 String text = ''' |
| 9296 // Extra comment so doc comment offset != 0 |
| 9297 /** |
| 9298 * Docs |
| 9299 */ |
| 9300 void set f(value) {}'''; |
| 9301 UnlinkedExecutable executable = |
| 9302 serializeExecutableText(text, executableName: 'f='); |
| 9303 expect(executable.documentationComment, isNotNull); |
| 9304 checkDocumentationComment(executable.documentationComment, text); |
| 9305 } |
| 9306 |
| 9307 test_setter_inferred_type_nonstatic_explicit_param() { |
| 9308 UnlinkedExecutable f = serializeClassText( |
| 9309 'class C extends D { void set f(num value) {} }' |
| 9310 ' abstract class D { void set f(int value); }', |
| 9311 className: 'C') |
| 9312 .executables[0]; |
| 9313 expect(f.parameters[0].inferredTypeSlot, 0); |
| 9314 } |
| 9315 |
| 9316 test_setter_inferred_type_nonstatic_explicit_return() { |
| 9317 UnlinkedExecutable f = |
| 9318 serializeClassText('class C { void set f(int value) {} }').executables[ |
| 9319 0]; |
| 9320 expect(f.inferredReturnTypeSlot, 0); |
| 9321 } |
| 9322 |
| 9323 test_setter_inferred_type_nonstatic_implicit_param() { |
| 9324 UnlinkedExecutable f = serializeClassText( |
| 9325 'class C extends D { void set f(value) {} }' |
| 9326 ' abstract class D { void set f(int value); }', |
| 9327 className: 'C') |
| 9328 .executables[0]; |
| 9329 checkInferredTypeSlot( |
| 9330 f.parameters[0].inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 9331 } |
| 9332 |
| 9333 test_setter_inferred_type_nonstatic_implicit_return() { |
| 9334 UnlinkedExecutable f = |
| 9335 serializeClassText('class C { set f(int value) {} }').executables[0]; |
| 9336 checkInferredTypeSlot(f.inferredReturnTypeSlot, null, null, 'void'); |
| 9337 } |
| 9338 |
| 9339 test_setter_inferred_type_static_implicit_param() { |
| 9340 UnlinkedExecutable f = serializeClassText( |
| 9341 'class C extends D { static void set f(value) {} }' |
| 9342 ' class D { static void set f(int value) {} }', |
| 9343 className: 'C') |
| 9344 .executables[0]; |
| 9345 expect(f.parameters[0].inferredTypeSlot, 0); |
| 9346 } |
| 9347 |
| 9348 test_setter_inferred_type_static_implicit_return() { |
| 9349 UnlinkedExecutable f = |
| 9350 serializeClassText('class C { static set f(int value) {} }') |
| 9351 .executables[0]; |
| 9352 expect(f.inferredReturnTypeSlot, 0); |
| 9353 } |
| 9354 |
| 9355 test_setter_inferred_type_top_level_implicit_param() { |
| 9356 UnlinkedExecutable f = |
| 9357 serializeExecutableText('void set f(value) {}', executableName: 'f='); |
| 9358 expect(f.parameters[0].inferredTypeSlot, 0); |
| 9359 } |
| 9360 |
| 9361 test_setter_inferred_type_top_level_implicit_return() { |
| 9362 UnlinkedExecutable f = |
| 9363 serializeExecutableText('set f(int value) {}', executableName: 'f='); |
| 9364 expect(f.inferredReturnTypeSlot, 0); |
| 9365 } |
| 9366 |
| 9367 test_slot_reuse() { |
| 9368 // Different compilation units have independent notions of slot id, so slot |
| 9369 // ids should be reused. |
| 9370 addNamedSource('/a.dart', 'part of foo; final v = 0;'); |
| 9371 serializeLibraryText('library foo; part "a.dart"; final w = 0;'); |
| 9372 expect(unlinkedUnits[1].variables[0].inferredTypeSlot, |
| 9373 unlinkedUnits[0].variables[0].inferredTypeSlot); |
| 9374 } |
| 9375 |
| 9376 test_syntheticFunctionType_genericClosure() { |
| 9377 if (skipFullyLinkedData) { |
| 9378 return; |
| 9379 } |
| 9380 if (!strongMode) { |
| 9381 // The test below uses generic comment syntax because proper generic |
| 9382 // method syntax doesn't support generic closures. So it can only run in |
| 9383 // strong mode. |
| 9384 // TODO(paulberry): once proper generic method syntax supports generic |
| 9385 // closures, rewrite the test below without using generic comment syntax, |
| 9386 // and remove this hack. See dartbug.com/25819 |
| 9387 return; |
| 9388 } |
| 9389 UnlinkedVariable variable = serializeVariableText(''' |
| 9390 final v = f() ? /*<T>*/(T t) => 0 : /*<T>*/(T t) => 1; |
| 9391 bool f() => true; |
| 9392 '''); |
| 9393 EntityRef inferredType = getTypeRefForSlot(variable.inferredTypeSlot); |
| 9394 checkLinkedTypeRef( |
| 9395 inferredType.syntheticReturnType, 'dart:core', 'dart:core', 'int'); |
| 9396 expect(inferredType.syntheticParams, hasLength(1)); |
| 9397 checkLinkedTypeRef( |
| 9398 inferredType.syntheticParams[0].type, null, null, '*bottom*'); |
| 9399 } |
| 9400 |
| 9401 test_syntheticFunctionType_genericClosure_inGenericFunction() { |
| 9402 if (skipFullyLinkedData) { |
| 9403 return; |
| 9404 } |
| 9405 if (!strongMode) { |
| 9406 // The test below uses generic comment syntax because proper generic |
| 9407 // method syntax doesn't support generic closures. So it can only run in |
| 9408 // strong mode. |
| 9409 // TODO(paulberry): once proper generic method syntax supports generic |
| 9410 // closures, rewrite the test below without using generic comment syntax, |
| 9411 // and remove this hack. See dartbug.com/25819 |
| 9412 return; |
| 9413 } |
| 9414 UnlinkedVariable variable = serializeExecutableText(''' |
| 9415 void f<T, U>(bool b) { |
| 9416 final v = b ? /*<V>*/(T t, U u, V v) => 0 : /*<V>*/(T t, U u, V v) => 1; |
| 9417 } |
| 9418 ''').localVariables[0]; |
| 9419 EntityRef inferredType = getTypeRefForSlot(variable.inferredTypeSlot); |
| 9420 checkLinkedTypeRef( |
| 9421 inferredType.syntheticReturnType, 'dart:core', 'dart:core', 'int'); |
| 9422 expect(inferredType.syntheticParams, hasLength(3)); |
| 9423 checkParamTypeRef(inferredType.syntheticParams[0].type, 2); |
| 9424 checkParamTypeRef(inferredType.syntheticParams[1].type, 1); |
| 9425 checkLinkedTypeRef( |
| 9426 inferredType.syntheticParams[2].type, null, null, '*bottom*'); |
| 9427 } |
| 9428 |
| 9429 test_syntheticFunctionType_inGenericClass() { |
| 9430 if (skipFullyLinkedData) { |
| 9431 return; |
| 9432 } |
| 9433 UnlinkedVariable variable = serializeClassText(''' |
| 9434 class C<T, U> { |
| 9435 var v = f() ? (T t, U u) => 0 : (T t, U u) => 1; |
| 9436 } |
| 9437 bool f() => false; |
| 9438 ''').fields[0]; |
| 9439 EntityRef inferredType = |
| 9440 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 9441 checkLinkedTypeRef( |
| 9442 inferredType.syntheticReturnType, 'dart:core', 'dart:core', 'int'); |
| 9443 checkParamTypeRef(inferredType.syntheticParams[0].type, 2); |
| 9444 checkParamTypeRef(inferredType.syntheticParams[1].type, 1); |
| 9445 } |
| 9446 |
| 9447 test_syntheticFunctionType_inGenericFunction() { |
| 9448 if (skipFullyLinkedData) { |
| 9449 return; |
| 9450 } |
| 9451 UnlinkedVariable variable = serializeExecutableText(''' |
| 9452 void f<T, U>(bool b) { |
| 9453 var v = b ? (T t, U u) => 0 : (T t, U u) => 1; |
| 9454 } |
| 9455 ''').localVariables[0]; |
| 9456 EntityRef inferredType = |
| 9457 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 9458 checkLinkedTypeRef( |
| 9459 inferredType.syntheticReturnType, 'dart:core', 'dart:core', 'int'); |
| 9460 checkParamTypeRef(inferredType.syntheticParams[0].type, 2); |
| 9461 checkParamTypeRef(inferredType.syntheticParams[1].type, 1); |
| 9462 } |
| 9463 |
| 9464 test_type_arguments_explicit() { |
| 9465 EntityRef typeRef = serializeTypeText('List<int>'); |
| 9466 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 9467 numTypeParameters: 1, numTypeArguments: 1); |
| 9468 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 9469 } |
| 9470 |
| 9471 test_type_arguments_explicit_dynamic() { |
| 9472 EntityRef typeRef = serializeTypeText('List<dynamic>'); |
| 9473 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 9474 numTypeParameters: 1, numTypeArguments: 1); |
| 9475 checkDynamicTypeRef(typeRef.typeArguments[0]); |
| 9476 } |
| 9477 |
| 9478 test_type_arguments_explicit_dynamic_dynamic() { |
| 9479 EntityRef typeRef = serializeTypeText('Map<dynamic, dynamic>'); |
| 9480 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 9481 numTypeParameters: 2, numTypeArguments: 2); |
| 9482 checkDynamicTypeRef(typeRef.typeArguments[0]); |
| 9483 checkDynamicTypeRef(typeRef.typeArguments[1]); |
| 9484 } |
| 9485 |
| 9486 test_type_arguments_explicit_dynamic_int() { |
| 9487 EntityRef typeRef = serializeTypeText('Map<dynamic, int>'); |
| 9488 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 9489 numTypeParameters: 2, numTypeArguments: 2); |
| 9490 checkDynamicTypeRef(typeRef.typeArguments[0]); |
| 9491 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int'); |
| 9492 } |
| 9493 |
| 9494 test_type_arguments_explicit_dynamic_typedef() { |
| 9495 EntityRef typeRef = |
| 9496 serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();'); |
| 9497 checkTypeRef(typeRef, null, null, 'F', |
| 9498 expectedKind: ReferenceKind.typedef, |
| 9499 numTypeParameters: 1, |
| 9500 numTypeArguments: 1); |
| 9501 checkDynamicTypeRef(typeRef.typeArguments[0]); |
| 9502 } |
| 9503 |
| 9504 test_type_arguments_explicit_String_dynamic() { |
| 9505 EntityRef typeRef = serializeTypeText('Map<String, dynamic>'); |
| 9506 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 9507 numTypeParameters: 2, numTypeArguments: 2); |
| 9508 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String'); |
| 9509 checkDynamicTypeRef(typeRef.typeArguments[1]); |
| 9510 } |
| 9511 |
| 9512 test_type_arguments_explicit_String_int() { |
| 9513 EntityRef typeRef = serializeTypeText('Map<String, int>'); |
| 9514 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 9515 numTypeParameters: 2, numTypeArguments: 2); |
| 9516 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String'); |
| 9517 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int'); |
| 9518 } |
| 9519 |
| 9520 test_type_arguments_explicit_typedef() { |
| 9521 EntityRef typeRef = |
| 9522 serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();'); |
| 9523 checkTypeRef(typeRef, null, null, 'F', |
| 9524 expectedKind: ReferenceKind.typedef, |
| 9525 numTypeParameters: 1, |
| 9526 numTypeArguments: 1); |
| 9527 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 9528 } |
| 9529 |
| 9530 test_type_arguments_implicit() { |
| 9531 EntityRef typeRef = serializeTypeText('List'); |
| 9532 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List', |
| 9533 numTypeParameters: 1); |
| 9534 } |
| 9535 |
| 9536 test_type_arguments_implicit_typedef() { |
| 9537 EntityRef typeRef = |
| 9538 serializeTypeText('F', otherDeclarations: 'typedef T F<T>();'); |
| 9539 checkTypeRef(typeRef, null, null, 'F', |
| 9540 expectedKind: ReferenceKind.typedef, numTypeParameters: 1); |
| 9541 } |
| 9542 |
| 9543 test_type_arguments_implicit_typedef_withBound() { |
| 9544 EntityRef typeRef = serializeTypeText('F', |
| 9545 otherDeclarations: 'typedef T F<T extends num>();'); |
| 9546 checkTypeRef(typeRef, null, null, 'F', |
| 9547 expectedKind: ReferenceKind.typedef, numTypeParameters: 1); |
| 9548 } |
| 9549 |
| 9550 test_type_arguments_order() { |
| 9551 EntityRef typeRef = serializeTypeText('Map<int, Object>'); |
| 9552 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map', |
| 9553 numTypeParameters: 2, numTypeArguments: 2); |
| 9554 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 9555 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object'); |
| 9556 } |
| 9557 |
| 9558 test_type_dynamic() { |
| 9559 checkDynamicTypeRef(serializeTypeText('dynamic')); |
| 9560 } |
| 9561 |
| 9562 test_type_param_codeRange() { |
| 9563 UnlinkedClass cls = |
| 9564 serializeClassText('class A {} class C<T extends A> {}'); |
| 9565 UnlinkedTypeParam typeParameter = cls.typeParameters[0]; |
| 9566 _assertCodeRange(typeParameter.codeRange, 19, 11); |
| 9567 } |
| 9568 |
| 9569 test_type_param_not_shadowed_by_constructor() { |
| 9570 UnlinkedClass cls = |
| 9571 serializeClassText('class C<D> { D x; C.D(); } class D {}'); |
| 9572 checkParamTypeRef(cls.fields[0].type, 1); |
| 9573 } |
| 9574 |
| 9575 test_type_param_not_shadowed_by_field_in_extends() { |
| 9576 UnlinkedClass cls = |
| 9577 serializeClassText('class C<T> extends D<T> { T x; } class D<T> {}'); |
| 9578 checkParamTypeRef(cls.supertype.typeArguments[0], 1); |
| 9579 } |
| 9580 |
| 9581 test_type_param_not_shadowed_by_field_in_implements() { |
| 9582 UnlinkedClass cls = |
| 9583 serializeClassText('class C<T> implements D<T> { T x; } class D<T> {}'); |
| 9584 checkParamTypeRef(cls.interfaces[0].typeArguments[0], 1); |
| 9585 } |
| 9586 |
| 9587 test_type_param_not_shadowed_by_field_in_with() { |
| 9588 UnlinkedClass cls = serializeClassText( |
| 9589 'class C<T> extends Object with D<T> { T x; } class D<T> {}'); |
| 9590 checkParamTypeRef(cls.mixins[0].typeArguments[0], 1); |
| 9591 } |
| 9592 |
| 9593 test_type_param_not_shadowed_by_method_parameter() { |
| 9594 UnlinkedClass cls = serializeClassText('class C<T> { f(int T, T x) {} }'); |
| 9595 checkParamTypeRef(cls.executables[0].parameters[1].type, 1); |
| 9596 } |
| 9597 |
| 9598 test_type_param_not_shadowed_by_setter() { |
| 9599 // The code under test should not produce a compile-time error, but it |
| 9600 // does. |
| 9601 bool workAroundBug25525 = true; |
| 9602 UnlinkedClass cls = serializeClassText( |
| 9603 'class C<D> { D x; void set D(value) {} } class D {}', |
| 9604 allowErrors: workAroundBug25525); |
| 9605 checkParamTypeRef(cls.fields[0].type, 1); |
| 9606 } |
| 9607 |
| 9608 test_type_param_not_shadowed_by_typedef_parameter() { |
| 9609 UnlinkedTypedef typedef = |
| 9610 serializeTypedefText('typedef void F<T>(int T, T x);'); |
| 9611 checkParamTypeRef(typedef.parameters[1].type, 1); |
| 9612 } |
| 9613 |
| 9614 test_type_param_shadowed_by_field() { |
| 9615 UnlinkedClass cls = serializeClassText( |
| 9616 'class C<D> { D x; int D; } class D {}', |
| 9617 allowErrors: true); |
| 9618 checkDynamicTypeRef(cls.fields[0].type); |
| 9619 } |
| 9620 |
| 9621 test_type_param_shadowed_by_getter() { |
| 9622 UnlinkedClass cls = serializeClassText( |
| 9623 'class C<D> { D x; int get D => null; } class D {}', |
| 9624 allowErrors: true); |
| 9625 checkDynamicTypeRef(cls.fields[0].type); |
| 9626 } |
| 9627 |
| 9628 test_type_param_shadowed_by_method() { |
| 9629 UnlinkedClass cls = serializeClassText( |
| 9630 'class C<D> { D x; void D() {} } class D {}', |
| 9631 allowErrors: true); |
| 9632 checkDynamicTypeRef(cls.fields[0].type); |
| 9633 } |
| 9634 |
| 9635 test_type_param_shadowed_by_type_param() { |
| 9636 UnlinkedClass cls = |
| 9637 serializeClassText('class C<T> { T f<T>(T x) => null; }'); |
| 9638 checkParamTypeRef(cls.executables[0].returnType, 1); |
| 9639 checkParamTypeRef(cls.executables[0].parameters[0].type, 1); |
| 9640 } |
| 9641 |
| 9642 test_type_reference_from_part() { |
| 9643 addNamedSource('/a.dart', 'part of foo; C v;'); |
| 9644 serializeLibraryText('library foo; part "a.dart"; class C {}'); |
| 9645 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type, |
| 9646 null, null, 'C', |
| 9647 expectedKind: ReferenceKind.classOrEnum, |
| 9648 linkedSourceUnit: linked.units[1], |
| 9649 unlinkedSourceUnit: unlinkedUnits[1]); |
| 9650 } |
| 9651 |
| 9652 test_type_reference_from_part_withPrefix() { |
| 9653 addNamedSource('/a.dart', 'class C {}'); |
| 9654 addNamedSource('/p.dart', 'part of foo; a.C v;'); |
| 9655 serializeLibraryText( |
| 9656 'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";', |
| 9657 allowErrors: true); |
| 9658 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type, |
| 9659 absUri('/a.dart'), 'a.dart', 'C', |
| 9660 expectedPrefix: 'a', |
| 9661 linkedSourceUnit: linked.units[1], |
| 9662 unlinkedSourceUnit: unlinkedUnits[1]); |
| 9663 } |
| 9664 |
| 9665 test_type_reference_to_class_argument() { |
| 9666 UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }'); |
| 9667 { |
| 9668 EntityRef typeRef = |
| 9669 findVariable('t', variables: cls.fields, failIfAbsent: true).type; |
| 9670 checkParamTypeRef(typeRef, 2); |
| 9671 } |
| 9672 { |
| 9673 EntityRef typeRef = |
| 9674 findVariable('u', variables: cls.fields, failIfAbsent: true).type; |
| 9675 checkParamTypeRef(typeRef, 1); |
| 9676 } |
| 9677 } |
| 9678 |
| 9679 test_type_reference_to_import_of_export() { |
| 9680 addNamedSource('/a.dart', 'library a; export "b.dart";'); |
| 9681 addNamedSource('/b.dart', 'library b; class C {}'); |
| 9682 checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'), |
| 9683 absUri('/b.dart'), 'b.dart', 'C'); |
| 9684 } |
| 9685 |
| 9686 test_type_reference_to_import_of_export_via_prefix() { |
| 9687 addNamedSource('/a.dart', 'library a; export "b.dart";'); |
| 9688 addNamedSource('/b.dart', 'library b; class C {}'); |
| 9689 checkTypeRef( |
| 9690 serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'), |
| 9691 absUri('/b.dart'), |
| 9692 'b.dart', |
| 9693 'C', |
| 9694 expectedPrefix: 'p'); |
| 9695 } |
| 9696 |
| 9697 test_type_reference_to_imported_part() { |
| 9698 addNamedSource('/a.dart', 'library my.lib; part "b.dart";'); |
| 9699 addNamedSource('/b.dart', 'part of my.lib; class C {}'); |
| 9700 checkTypeRef( |
| 9701 serializeTypeText('C', |
| 9702 otherDeclarations: 'library my.lib; import "a.dart";'), |
| 9703 absUri('/a.dart'), |
| 9704 'a.dart', |
| 9705 'C', |
| 9706 expectedTargetUnit: 1); |
| 9707 } |
| 9708 |
| 9709 test_type_reference_to_imported_part_with_prefix() { |
| 9710 addNamedSource('/a.dart', 'library my.lib; part "b.dart";'); |
| 9711 addNamedSource('/b.dart', 'part of my.lib; class C {}'); |
| 9712 checkTypeRef( |
| 9713 serializeTypeText('p.C', |
| 9714 otherDeclarations: 'library my.lib; import "a.dart" as p;'), |
| 9715 absUri('/a.dart'), |
| 9716 'a.dart', |
| 9717 'C', |
| 9718 expectedPrefix: 'p', |
| 9719 expectedTargetUnit: 1); |
| 9720 } |
| 9721 |
| 9722 test_type_reference_to_internal_class() { |
| 9723 checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null, |
| 9724 null, 'C'); |
| 9725 } |
| 9726 |
| 9727 test_type_reference_to_internal_class_alias() { |
| 9728 checkTypeRef( |
| 9729 serializeTypeText('C', |
| 9730 otherDeclarations: 'class C = D with E; class D {} class E {}'), |
| 9731 null, |
| 9732 null, |
| 9733 'C'); |
| 9734 } |
| 9735 |
| 9736 test_type_reference_to_internal_enum() { |
| 9737 checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'), |
| 9738 null, null, 'E'); |
| 9739 } |
| 9740 |
| 9741 test_type_reference_to_local_part() { |
| 9742 addNamedSource('/a.dart', 'part of my.lib; class C {}'); |
| 9743 checkTypeRef( |
| 9744 serializeTypeText('C', |
| 9745 otherDeclarations: 'library my.lib; part "a.dart";'), |
| 9746 null, |
| 9747 null, |
| 9748 'C', |
| 9749 expectedTargetUnit: 1); |
| 9750 } |
| 9751 |
| 9752 test_type_reference_to_nonexistent_file_via_prefix() { |
| 9753 allowMissingFiles = true; |
| 9754 EntityRef typeRef = serializeTypeText('p.C', |
| 9755 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true); |
| 9756 checkUnresolvedTypeRef(typeRef, 'p', 'C'); |
| 9757 } |
| 9758 |
| 9759 test_type_reference_to_part() { |
| 9760 addNamedSource('/a.dart', 'part of foo; class C { C(); }'); |
| 9761 serializeLibraryText('library foo; part "a.dart"; C c;'); |
| 9762 checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C', |
| 9763 expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1); |
| 9764 } |
| 9765 |
| 9766 test_type_reference_to_type_visible_via_multiple_import_prefixes() { |
| 9767 addNamedSource('/lib1.dart', 'class C'); |
| 9768 addNamedSource('/lib2.dart', 'export "lib1.dart";'); |
| 9769 addNamedSource('/lib3.dart', 'export "lib1.dart";'); |
| 9770 addNamedSource('/lib4.dart', 'export "lib1.dart";'); |
| 9771 serializeLibraryText(''' |
| 9772 import 'lib2.dart'; |
| 9773 import 'lib3.dart' as a; |
| 9774 import 'lib4.dart' as b; |
| 9775 C c2; |
| 9776 a.C c3; |
| 9777 b.C c4;'''); |
| 9778 // Note: it is important that each reference to class C records the prefix |
| 9779 // used to find it; otherwise it's possible that relinking might produce an |
| 9780 // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart. |
| 9781 checkTypeRef( |
| 9782 findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C'); |
| 9783 checkTypeRef( |
| 9784 findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C', |
| 9785 expectedPrefix: 'a'); |
| 9786 checkTypeRef( |
| 9787 findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C', |
| 9788 expectedPrefix: 'b'); |
| 9789 } |
| 9790 |
| 9791 test_type_reference_to_typedef() { |
| 9792 checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'), |
| 9793 null, null, 'F', |
| 9794 expectedKind: ReferenceKind.typedef); |
| 9795 } |
| 9796 |
| 9797 test_type_unit_counts_unreferenced_units() { |
| 9798 addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";'); |
| 9799 addNamedSource('/b.dart', 'part of a;'); |
| 9800 addNamedSource('/c.dart', 'part of a; class C {}'); |
| 9801 EntityRef typeRef = |
| 9802 serializeTypeText('C', otherDeclarations: 'import "a.dart";'); |
| 9803 // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is |
| 9804 // b.dart. a.dart and b.dart are counted even though nothing is imported |
| 9805 // from them. |
| 9806 checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C', |
| 9807 expectedTargetUnit: 2); |
| 9808 } |
| 9809 |
| 9810 test_type_unresolved() { |
| 9811 EntityRef typeRef = serializeTypeText('Foo', allowErrors: true); |
| 9812 checkUnresolvedTypeRef(typeRef, null, 'Foo'); |
| 9813 } |
| 9814 |
| 9815 test_typedef_codeRange() { |
| 9816 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 9817 _assertCodeRange(type.codeRange, 0, 12); |
| 9818 } |
| 9819 |
| 9820 test_typedef_documented() { |
| 9821 String text = ''' |
| 9822 // Extra comment so doc comment offset != 0 |
| 9823 /** |
| 9824 * Docs |
| 9825 */ |
| 9826 typedef F();'''; |
| 9827 UnlinkedTypedef typedef = serializeTypedefText(text); |
| 9828 expect(typedef.documentationComment, isNotNull); |
| 9829 checkDocumentationComment(typedef.documentationComment, text); |
| 9830 } |
| 9831 |
| 9832 test_typedef_name() { |
| 9833 String text = 'typedef F();'; |
| 9834 UnlinkedTypedef type = serializeTypedefText(text); |
| 9835 expect(type.name, 'F'); |
| 9836 expect(type.nameOffset, text.indexOf('F')); |
| 9837 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1)); |
| 9838 expect( |
| 9839 unlinkedUnits[0].publicNamespace.names[0].kind, ReferenceKind.typedef); |
| 9840 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F'); |
| 9841 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 9842 } |
| 9843 |
| 9844 test_typedef_param_none() { |
| 9845 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 9846 expect(type.parameters, isEmpty); |
| 9847 } |
| 9848 |
| 9849 test_typedef_param_order() { |
| 9850 UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);'); |
| 9851 expect(type.parameters, hasLength(2)); |
| 9852 expect(type.parameters[0].name, 'x'); |
| 9853 expect(type.parameters[1].name, 'y'); |
| 9854 } |
| 9855 |
| 9856 test_typedef_private() { |
| 9857 serializeTypedefText('typedef _F();', '_F'); |
| 9858 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 9859 } |
| 9860 |
| 9861 test_typedef_reference_generic() { |
| 9862 EntityRef typeRef = |
| 9863 serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();'); |
| 9864 checkTypeRef(typeRef, null, null, 'F', |
| 9865 numTypeParameters: 2, expectedKind: ReferenceKind.typedef); |
| 9866 } |
| 9867 |
| 9868 test_typedef_reference_generic_imported() { |
| 9869 addNamedSource('/lib.dart', 'typedef void F<A, B>();'); |
| 9870 EntityRef typeRef = |
| 9871 serializeTypeText('F', otherDeclarations: 'import "lib.dart";'); |
| 9872 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F', |
| 9873 numTypeParameters: 2, expectedKind: ReferenceKind.typedef); |
| 9874 } |
| 9875 |
| 9876 test_typedef_return_type_explicit() { |
| 9877 UnlinkedTypedef type = serializeTypedefText('typedef int F();'); |
| 9878 checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int'); |
| 9879 } |
| 9880 |
| 9881 test_typedef_type_param_in_parameter() { |
| 9882 UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);'); |
| 9883 checkParamTypeRef(type.parameters[0].type, 1); |
| 9884 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1); |
| 9885 } |
| 9886 |
| 9887 test_typedef_type_param_in_return_type() { |
| 9888 UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();'); |
| 9889 checkParamTypeRef(type.returnType, 1); |
| 9890 } |
| 9891 |
| 9892 test_typedef_type_param_none() { |
| 9893 UnlinkedTypedef type = serializeTypedefText('typedef F();'); |
| 9894 expect(type.typeParameters, isEmpty); |
| 9895 } |
| 9896 |
| 9897 test_typedef_type_param_order() { |
| 9898 UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();'); |
| 9899 expect(type.typeParameters, hasLength(2)); |
| 9900 expect(type.typeParameters[0].name, 'T'); |
| 9901 expect(type.typeParameters[1].name, 'U'); |
| 9902 } |
| 9903 |
| 9904 test_unit_codeRange() { |
| 9905 serializeLibraryText(' int a = 1; '); |
| 9906 UnlinkedUnit unit = unlinkedUnits[0]; |
| 9907 _assertCodeRange(unit.codeRange, 0, 14); |
| 9908 } |
| 9909 |
| 9910 test_unresolved_export() { |
| 9911 allowMissingFiles = true; |
| 9912 serializeLibraryText("export 'foo.dart';", allowErrors: true); |
| 9913 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1)); |
| 9914 expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'foo.dart'); |
| 9915 expect(linked.exportDependencies, hasLength(1)); |
| 9916 checkDependency( |
| 9917 linked.exportDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 9918 } |
| 9919 |
| 9920 test_unresolved_import() { |
| 9921 allowMissingFiles = true; |
| 9922 serializeLibraryText("import 'foo.dart';", allowErrors: true); |
| 9923 expect(unlinkedUnits[0].imports, hasLength(2)); |
| 9924 expect(unlinkedUnits[0].imports[0].uri, 'foo.dart'); |
| 9925 // Note: imports[1] is the implicit import of dart:core. |
| 9926 expect(unlinkedUnits[0].imports[1].isImplicit, true); |
| 9927 expect(linked.importDependencies, hasLength(2)); |
| 9928 checkDependency( |
| 9929 linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart'); |
| 9930 } |
| 9931 |
| 9932 test_unresolved_part() { |
| 9933 allowMissingFiles = true; |
| 9934 serializeLibraryText("part 'foo.dart';", allowErrors: true); |
| 9935 expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1)); |
| 9936 expect(unlinkedUnits[0].publicNamespace.parts[0], 'foo.dart'); |
| 9937 } |
| 9938 |
| 9939 test_unresolved_reference_in_multiple_parts() { |
| 9940 addNamedSource('/a.dart', 'part of foo; int x; Unresolved y;'); |
| 9941 serializeLibraryText('library foo; part "a.dart"; Unresolved z;', |
| 9942 allowErrors: true); |
| 9943 // The unresolved types in the defining compilation unit and the part |
| 9944 // should both work correctly even though they use different reference |
| 9945 // indices. |
| 9946 checkUnresolvedTypeRef( |
| 9947 unlinkedUnits[0].variables[0].type, null, 'Unresolved'); |
| 9948 checkUnresolvedTypeRef( |
| 9949 unlinkedUnits[1].variables[1].type, null, 'Unresolved', |
| 9950 linkedSourceUnit: linked.units[1], |
| 9951 unlinkedSourceUnit: unlinkedUnits[1]); |
| 9952 } |
| 9953 |
| 9954 test_unresolved_reference_shared() { |
| 9955 // Both `x` and `y` use unresolved identifier `C` as their type. Verify |
| 9956 // that they both use the same unresolved reference. |
| 9957 serializeLibraryText('C x; C y;', allowErrors: true); |
| 9958 EntityRef xType = findVariable('x').type; |
| 9959 EntityRef yType = findVariable('y').type; |
| 9960 expect(xType.reference, yType.reference); |
| 9961 } |
| 9962 |
| 9963 test_unused_type_parameter() { |
| 9964 if (!strongMode || skipFullyLinkedData) { |
| 9965 return; |
| 9966 } |
| 9967 UnlinkedVariable variable = serializeVariableText(''' |
| 9968 class C<T> { |
| 9969 void f() {} |
| 9970 } |
| 9971 C<int> c; |
| 9972 var v = c.f; |
| 9973 '''); |
| 9974 EntityRef type = |
| 9975 getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot); |
| 9976 expect(type.typeArguments, hasLength(1)); |
| 9977 checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int'); |
| 9978 } |
| 9979 |
| 9980 test_variable() { |
| 9981 String text = 'int i;'; |
| 9982 UnlinkedVariable v = serializeVariableText(text, variableName: 'i'); |
| 9983 expect(v.nameOffset, text.indexOf('i;')); |
| 9984 expect(findExecutable('i'), isNull); |
| 9985 expect(findExecutable('i='), isNull); |
| 9986 expect(unlinkedUnits[0].publicNamespace.names, hasLength(2)); |
| 9987 expect(unlinkedUnits[0].publicNamespace.names[0].kind, |
| 9988 ReferenceKind.topLevelPropertyAccessor); |
| 9989 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i'); |
| 9990 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0); |
| 9991 expect(unlinkedUnits[0].publicNamespace.names[1].kind, |
| 9992 ReferenceKind.topLevelPropertyAccessor); |
| 9993 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i='); |
| 9994 expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0); |
| 9995 } |
| 9996 |
| 9997 test_variable_codeRange() { |
| 9998 serializeLibraryText(' int a = 1, b = 22;'); |
| 9999 List<UnlinkedVariable> variables = unlinkedUnits[0].variables; |
| 10000 _assertCodeRange(variables[0].codeRange, 1, 18); |
| 10001 _assertCodeRange(variables[1].codeRange, 1, 18); |
| 10002 } |
| 10003 |
| 10004 test_variable_const() { |
| 10005 UnlinkedVariable variable = |
| 10006 serializeVariableText('const int i = 0;', variableName: 'i'); |
| 10007 expect(variable.isConst, isTrue); |
| 10008 } |
| 10009 |
| 10010 test_variable_documented() { |
| 10011 String text = ''' |
| 10012 // Extra comment so doc comment offset != 0 |
| 10013 /** |
| 10014 * Docs |
| 10015 */ |
| 10016 var v;'''; |
| 10017 UnlinkedVariable variable = serializeVariableText(text); |
| 10018 expect(variable.documentationComment, isNotNull); |
| 10019 checkDocumentationComment(variable.documentationComment, text); |
| 10020 } |
| 10021 |
| 10022 test_variable_explicit_dynamic() { |
| 10023 UnlinkedVariable variable = serializeVariableText('dynamic v;'); |
| 10024 checkDynamicTypeRef(variable.type); |
| 10025 } |
| 10026 |
| 10027 test_variable_final_top_level() { |
| 10028 UnlinkedVariable variable = |
| 10029 serializeVariableText('final int i = 0;', variableName: 'i'); |
| 10030 expect(variable.isFinal, isTrue); |
| 10031 expect(variable.initializer.bodyExpr, isNull); |
| 10032 } |
| 10033 |
| 10034 test_variable_final_top_level_untyped() { |
| 10035 UnlinkedVariable variable = serializeVariableText('final v = 0;'); |
| 10036 expect(variable.initializer.bodyExpr, isNotNull); |
| 10037 } |
| 10038 |
| 10039 test_variable_implicit_dynamic() { |
| 10040 UnlinkedVariable variable = serializeVariableText('var v;'); |
| 10041 expect(variable.type, isNull); |
| 10042 } |
| 10043 |
| 10044 test_variable_inferred_type_explicit_initialized() { |
| 10045 UnlinkedVariable v = serializeVariableText('int v = 0;'); |
| 10046 expect(v.inferredTypeSlot, 0); |
| 10047 } |
| 10048 |
| 10049 test_variable_inferred_type_implicit_initialized() { |
| 10050 UnlinkedVariable v = serializeVariableText('var v = 0;'); |
| 10051 checkInferredTypeSlot(v.inferredTypeSlot, 'dart:core', 'dart:core', 'int'); |
| 10052 } |
| 10053 |
| 10054 test_variable_inferred_type_implicit_uninitialized() { |
| 10055 UnlinkedVariable v = serializeVariableText('var v;'); |
| 10056 expect(v.inferredTypeSlot, 0); |
| 10057 } |
| 10058 |
| 10059 test_variable_initializer_literal() { |
| 10060 UnlinkedVariable variable = serializeVariableText('var v = 42;'); |
| 10061 UnlinkedExecutable initializer = variable.initializer; |
| 10062 expect(initializer, isNotNull); |
| 10063 expect(initializer.nameOffset, 8); |
| 10064 expect(initializer.name, isEmpty); |
| 10065 expect(initializer.localFunctions, isEmpty); |
| 10066 expect(initializer.localVariables, isEmpty); |
| 10067 } |
| 10068 |
| 10069 test_variable_initializer_noInitializer() { |
| 10070 UnlinkedVariable variable = serializeVariableText('var v;'); |
| 10071 expect(variable.initializer, isNull); |
| 10072 } |
| 10073 |
| 10074 test_variable_initializer_withLocals() { |
| 10075 String text = 'var v = <dynamic, dynamic>{"1": () { f1() {} var v1; }, ' |
| 10076 '"2": () { f2() {} var v2; }};'; |
| 10077 UnlinkedVariable variable = serializeVariableText(text); |
| 10078 UnlinkedExecutable initializer = variable.initializer; |
| 10079 expect(initializer, isNotNull); |
| 10080 expect(initializer.nameOffset, text.indexOf('<dynamic, dynamic>{"1')); |
| 10081 expect(initializer.name, isEmpty); |
| 10082 expect(initializer.localFunctions, hasLength(2)); |
| 10083 // closure: () { f1() {} var v1; } |
| 10084 { |
| 10085 UnlinkedExecutable closure = initializer.localFunctions[0]; |
| 10086 expect(closure.nameOffset, text.indexOf('() { f1()')); |
| 10087 expect(closure.name, isEmpty); |
| 10088 // closure - f1 |
| 10089 expect(closure.localFunctions, hasLength(1)); |
| 10090 expect(closure.localFunctions[0].name, 'f1'); |
| 10091 expect(closure.localFunctions[0].nameOffset, text.indexOf('f1()')); |
| 10092 // closure - v1 |
| 10093 expect(closure.localVariables, hasLength(1)); |
| 10094 expect(closure.localVariables[0].name, 'v1'); |
| 10095 expect(closure.localVariables[0].nameOffset, text.indexOf('v1;')); |
| 10096 } |
| 10097 // closure: () { f2() {} var v2; } |
| 10098 { |
| 10099 UnlinkedExecutable closure = initializer.localFunctions[1]; |
| 10100 expect(closure.nameOffset, text.indexOf('() { f2()')); |
| 10101 expect(closure.name, isEmpty); |
| 10102 // closure - f1 |
| 10103 expect(closure.localFunctions, hasLength(1)); |
| 10104 expect(closure.localFunctions[0].name, 'f2'); |
| 10105 expect(closure.localFunctions[0].nameOffset, text.indexOf('f2()')); |
| 10106 // closure - v1 |
| 10107 expect(closure.localVariables, hasLength(1)); |
| 10108 expect(closure.localVariables[0].name, 'v2'); |
| 10109 expect(closure.localVariables[0].nameOffset, text.indexOf('v2;')); |
| 10110 } |
| 10111 } |
| 10112 |
| 10113 test_variable_name() { |
| 10114 UnlinkedVariable variable = |
| 10115 serializeVariableText('int i;', variableName: 'i'); |
| 10116 expect(variable.name, 'i'); |
| 10117 } |
| 10118 |
| 10119 test_variable_no_flags() { |
| 10120 UnlinkedVariable variable = |
| 10121 serializeVariableText('int i;', variableName: 'i'); |
| 10122 expect(variable.isStatic, isFalse); |
| 10123 expect(variable.isConst, isFalse); |
| 10124 expect(variable.isFinal, isFalse); |
| 10125 } |
| 10126 |
| 10127 test_variable_non_const() { |
| 10128 UnlinkedVariable variable = |
| 10129 serializeVariableText('int i = 0;', variableName: 'i'); |
| 10130 expect(variable.isConst, isFalse); |
| 10131 } |
| 10132 |
| 10133 test_variable_non_final() { |
| 10134 UnlinkedVariable variable = |
| 10135 serializeVariableText('int i;', variableName: 'i'); |
| 10136 expect(variable.isFinal, isFalse); |
| 10137 } |
| 10138 |
| 10139 test_variable_non_static() { |
| 10140 UnlinkedVariable variable = |
| 10141 serializeClassText('class C { int i; }').fields[0]; |
| 10142 expect(variable.isStatic, isFalse); |
| 10143 } |
| 10144 |
| 10145 test_variable_non_static_top_level() { |
| 10146 // Top level variables are considered non-static. |
| 10147 UnlinkedVariable variable = |
| 10148 serializeVariableText('int i;', variableName: 'i'); |
| 10149 expect(variable.isStatic, isFalse); |
| 10150 } |
| 10151 |
| 10152 test_variable_private() { |
| 10153 serializeVariableText('int _i;', variableName: '_i'); |
| 10154 expect(unlinkedUnits[0].publicNamespace.names, isEmpty); |
| 10155 } |
| 10156 |
| 10157 test_variable_static() { |
| 10158 UnlinkedVariable variable = |
| 10159 serializeClassText('class C { static int i; }').fields[0]; |
| 10160 expect(variable.isStatic, isTrue); |
| 10161 } |
| 10162 |
| 10163 test_variable_type() { |
| 10164 UnlinkedVariable variable = |
| 10165 serializeVariableText('int i;', variableName: 'i'); |
| 10166 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int'); |
| 10167 } |
| 10168 |
| 10169 /** |
| 10170 * Verify invariants of the given [linkedLibrary]. |
| 10171 */ |
| 10172 void validateLinkedLibrary(LinkedLibrary linkedLibrary) { |
| 10173 for (LinkedUnit unit in linkedLibrary.units) { |
| 10174 for (LinkedReference reference in unit.references) { |
| 10175 switch (reference.kind) { |
| 10176 case ReferenceKind.classOrEnum: |
| 10177 case ReferenceKind.topLevelPropertyAccessor: |
| 10178 case ReferenceKind.topLevelFunction: |
| 10179 case ReferenceKind.typedef: |
| 10180 // This reference can have either a zero or a nonzero dependency, |
| 10181 // since it refers to top level element which might or might not be |
| 10182 // imported from another library. |
| 10183 break; |
| 10184 case ReferenceKind.prefix: |
| 10185 // Prefixes should have a dependency of 0, since they come from the |
| 10186 // current library. |
| 10187 expect(reference.dependency, 0, |
| 10188 reason: 'Nonzero dependency for prefix'); |
| 10189 break; |
| 10190 case ReferenceKind.unresolved: |
| 10191 // Unresolved references always have a dependency of 0. |
| 10192 expect(reference.dependency, 0, |
| 10193 reason: 'Nonzero dependency for undefined'); |
| 10194 break; |
| 10195 default: |
| 10196 // This reference should have a dependency of 0, since it refers to |
| 10197 // an element that is contained within some other element. |
| 10198 expect(reference.dependency, 0, |
| 10199 reason: 'Nonzero dependency for ${reference.kind}'); |
| 10200 } |
| 10201 } |
| 10202 } |
| 10203 } |
| 10204 |
| 10205 /** |
| 10206 * Assert that serializing the given [expr] of form `(a op= 1 + 2) + 3` |
| 10207 * uses the given [expectedAssignOperator]. |
| 10208 */ |
| 10209 void _assertAssignmentOperator( |
| 10210 String expr, UnlinkedExprAssignOperator expectedAssignOperator) { |
| 10211 if (skipNonConstInitializers) { |
| 10212 return; |
| 10213 } |
| 10214 UnlinkedVariable variable = serializeVariableText(''' |
| 10215 int a = 0; |
| 10216 final v = $expr; |
| 10217 '''); |
| 10218 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 10219 isValidConst: false, |
| 10220 operators: [ |
| 10221 UnlinkedConstOperation.pushInt, |
| 10222 UnlinkedConstOperation.pushInt, |
| 10223 UnlinkedConstOperation.add, |
| 10224 UnlinkedConstOperation.assignToRef, |
| 10225 UnlinkedConstOperation.pushInt, |
| 10226 UnlinkedConstOperation.add, |
| 10227 ], |
| 10228 assignmentOperators: [ |
| 10229 expectedAssignOperator |
| 10230 ], |
| 10231 ints: [ |
| 10232 1, |
| 10233 2, |
| 10234 3 |
| 10235 ], |
| 10236 strings: [], |
| 10237 referenceValidators: [ |
| 10238 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 10239 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 10240 ]); |
| 10241 } |
| 10242 |
| 10243 void _assertCodeRange(CodeRange codeRange, int offset, int length) { |
| 10244 expect(codeRange, isNotNull); |
| 10245 expect(codeRange.offset, offset); |
| 10246 expect(codeRange.length, length); |
| 10247 } |
| 10248 |
| 10249 void _assertExecutableVisible(String code, UnlinkedExecutable f, |
| 10250 String visibleBegin, String visibleEnd) { |
| 10251 int expectedVisibleOffset = code.indexOf(visibleBegin); |
| 10252 int expectedVisibleLength = |
| 10253 code.indexOf(visibleEnd) - expectedVisibleOffset + 1; |
| 10254 expect(f.visibleOffset, expectedVisibleOffset); |
| 10255 expect(f.visibleLength, expectedVisibleLength); |
| 10256 } |
| 10257 |
| 10258 void _assertParameterVisible( |
| 10259 String code, UnlinkedParam p, String visibleBegin, String visibleEnd) { |
| 10260 int expectedVisibleOffset = code.indexOf(visibleBegin); |
| 10261 int expectedVisibleLength = |
| 10262 code.indexOf(visibleEnd) - expectedVisibleOffset + 1; |
| 10263 expect(p.visibleOffset, expectedVisibleOffset); |
| 10264 expect(p.visibleLength, expectedVisibleLength); |
| 10265 } |
| 10266 |
| 10267 void _assertParameterZeroVisibleRange(UnlinkedParam p) { |
| 10268 expect(p.visibleOffset, isZero); |
| 10269 expect(p.visibleLength, isZero); |
| 10270 } |
| 10271 |
| 10272 /** |
| 10273 * Assert that the [expr] of the form `++a + 2` is serialized with the |
| 10274 * [expectedAssignmentOperator]. |
| 10275 */ |
| 10276 void _assertRefPrefixPostfixIncrementDecrement( |
| 10277 String expr, UnlinkedExprAssignOperator expectedAssignmentOperator) { |
| 10278 if (skipNonConstInitializers) { |
| 10279 return; |
| 10280 } |
| 10281 UnlinkedVariable variable = serializeVariableText(''' |
| 10282 int a = 0; |
| 10283 final v = $expr; |
| 10284 '''); |
| 10285 _assertUnlinkedConst(variable.initializer.bodyExpr, |
| 10286 isValidConst: false, |
| 10287 operators: [ |
| 10288 UnlinkedConstOperation.assignToRef, |
| 10289 UnlinkedConstOperation.pushInt, |
| 10290 UnlinkedConstOperation.add, |
| 10291 ], |
| 10292 assignmentOperators: [ |
| 10293 expectedAssignmentOperator |
| 10294 ], |
| 10295 ints: [ |
| 10296 2 |
| 10297 ], |
| 10298 strings: [], |
| 10299 referenceValidators: [ |
| 10300 (EntityRef r) => checkTypeRef(r, null, null, 'a', |
| 10301 expectedKind: ReferenceKind.topLevelPropertyAccessor) |
| 10302 ]); |
| 10303 } |
| 10304 |
| 10305 /** |
| 10306 * TODO(scheglov) rename "Const" to "Expr" everywhere |
| 10307 */ |
| 10308 void _assertUnlinkedConst(UnlinkedConst constExpr, |
| 10309 {bool isValidConst: true, |
| 10310 List<UnlinkedConstOperation> operators: const <UnlinkedConstOperation>[], |
| 10311 List<UnlinkedExprAssignOperator> assignmentOperators: |
| 10312 const <UnlinkedExprAssignOperator>[], |
| 10313 List<int> ints: const <int>[], |
| 10314 List<double> doubles: const <double>[], |
| 10315 List<String> strings: const <String>[], |
| 10316 List<_EntityRefValidator> referenceValidators: |
| 10317 const <_EntityRefValidator>[]}) { |
| 10318 expect(constExpr, isNotNull); |
| 10319 expect(constExpr.isValidConst, isValidConst); |
| 10320 expect(constExpr.operations, operators); |
| 10321 expect(constExpr.ints, ints); |
| 10322 expect(constExpr.doubles, doubles); |
| 10323 expect(constExpr.strings, strings); |
| 10324 expect(constExpr.assignmentOperators, assignmentOperators); |
| 10325 expect(constExpr.references, hasLength(referenceValidators.length)); |
| 10326 for (int i = 0; i < referenceValidators.length; i++) { |
| 10327 referenceValidators[i](constExpr.references[i]); |
| 10328 } |
| 10329 } |
| 10330 |
| 10331 void _assertVariableVisible( |
| 10332 String code, UnlinkedVariable v, String visibleBegin, String visibleEnd) { |
| 10333 int expectedVisibleOffset = code.indexOf(visibleBegin); |
| 10334 int expectedVisibleLength = |
| 10335 code.indexOf(visibleEnd) - expectedVisibleOffset + 1; |
| 10336 expect(v.visibleOffset, expectedVisibleOffset); |
| 10337 expect(v.visibleLength, expectedVisibleLength); |
| 10338 } |
| 10339 } |
| 10340 |
| 10341 /** |
| 10342 * Description of expectations for a prelinked prefix reference. |
| 10343 */ |
| 10344 class _PrefixExpectation { |
| 10345 final ReferenceKind kind; |
| 10346 final String name; |
| 10347 final String absoluteUri; |
| 10348 final String relativeUri; |
| 10349 final int numTypeParameters; |
| 10350 |
| 10351 _PrefixExpectation(this.kind, this.name, |
| 10352 {this.absoluteUri, this.relativeUri, this.numTypeParameters: 0}); |
| 10353 } |
| OLD | NEW |