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

Side by Side Diff: pkg/analyzer/test/src/summary/summary_test.dart

Issue 1606123003: Split summary_test into multiple files. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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_test;
6
7 import 'package:analyzer/analyzer.dart';
8 import 'package:analyzer/dart/ast/ast.dart';
9 import 'package:analyzer/dart/element/element.dart';
10 import 'package:analyzer/src/generated/engine.dart';
11 import 'package:analyzer/src/generated/error.dart';
12 import 'package:analyzer/src/generated/java_engine_io.dart';
13 import 'package:analyzer/src/generated/parser.dart';
14 import 'package:analyzer/src/generated/scanner.dart';
15 import 'package:analyzer/src/generated/source.dart';
16 import 'package:analyzer/src/generated/source_io.dart';
17 import 'package:analyzer/src/summary/base.dart';
18 import 'package:analyzer/src/summary/format.dart';
19 import 'package:analyzer/src/summary/prelink.dart';
20 import 'package:analyzer/src/summary/public_namespace_computer.dart'
21 as public_namespace;
22 import 'package:analyzer/src/summary/summarize_ast.dart';
23 import 'package:analyzer/src/summary/summarize_elements.dart'
24 as summarize_elements;
25 import 'package:unittest/unittest.dart';
26
27 import '../../generated/resolver_test.dart';
28 import '../../reflective_tests.dart';
29
30 main() {
31 groupSep = ' | ';
32 runReflectiveTests(SummarizeElementsTest);
33 runReflectiveTests(PrelinkerTest);
34 runReflectiveTests(UnlinkedSummarizeAstTest);
35 }
36
37 /**
38 * The public namespaces of the sdk are computed once so that we don't bog
39 * down the test. Structured as a map from absolute URI to the corresponding
40 * public namespace.
41 *
42 * Note: should an exception occur during computation of this variable, it
43 * will silently be set to null to allow other tests to run.
44 */
45 final Map<String, UnlinkedPublicNamespace> sdkPublicNamespace = () {
46 try {
47 AnalysisContext analysisContext = AnalysisContextFactory.contextWithCore();
48 Map<String, UnlinkedPublicNamespace> uriToNamespace =
49 <String, UnlinkedPublicNamespace>{};
50 List<LibraryElement> libraries = [
51 analysisContext.typeProvider.objectType.element.library,
52 analysisContext.typeProvider.futureType.element.library
53 ];
54 for (LibraryElement library in libraries) {
55 summarize_elements.LibrarySerializationResult serializedLibrary =
56 summarize_elements.serializeLibrary(
57 library, analysisContext.typeProvider);
58 for (int i = 0; i < serializedLibrary.unlinkedUnits.length; i++) {
59 uriToNamespace[serializedLibrary.unitUris[i]] =
60 new UnlinkedUnit.fromBuffer(
61 serializedLibrary.unlinkedUnits[i].toBuffer()).publicNamespace;
62 }
63 }
64 return uriToNamespace;
65 } catch (_) {
66 return null;
67 }
68 }();
69
70 /**
71 * Convert a summary object (or a portion of one) into a canonical form that
72 * can be easily compared using [expect]. If [orderByName] is true, and the
73 * object is a [List], it is sorted by the `name` field of its elements.
74 */
75 Object canonicalize(Object obj, {bool orderByName: false}) {
76 if (obj is SummaryClass) {
77 Map<String, Object> result = <String, Object>{};
78 obj.toMap().forEach((String key, Object value) {
79 bool orderByName = false;
80 if (obj is UnlinkedPublicNamespace && key == 'names') {
81 orderByName = true;
82 }
83 result[key] = canonicalize(value, orderByName: orderByName);
84 });
85 return result;
86 } else if (obj is List) {
87 List<Object> result = <Object>[];
88 for (Object item in obj) {
89 result.add(canonicalize(item));
90 }
91 if (orderByName) {
92 result.sort((Object a, Object b) {
93 if (a is Map && b is Map) {
94 return Comparable.compare(a['name'], b['name']);
95 } else {
96 return 0;
97 }
98 });
99 }
100 return result;
101 } else if (obj is String || obj is num || obj is bool) {
102 return obj;
103 } else {
104 return obj.toString();
105 }
106 }
107
108 UnlinkedPublicNamespace computePublicNamespaceFromText(
109 String text, Source source) {
110 CharacterReader reader = new CharSequenceReader(text);
111 Scanner scanner =
112 new Scanner(source, reader, AnalysisErrorListener.NULL_LISTENER);
113 Parser parser = new Parser(source, AnalysisErrorListener.NULL_LISTENER);
114 parser.parseGenericMethods = true;
115 CompilationUnit unit = parser.parseCompilationUnit(scanner.tokenize());
116 UnlinkedPublicNamespace namespace = new UnlinkedPublicNamespace.fromBuffer(
117 public_namespace.computePublicNamespace(unit).toBuffer());
118 return namespace;
119 }
120
121 /**
122 * Type of a function that validates an [TypeRef].
123 */
124 typedef void _TypeRefValidator(TypeRef unlinkedTypeRef);
125
126 /**
127 * Override of [SummaryTest] which verifies the correctness of the prelinker by
128 * creating summaries from the element model, discarding their prelinked
129 * information, and then recreating it using the prelinker.
130 */
131 @reflectiveTest
132 class PrelinkerTest extends SummarizeElementsTest {
133 final Map<String, UnlinkedPublicNamespace> uriToPublicNamespace =
134 <String, UnlinkedPublicNamespace>{};
135
136 @override
137 bool get expectAbsoluteUrisInDependencies => false;
138
139 @override
140 bool get skipFullyLinkedData => true;
141
142 @override
143 Source addNamedSource(String filePath, String contents) {
144 Source source = super.addNamedSource(filePath, contents);
145 uriToPublicNamespace[absUri(filePath)] =
146 computePublicNamespaceFromText(contents, source);
147 return source;
148 }
149
150 String resolveToAbsoluteUri(LibraryElement library, String relativeUri) {
151 Source resolvedSource =
152 analysisContext.sourceFactory.resolveUri(library.source, relativeUri);
153 if (resolvedSource == null) {
154 fail('Failed to resolve relative uri "$relativeUri"');
155 }
156 return resolvedSource.uri.toString();
157 }
158
159 @override
160 void serializeLibraryElement(LibraryElement library) {
161 super.serializeLibraryElement(library);
162 Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
163 expect(unlinkedUnits.length, unitUris.length);
164 for (int i = 1; i < unlinkedUnits.length; i++) {
165 uriToUnit[unitUris[i]] = unlinkedUnits[i];
166 }
167 UnlinkedUnit getPart(String relativeUri) {
168 String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
169 UnlinkedUnit unit = uriToUnit[absoluteUri];
170 if (unit == null) {
171 fail('Prelinker unexpectedly requested unit for "$relativeUri"'
172 ' (resolves to "$absoluteUri").');
173 }
174 return unit;
175 }
176 UnlinkedPublicNamespace getImport(String relativeUri) {
177 String absoluteUri = resolveToAbsoluteUri(library, relativeUri);
178 UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
179 if (namespace == null) {
180 namespace = uriToPublicNamespace[absoluteUri];
181 }
182 if (namespace == null && !allowMissingFiles) {
183 fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
184 ' (resolves to "$absoluteUri").'
185 ' Namespaces available: ${uriToPublicNamespace.keys}');
186 }
187 return namespace;
188 }
189 linked = new LinkedLibrary.fromBuffer(
190 prelink(unlinkedUnits[0], getPart, getImport).toBuffer());
191 }
192 }
193
194 /**
195 * Override of [SummaryTest] which creates summaries from the element model.
196 */
197 @reflectiveTest
198 class SummarizeElementsTest extends ResolverTestCase with SummaryTest {
199 /**
200 * The list of absolute unit URIs corresponding to the compilation units in
201 * [unlinkedUnits].
202 */
203 List<String> unitUris;
204
205 /**
206 * Map containing all source files in this test, and their corresponding file
207 * contents.
208 */
209 final Map<Source, String> _fileContents = <Source, String>{};
210
211 @override
212 LinkedLibrary linked;
213
214 @override
215 List<UnlinkedUnit> unlinkedUnits;
216
217 @override
218 bool get checkAstDerivedData => false;
219
220 @override
221 bool get expectAbsoluteUrisInDependencies => true;
222
223 @override
224 bool get skipFullyLinkedData => false;
225
226 @override
227 Source addNamedSource(String filePath, String contents) {
228 Source source = super.addNamedSource(filePath, contents);
229 _fileContents[source] = contents;
230 return source;
231 }
232
233 /**
234 * Serialize the library containing the given class [element], then
235 * deserialize it and return the summary of the class.
236 */
237 UnlinkedClass serializeClassElement(ClassElement element) {
238 serializeLibraryElement(element.library);
239 return findClass(element.name, failIfAbsent: true);
240 }
241
242 /**
243 * Serialize the given [library] element, then deserialize it and store the
244 * resulting summary in [linked] and [unlinkedUnits].
245 */
246 void serializeLibraryElement(LibraryElement library) {
247 summarize_elements.LibrarySerializationResult serializedLib =
248 summarize_elements.serializeLibrary(library, typeProvider);
249 {
250 List<int> buffer = serializedLib.linked.toBuffer();
251 linked = new LinkedLibrary.fromBuffer(buffer);
252 }
253 unlinkedUnits = serializedLib.unlinkedUnits.map((UnlinkedUnitBuilder b) {
254 List<int> buffer = b.toBuffer();
255 return new UnlinkedUnit.fromBuffer(buffer);
256 }).toList();
257 unitUris = serializedLib.unitUris;
258 }
259
260 @override
261 void serializeLibraryText(String text, {bool allowErrors: false}) {
262 Source source = addSource(text);
263 _fileContents[source] = text;
264 LibraryElement library = resolve2(source);
265 if (!allowErrors) {
266 assertNoErrors(source);
267 }
268 serializeLibraryElement(library);
269 expect(unlinkedUnits[0].imports.length, linked.importDependencies.length);
270 expect(linked.units.length, unlinkedUnits.length);
271 for (int i = 0; i < linked.units.length; i++) {
272 expect(unlinkedUnits[i].references.length,
273 lessThanOrEqualTo(linked.units[i].references.length));
274 }
275 verifyPublicNamespace();
276 }
277
278 @override
279 void setUp() {
280 super.setUp();
281 AnalysisOptionsImpl options = new AnalysisOptionsImpl();
282 options.enableGenericMethods = true;
283 resetWithOptions(options);
284 }
285
286 test_class_no_superclass() {
287 UnlinkedClass cls = serializeClassElement(typeProvider.objectType.element);
288 expect(cls.supertype, isNull);
289 expect(cls.hasNoSupertype, isTrue);
290 }
291
292 /**
293 * Verify that [public_namespace.computePublicNamespace] produces data that's
294 * equivalent to that produced by [summarize_elements.serializeLibrary].
295 */
296 void verifyPublicNamespace() {
297 for (int i = 0; i < unlinkedUnits.length; i++) {
298 Source source = analysisContext.sourceFactory.forUri(unitUris[i]);
299 String text = _fileContents[source];
300 if (text == null) {
301 if (!allowMissingFiles) {
302 fail('Could not find file while verifying public namespace: '
303 '${unitUris[i]}');
304 }
305 } else {
306 UnlinkedPublicNamespace namespace =
307 computePublicNamespaceFromText(text, source);
308 expect(canonicalize(namespace),
309 canonicalize(unlinkedUnits[i].publicNamespace),
310 reason: 'publicNamespace(${unitUris[i]})');
311 }
312 }
313 }
314 }
315
316 /**
317 * Base class containing most summary tests. This allows summary tests to be
318 * re-used to exercise all the different ways in which summaries can be
319 * generated (e.g. direct from the AST, from the element model, from a
320 * "relinking" process, etc.)
321 */
322 abstract class SummaryTest {
323 /**
324 * A test will set this to `true` if it contains `import`, `export`, or
325 * `part` declarations that deliberately refer to non-existent files.
326 */
327 bool allowMissingFiles = false;
328
329 /**
330 * `true` if the summary was created directly from the AST (and hence
331 * contains information that is not obtainable from the element model alone).
332 * TODO(paulberry): modify the element model so that it contains all the data
333 * that summaries need, so that this flag is no longer needed.
334 */
335 bool get checkAstDerivedData;
336
337 /**
338 * Get access to the linked defining compilation unit.
339 */
340 LinkedUnit get definingUnit => linked.units[0];
341
342 /**
343 * `true` if the linked portion of the summary is expected to contain
344 * absolute URIs. This happens because the element model doesn't (yet) store
345 * enough information to recover relative URIs, TODO(paulberry): fix this.
346 */
347 bool get expectAbsoluteUrisInDependencies;
348
349 /**
350 * Get access to the linked summary that results from serializing and
351 * then deserializing the library under test.
352 */
353 LinkedLibrary get linked;
354
355 /**
356 * `true` if the linked portion of the summary only contains prelinked data.
357 * This happens because we don't yet have a full linker; only a prelinker.
358 */
359 bool get skipFullyLinkedData;
360
361 /**
362 * Get access to the unlinked compilation unit summaries that result from
363 * serializing and deserializing the library under test.
364 */
365 List<UnlinkedUnit> get unlinkedUnits;
366
367 /**
368 * Convert [path] to a suitably formatted absolute path URI for the current
369 * platform.
370 */
371 String absUri(String path) {
372 return FileUtilities2.createFile(path).toURI().toString();
373 }
374
375 /**
376 * Add the given source file so that it may be referenced by the file under
377 * test.
378 */
379 Source addNamedSource(String filePath, String contents);
380
381 /**
382 * Verify that the [dependency]th element of the dependency table represents
383 * a file reachable via the given [absoluteUri] and [relativeUri].
384 */
385 void checkDependency(int dependency, String absoluteUri, String relativeUri) {
386 if (expectAbsoluteUrisInDependencies) {
387 // The element model doesn't (yet) store enough information to recover
388 // relative URIs, so we have to use the absolute URI.
389 // TODO(paulberry): fix this.
390 relativeUri = absoluteUri;
391 }
392 expect(dependency, new isInstanceOf<int>());
393 expect(linked.dependencies[dependency].uri, relativeUri);
394 }
395
396 /**
397 * Verify that the given [dependency] lists the given [absoluteUris] or
398 * [relativeUris] as its parts.
399 */
400 void checkDependencyParts(LinkedDependency dependency,
401 List<String> absoluteUris, List<String> relativeUris) {
402 if (expectAbsoluteUrisInDependencies) {
403 // The element model doesn't (yet) store enough information to recover
404 // relative URIs, so we have to use the absolute URI.
405 // TODO(paulberry): fix this.
406 relativeUris = absoluteUris;
407 }
408 expect(dependency.parts, relativeUris);
409 }
410
411 /**
412 * Check that the given [documentationComment] matches the first
413 * Javadoc-style comment found in [text].
414 *
415 * Note that the algorithm for finding the Javadoc-style comment in [text] is
416 * a simple-minded text search; it is easily confused by corner cases such as
417 * strings containing comments, nested comments, etc.
418 */
419 void checkDocumentationComment(
420 UnlinkedDocumentationComment documentationComment, String text) {
421 expect(documentationComment, isNotNull);
422 int commentStart = text.indexOf('/*');
423 expect(commentStart, isNot(-1));
424 int commentEnd = text.indexOf('*/');
425 expect(commentEnd, isNot(-1));
426 commentEnd += 2;
427 String expectedCommentText =
428 text.substring(commentStart, commentEnd).replaceAll('\r\n', '\n');
429 expect(documentationComment.text, expectedCommentText);
430 expect(documentationComment.offset, commentStart);
431 expect(documentationComment.length, commentEnd - commentStart);
432 }
433
434 /**
435 * Verify that the given [typeRef] represents the type `dynamic`.
436 */
437 void checkDynamicTypeRef(TypeRef typeRef) {
438 checkTypeRef(typeRef, null, null, null);
439 }
440
441 /**
442 * Verify that the given [exportName] represents a reference to an entity
443 * declared in a file reachable via [absoluteUri] and [relativeUri], having
444 * name [expectedName]. [expectedKind] is the kind of object referenced.
445 * [expectedTargetUnit] is the index of the compilation unit in which the
446 * target of the [exportName] is expected to appear; if not specified it is
447 * assumed to be the defining compilation unit.
448 */
449 void checkExportName(LinkedExportName exportName, String absoluteUri,
450 String relativeUri, String expectedName, ReferenceKind expectedKind,
451 {int expectedTargetUnit: 0}) {
452 expect(exportName, new isInstanceOf<LinkedExportName>());
453 // Exported names must come from other libraries.
454 expect(exportName.dependency, isNot(0));
455 checkDependency(exportName.dependency, absoluteUri, relativeUri);
456 expect(exportName.name, expectedName);
457 expect(exportName.kind, expectedKind);
458 expect(exportName.unit, expectedTargetUnit);
459 }
460
461 /**
462 * Verify that the dependency table contains an entry for a file reachable
463 * via the given [absoluteUri] and [relativeUri]. If [fullyLinked] is
464 * `true`, then the dependency should be a fully-linked dependency; otherwise
465 * it should be a prelinked dependency.
466 *
467 * The index of the [LinkedDependency] is returned.
468 */
469 int checkHasDependency(String absoluteUri, String relativeUri,
470 {bool fullyLinked: false}) {
471 if (expectAbsoluteUrisInDependencies) {
472 // The element model doesn't (yet) store enough information to recover
473 // relative URIs, so we have to use the absolute URI.
474 // TODO(paulberry): fix this.
475 relativeUri = absoluteUri;
476 }
477 List<String> found = <String>[];
478 for (int i = 0; i < linked.dependencies.length; i++) {
479 LinkedDependency dep = linked.dependencies[i];
480 if (dep.uri == relativeUri) {
481 if (fullyLinked) {
482 expect(i, greaterThanOrEqualTo(linked.numPrelinkedDependencies));
483 } else {
484 expect(i, lessThan(linked.numPrelinkedDependencies));
485 }
486 return i;
487 }
488 found.add(dep.uri);
489 }
490 fail('Did not find dependency $relativeUri. Found: $found');
491 return null;
492 }
493
494 /**
495 * Verify that the dependency table *does not* contain any entries for a file
496 * reachable via the given [absoluteUri] and [relativeUri].
497 */
498 void checkLacksDependency(String absoluteUri, String relativeUri) {
499 if (expectAbsoluteUrisInDependencies) {
500 // The element model doesn't (yet) store enough information to recover
501 // relative URIs, so we have to use the absolute URI.
502 // TODO(paulberry): fix this.
503 relativeUri = absoluteUri;
504 }
505 for (LinkedDependency dep in linked.dependencies) {
506 if (dep.uri == relativeUri) {
507 fail('Unexpected dependency found: $relativeUri');
508 }
509 }
510 }
511
512 /**
513 * Verify that the given [typeRef] represents a reference to a type declared
514 * in a file reachable via [absoluteUri] and [relativeUri], having name
515 * [expectedName]. If [allowTypeParameters] is true, allow the type
516 * reference to supply type parameters. [expectedKind] is the kind of object
517 * referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
518 * compilation unit within which the [typeRef] appears; if not specified they
519 * are assumed to refer to the defining compilation unit.
520 * [expectedTargetUnit] is the index of the compilation unit in which the
521 * target of the [typeRef] is expected to appear; if not specified it is
522 * assumed to be the defining compilation unit. [numTypeParameters] is the
523 * number of type parameters of the thing being referred to.
524 */
525 void checkLinkedTypeRef(TypeRef typeRef, String absoluteUri,
526 String relativeUri, String expectedName,
527 {bool allowTypeParameters: false,
528 ReferenceKind expectedKind: ReferenceKind.classOrEnum,
529 int expectedTargetUnit: 0,
530 LinkedUnit linkedSourceUnit,
531 UnlinkedUnit unlinkedSourceUnit,
532 int numTypeParameters: 0}) {
533 linkedSourceUnit ??= definingUnit;
534 expect(typeRef, isNotNull,
535 reason: 'No entry in linkedSourceUnit.types matching slotId');
536 expect(typeRef.paramReference, 0);
537 int index = typeRef.reference;
538 if (!allowTypeParameters) {
539 expect(typeRef.typeArguments, isEmpty);
540 }
541 checkTypeRefCommonElements(
542 index,
543 absoluteUri,
544 relativeUri,
545 expectedName,
546 expectedKind,
547 expectedTargetUnit,
548 linkedSourceUnit,
549 unlinkedSourceUnit,
550 numTypeParameters);
551 }
552
553 /**
554 * Verify that the given [slotId] represents a reference to a type declared
555 * in a file reachable via [absoluteUri] and [relativeUri], having name
556 * [expectedName]. If [allowTypeParameters] is true, allow the type
557 * reference to supply type parameters. [expectedKind] is the kind of object
558 * referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
559 * compilation unit within which the [typeRef] appears; if not specified they
560 * are assumed to refer to the defining compilation unit.
561 * [expectedTargetUnit] is the index of the compilation unit in which the
562 * target of the [typeRef] is expected to appear; if not specified it is
563 * assumed to be the defining compilation unit. [numTypeParameters] is the
564 * number of type parameters of the thing being referred to.
565 */
566 void checkLinkedTypeSlot(
567 int slotId, String absoluteUri, String relativeUri, String expectedName,
568 {bool allowTypeParameters: false,
569 ReferenceKind expectedKind: ReferenceKind.classOrEnum,
570 int expectedTargetUnit: 0,
571 LinkedUnit linkedSourceUnit,
572 UnlinkedUnit unlinkedSourceUnit,
573 int numTypeParameters: 0}) {
574 // Slot ids should be nonzero, since zero means "no associated slot".
575 expect(slotId, isNot(0));
576 if (skipFullyLinkedData) {
577 return;
578 }
579 linkedSourceUnit ??= definingUnit;
580 checkLinkedTypeRef(
581 getTypeRefForSlot(slotId, linkedSourceUnit: linkedSourceUnit),
582 absoluteUri,
583 relativeUri,
584 expectedName,
585 allowTypeParameters: allowTypeParameters,
586 expectedKind: expectedKind,
587 expectedTargetUnit: expectedTargetUnit,
588 linkedSourceUnit: linkedSourceUnit,
589 unlinkedSourceUnit: unlinkedSourceUnit,
590 numTypeParameters: numTypeParameters);
591 }
592
593 /**
594 * Verify that the given [typeRef] represents a reference to a type parameter
595 * having the given [deBruijnIndex].
596 */
597 void checkParamTypeRef(TypeRef typeRef, int deBruijnIndex) {
598 expect(typeRef, new isInstanceOf<TypeRef>());
599 expect(typeRef.reference, 0);
600 expect(typeRef.typeArguments, isEmpty);
601 expect(typeRef.paramReference, deBruijnIndex);
602 }
603
604 /**
605 * Verify that [prefixReference] is a valid reference to a prefix having the
606 * given [name].
607 */
608 void checkPrefix(int prefixReference, String name) {
609 expect(prefixReference, isNot(0));
610 expect(unlinkedUnits[0].references[prefixReference].prefixReference, 0);
611 expect(unlinkedUnits[0].references[prefixReference].name, name);
612 expect(definingUnit.references[prefixReference].dependency, 0);
613 expect(definingUnit.references[prefixReference].kind, ReferenceKind.prefix);
614 expect(definingUnit.references[prefixReference].unit, 0);
615 }
616
617 /**
618 * Verify that the given [typeRef] represents a reference to a type declared
619 * in a file reachable via [absoluteUri] and [relativeUri], having name
620 * [expectedName]. If [expectedPrefix] is supplied, verify that the type is
621 * reached via the given prefix. If [allowTypeParameters] is true, allow the
622 * type reference to supply type parameters. [expectedKind] is the kind of
623 * object referenced. [linkedSourceUnit] and [unlinkedSourceUnit] refer
624 * to the compilation unit within which the [typeRef] appears; if not
625 * specified they are assumed to refer to the defining compilation unit.
626 * [expectedTargetUnit] is the index of the compilation unit in which the
627 * target of the [typeRef] is expected to appear; if not specified it is
628 * assumed to be the defining compilation unit. [numTypeParameters] is the
629 * number of type parameters of the thing being referred to.
630 */
631 void checkTypeRef(TypeRef typeRef, String absoluteUri, String relativeUri,
632 String expectedName,
633 {String expectedPrefix,
634 bool allowTypeParameters: false,
635 ReferenceKind expectedKind: ReferenceKind.classOrEnum,
636 int expectedTargetUnit: 0,
637 LinkedUnit linkedSourceUnit,
638 UnlinkedUnit unlinkedSourceUnit,
639 int numTypeParameters: 0}) {
640 linkedSourceUnit ??= definingUnit;
641 expect(typeRef, new isInstanceOf<TypeRef>());
642 expect(typeRef.paramReference, 0);
643 int index = typeRef.reference;
644 if (!allowTypeParameters) {
645 expect(typeRef.typeArguments, isEmpty);
646 }
647 UnlinkedReference reference = checkTypeRefCommonElements(
648 index,
649 absoluteUri,
650 relativeUri,
651 expectedName,
652 expectedKind,
653 expectedTargetUnit,
654 linkedSourceUnit,
655 unlinkedSourceUnit,
656 numTypeParameters);
657 expect(reference, isNotNull,
658 reason: 'Unlinked type refs must refer to an explicit reference');
659 if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
660 // summarize_elements.dart isn't yet able to record the prefix of
661 // unresolved references. TODO(paulberry): fix this.
662 expect(reference.prefixReference, 0);
663 } else if (expectedPrefix == null) {
664 expect(reference.prefixReference, 0);
665 } else {
666 checkPrefix(reference.prefixReference, expectedPrefix);
667 }
668 }
669
670 /**
671 * Check the data structures that are common between [checkTypeRef] and
672 * [checkLinkedTypeRef]. If the type reference in question is an explicit
673 * reference, return the [UnlinkedReference] that is used to make the
674 * explicit reference. If the type reference in question is an implicit
675 * reference, return `null`.
676 */
677 UnlinkedReference checkTypeRefCommonElements(
678 int referenceIndex,
679 String absoluteUri,
680 String relativeUri,
681 String expectedName,
682 ReferenceKind expectedKind,
683 int expectedTargetUnit,
684 LinkedUnit linkedSourceUnit,
685 UnlinkedUnit unlinkedSourceUnit,
686 int numTypeParameters) {
687 unlinkedSourceUnit ??= unlinkedUnits[0];
688 LinkedReference referenceResolution =
689 linkedSourceUnit.references[referenceIndex];
690 String name;
691 UnlinkedReference reference;
692 if (referenceIndex < unlinkedSourceUnit.references.length) {
693 // This is an explicit reference, so its name and prefix should be in
694 // [UnlinkedUnit.references].
695 expect(referenceResolution.name, isEmpty);
696 reference = unlinkedSourceUnit.references[referenceIndex];
697 name = reference.name;
698 if (reference.prefixReference != 0) {
699 // Prefixes should appear in the references table before any reference
700 // that uses them.
701 expect(reference.prefixReference, lessThan(referenceIndex));
702 }
703 } else {
704 // This is an implicit reference, so its name should be in
705 // [LinkedUnit.references].
706 name = referenceResolution.name;
707 }
708 if (referenceIndex == 0) {
709 // Index 0 is reserved for "dynamic".
710 expect(name, isEmpty);
711 }
712 if (absoluteUri == null) {
713 expect(referenceResolution.dependency, 0);
714 } else {
715 checkDependency(referenceResolution.dependency, absoluteUri, relativeUri);
716 }
717 if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
718 // summarize_elements.dart isn't yet able to record the name of
719 // unresolved references. TODO(paulberry): fix this.
720 expect(name, '*unresolved*');
721 } else {
722 if (expectedName == null) {
723 expect(name, isEmpty);
724 } else {
725 expect(name, expectedName);
726 }
727 }
728 expect(referenceResolution.kind, expectedKind);
729 expect(referenceResolution.unit, expectedTargetUnit);
730 expect(referenceResolution.numTypeParameters, numTypeParameters);
731 return reference;
732 }
733
734 /**
735 * Verify that the given [typeRef] represents a reference to an unresolved
736 * type.
737 */
738 void checkUnresolvedTypeRef(
739 TypeRef typeRef, String expectedPrefix, String expectedName,
740 {LinkedUnit linkedSourceUnit, UnlinkedUnit unlinkedSourceUnit}) {
741 // When serializing from the element model, unresolved type refs lose their
742 // name.
743 checkTypeRef(typeRef, null, null, checkAstDerivedData ? expectedName : null,
744 expectedPrefix: expectedPrefix,
745 expectedKind: ReferenceKind.unresolved,
746 linkedSourceUnit: linkedSourceUnit,
747 unlinkedSourceUnit: unlinkedSourceUnit);
748 }
749
750 fail_constExpr_pushInt_shiftOr() {
751 UnlinkedVariable variable =
752 serializeVariableText('const v = 0x111222333444555666;');
753 // ^^!!!!^^^^!!!!^^^^
754 _assertUnlinkedConst(variable.constExpr, operators: [
755 UnlinkedConstOperation.pushInt,
756 UnlinkedConstOperation.shiftOr,
757 UnlinkedConstOperation.shiftOr
758 ], ints: [
759 0x11,
760 0x12223334,
761 0x44555666
762 ]);
763 }
764
765 fail_enum_value_documented() {
766 // TODO(paulberry): currently broken because of dartbug.com/25385
767 String text = '''
768 enum E {
769 /**
770 * Docs
771 */
772 v
773 }''';
774 UnlinkedEnumValue value = serializeEnumText(text).values[0];
775 expect(value.documentationComment, isNotNull);
776 checkDocumentationComment(value.documentationComment, text);
777 }
778
779 /**
780 * Find the class with the given [className] in the summary, and return its
781 * [UnlinkedClass] data structure. If [unit] is not given, the class is
782 * looked for in the defining compilation unit.
783 */
784 UnlinkedClass findClass(String className,
785 {bool failIfAbsent: false, UnlinkedUnit unit}) {
786 unit ??= unlinkedUnits[0];
787 UnlinkedClass result;
788 for (UnlinkedClass cls in unit.classes) {
789 if (cls.name == className) {
790 if (result != null) {
791 fail('Duplicate class $className');
792 }
793 result = cls;
794 }
795 }
796 if (result == null && failIfAbsent) {
797 fail('Class $className not found in serialized output');
798 }
799 return result;
800 }
801
802 /**
803 * Find the enum with the given [enumName] in the summary, and return its
804 * [UnlinkedEnum] data structure. If [unit] is not given, the enum is looked
805 * for in the defining compilation unit.
806 */
807 UnlinkedEnum findEnum(String enumName,
808 {bool failIfAbsent: false, UnlinkedUnit unit}) {
809 unit ??= unlinkedUnits[0];
810 UnlinkedEnum result;
811 for (UnlinkedEnum e in unit.enums) {
812 if (e.name == enumName) {
813 if (result != null) {
814 fail('Duplicate enum $enumName');
815 }
816 result = e;
817 }
818 }
819 if (result == null && failIfAbsent) {
820 fail('Enum $enumName not found in serialized output');
821 }
822 return result;
823 }
824
825 /**
826 * Find the executable with the given [executableName] in the summary, and
827 * return its [UnlinkedExecutable] data structure. If [executables] is not
828 * given, then the executable is searched for in the defining compilation
829 * unit.
830 */
831 UnlinkedExecutable findExecutable(String executableName,
832 {List<UnlinkedExecutable> executables, bool failIfAbsent: false}) {
833 executables ??= unlinkedUnits[0].executables;
834 UnlinkedExecutable result;
835 for (UnlinkedExecutable executable in executables) {
836 if (executable.name == executableName) {
837 if (result != null) {
838 fail('Duplicate executable $executableName');
839 }
840 result = executable;
841 }
842 }
843 if (result == null && failIfAbsent) {
844 fail('Executable $executableName not found in serialized output');
845 }
846 return result;
847 }
848
849 /**
850 * Find the typedef with the given [typedefName] in the summary, and return
851 * its [UnlinkedTypedef] data structure. If [unit] is not given, the typedef
852 * is looked for in the defining compilation unit.
853 */
854 UnlinkedTypedef findTypedef(String typedefName,
855 {bool failIfAbsent: false, UnlinkedUnit unit}) {
856 unit ??= unlinkedUnits[0];
857 UnlinkedTypedef result;
858 for (UnlinkedTypedef type in unit.typedefs) {
859 if (type.name == typedefName) {
860 if (result != null) {
861 fail('Duplicate typedef $typedefName');
862 }
863 result = type;
864 }
865 }
866 if (result == null && failIfAbsent) {
867 fail('Typedef $typedefName not found in serialized output');
868 }
869 return result;
870 }
871
872 /**
873 * Find the top level variable with the given [variableName] in the summary,
874 * and return its [UnlinkedVariable] data structure. If [variables] is not
875 * specified, the variable is looked for in the defining compilation unit.
876 */
877 UnlinkedVariable findVariable(String variableName,
878 {List<UnlinkedVariable> variables, bool failIfAbsent: false}) {
879 variables ??= unlinkedUnits[0].variables;
880 UnlinkedVariable result;
881 for (UnlinkedVariable variable in variables) {
882 if (variable.name == variableName) {
883 if (result != null) {
884 fail('Duplicate variable $variableName');
885 }
886 result = variable;
887 }
888 }
889 if (result == null && failIfAbsent) {
890 fail('Variable $variableName not found in serialized output');
891 }
892 return result;
893 }
894
895 /**
896 * Find the entry in [linkedSourceUnit.types] matching [slotId].
897 */
898 TypeRef getTypeRefForSlot(int slotId, {LinkedUnit linkedSourceUnit}) {
899 linkedSourceUnit ??= definingUnit;
900 for (TypeRef typeRef in linkedSourceUnit.types) {
901 if (typeRef.slot == slotId) {
902 return typeRef;
903 }
904 }
905 return null;
906 }
907
908 /**
909 * Serialize the given library [text] and return the summary of the class
910 * with the given [className].
911 */
912 UnlinkedClass serializeClassText(String text,
913 {String className: 'C', bool allowErrors: false}) {
914 serializeLibraryText(text, allowErrors: allowErrors);
915 return findClass(className, failIfAbsent: true);
916 }
917
918 /**
919 * Serialize the given library [text] and return the summary of the enum with
920 * the given [enumName].
921 */
922 UnlinkedEnum serializeEnumText(String text, [String enumName = 'E']) {
923 serializeLibraryText(text);
924 return findEnum(enumName, failIfAbsent: true);
925 }
926
927 /**
928 * Serialize the given library [text] and return the summary of the
929 * executable with the given [executableName].
930 */
931 UnlinkedExecutable serializeExecutableText(String text,
932 [String executableName = 'f']) {
933 serializeLibraryText(text);
934 return findExecutable(executableName, failIfAbsent: true);
935 }
936
937 /**
938 * Serialize the given library [text], then deserialize it and store its
939 * summary in [lib].
940 */
941 void serializeLibraryText(String text, {bool allowErrors: false});
942
943 /**
944 * Serialize the given method [text] and return the summary of the executable
945 * with the given [executableName].
946 */
947 UnlinkedExecutable serializeMethodText(String text,
948 [String executableName = 'f']) {
949 serializeLibraryText('class C { $text }');
950 return findExecutable(executableName,
951 executables: findClass('C', failIfAbsent: true).executables,
952 failIfAbsent: true);
953 }
954
955 /**
956 * Serialize the given library [text] and return the summary of the typedef
957 * with the given [typedefName].
958 */
959 UnlinkedTypedef serializeTypedefText(String text,
960 [String typedefName = 'F']) {
961 serializeLibraryText(text);
962 return findTypedef(typedefName, failIfAbsent: true);
963 }
964
965 /**
966 * Serialize a type declaration using the given [text] as a type name, and
967 * return a summary of the corresponding [TypeRef]. If the type
968 * declaration needs to refer to types that are not available in core, those
969 * types may be declared in [otherDeclarations].
970 */
971 TypeRef serializeTypeText(String text,
972 {String otherDeclarations: '', bool allowErrors: false}) {
973 return serializeVariableText('$otherDeclarations\n$text v;',
974 allowErrors: allowErrors).type;
975 }
976
977 /**
978 * Serialize the given library [text] and return the summary of the variable
979 * with the given [variableName].
980 */
981 UnlinkedVariable serializeVariableText(String text,
982 {String variableName: 'v', bool allowErrors: false}) {
983 serializeLibraryText(text, allowErrors: allowErrors);
984 return findVariable(variableName, failIfAbsent: true);
985 }
986
987 test_cascaded_export_hide_hide() {
988 addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
989 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
990 serializeLibraryText(
991 '''
992 import 'lib1.dart';
993 A a;
994 B b;
995 C c;
996 ''',
997 allowErrors: true);
998 checkTypeRef(
999 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
1000 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1001 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1002 }
1003
1004 test_cascaded_export_hide_show() {
1005 addNamedSource('/lib1.dart', 'export "lib2.dart" hide C show A, C;');
1006 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
1007 serializeLibraryText(
1008 '''
1009 import 'lib1.dart';
1010 A a;
1011 B b;
1012 C c;
1013 ''',
1014 allowErrors: true);
1015 checkTypeRef(
1016 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
1017 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1018 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1019 }
1020
1021 test_cascaded_export_show_hide() {
1022 addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B hide B, C;');
1023 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
1024 serializeLibraryText(
1025 '''
1026 import 'lib1.dart';
1027 A a;
1028 B b;
1029 C c;
1030 ''',
1031 allowErrors: true);
1032 checkTypeRef(
1033 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
1034 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1035 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1036 }
1037
1038 test_cascaded_export_show_show() {
1039 addNamedSource('/lib1.dart', 'export "lib2.dart" show A, B show A, C;');
1040 addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
1041 serializeLibraryText(
1042 '''
1043 import 'lib1.dart';
1044 A a;
1045 B b;
1046 C c;
1047 ''',
1048 allowErrors: true);
1049 checkTypeRef(
1050 findVariable('a').type, absUri('/lib2.dart'), 'lib2.dart', 'A');
1051 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1052 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1053 }
1054
1055 test_cascaded_import_hide_hide() {
1056 addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
1057 serializeLibraryText(
1058 '''
1059 import 'lib.dart' hide C hide B, C;
1060 A a;
1061 B b;
1062 C c;
1063 ''',
1064 allowErrors: true);
1065 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
1066 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1067 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1068 }
1069
1070 test_cascaded_import_hide_show() {
1071 addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
1072 serializeLibraryText(
1073 '''
1074 import 'lib.dart' hide C show A, C;
1075 A a;
1076 B b;
1077 C c;
1078 ''',
1079 allowErrors: true);
1080 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
1081 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1082 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1083 }
1084
1085 test_cascaded_import_show_hide() {
1086 addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
1087 serializeLibraryText(
1088 '''
1089 import 'lib.dart' show A, B hide B, C;
1090 A a;
1091 B b;
1092 C c;
1093 ''',
1094 allowErrors: true);
1095 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
1096 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1097 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1098 }
1099
1100 test_cascaded_import_show_show() {
1101 addNamedSource('/lib.dart', 'class A {} class B {} class C {}');
1102 serializeLibraryText(
1103 '''
1104 import 'lib.dart' show A, B show A, C;
1105 A a;
1106 B b;
1107 C c;
1108 ''',
1109 allowErrors: true);
1110 checkTypeRef(findVariable('a').type, absUri('/lib.dart'), 'lib.dart', 'A');
1111 checkUnresolvedTypeRef(findVariable('b').type, null, 'B');
1112 checkUnresolvedTypeRef(findVariable('c').type, null, 'C');
1113 }
1114
1115 test_class_abstract() {
1116 UnlinkedClass cls = serializeClassText('abstract class C {}');
1117 expect(cls.isAbstract, true);
1118 }
1119
1120 test_class_alias_abstract() {
1121 UnlinkedClass cls = serializeClassText(
1122 'abstract class C = D with E; class D {} class E {}');
1123 expect(cls.isAbstract, true);
1124 }
1125
1126 test_class_alias_concrete() {
1127 UnlinkedClass cls =
1128 serializeClassText('class C = _D with _E; class _D {} class _E {}');
1129 expect(cls.isAbstract, false);
1130 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
1131 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
1132 ReferenceKind.classOrEnum);
1133 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
1134 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
1135 }
1136
1137 test_class_alias_documented() {
1138 String text = '''
1139 // Extra comment so doc comment offset != 0
1140 /**
1141 * Docs
1142 */
1143 class C = D with E;
1144
1145 class D {}
1146 class E {}''';
1147 UnlinkedClass cls = serializeClassText(text);
1148 expect(cls.documentationComment, isNotNull);
1149 checkDocumentationComment(cls.documentationComment, text);
1150 }
1151
1152 test_class_alias_flag() {
1153 UnlinkedClass cls =
1154 serializeClassText('class C = D with E; class D {} class E {}');
1155 expect(cls.isMixinApplication, true);
1156 }
1157
1158 test_class_alias_generic() {
1159 serializeClassText('class C<A, B> = _D with _E; class _D {} class _E {}');
1160 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 2);
1161 }
1162
1163 test_class_alias_mixin_order() {
1164 UnlinkedClass cls = serializeClassText('''
1165 class C = D with E, F;
1166 class D {}
1167 class E {}
1168 class F {}
1169 ''');
1170 expect(cls.mixins, hasLength(2));
1171 checkTypeRef(cls.mixins[0], null, null, 'E');
1172 checkTypeRef(cls.mixins[1], null, null, 'F');
1173 }
1174
1175 test_class_alias_no_implicit_constructors() {
1176 UnlinkedClass cls = serializeClassText('''
1177 class C = D with E;
1178 class D {
1179 D.foo();
1180 D.bar();
1181 }
1182 class E {}
1183 ''');
1184 expect(cls.executables, isEmpty);
1185 }
1186
1187 test_class_alias_private() {
1188 serializeClassText('class _C = _D with _E; class _D {} class _E {}',
1189 className: '_C');
1190 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
1191 }
1192
1193 test_class_alias_reference_generic() {
1194 TypeRef typeRef = serializeTypeText('C',
1195 otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
1196 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
1197 }
1198
1199 test_class_alias_reference_generic_imported() {
1200 addNamedSource(
1201 '/lib.dart', 'class C<D, E> = F with G; class F {} class G {}');
1202 TypeRef typeRef =
1203 serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
1204 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
1205 numTypeParameters: 2);
1206 }
1207
1208 test_class_alias_supertype() {
1209 UnlinkedClass cls =
1210 serializeClassText('class C = D with E; class D {} class E {}');
1211 checkTypeRef(cls.supertype, null, null, 'D');
1212 expect(cls.hasNoSupertype, isFalse);
1213 }
1214
1215 test_class_concrete() {
1216 UnlinkedClass cls = serializeClassText('class C {}');
1217 expect(cls.isAbstract, false);
1218 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
1219 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
1220 ReferenceKind.classOrEnum);
1221 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
1222 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
1223 }
1224
1225 test_class_documented() {
1226 String text = '''
1227 // Extra comment so doc comment offset != 0
1228 /**
1229 * Docs
1230 */
1231 class C {}''';
1232 UnlinkedClass cls = serializeClassText(text);
1233 expect(cls.documentationComment, isNotNull);
1234 checkDocumentationComment(cls.documentationComment, text);
1235 }
1236
1237 test_class_documented_with_references() {
1238 String text = '''
1239 // Extra comment so doc comment offset != 0
1240 /**
1241 * Docs referring to [D] and [E]
1242 */
1243 class C {}
1244
1245 class D {}
1246 class E {}''';
1247 UnlinkedClass cls = serializeClassText(text);
1248 expect(cls.documentationComment, isNotNull);
1249 checkDocumentationComment(cls.documentationComment, text);
1250 }
1251
1252 test_class_documented_with_with_windows_line_endings() {
1253 String text = '/**\r\n * Docs\r\n */\r\nclass C {}';
1254 UnlinkedClass cls = serializeClassText(text);
1255 expect(cls.documentationComment, isNotNull);
1256 checkDocumentationComment(cls.documentationComment, text);
1257 }
1258
1259 test_class_interface() {
1260 UnlinkedClass cls = serializeClassText('''
1261 class C implements D {}
1262 class D {}
1263 ''');
1264 expect(cls.interfaces, hasLength(1));
1265 checkTypeRef(cls.interfaces[0], null, null, 'D');
1266 }
1267
1268 test_class_interface_order() {
1269 UnlinkedClass cls = serializeClassText('''
1270 class C implements D, E {}
1271 class D {}
1272 class E {}
1273 ''');
1274 expect(cls.interfaces, hasLength(2));
1275 checkTypeRef(cls.interfaces[0], null, null, 'D');
1276 checkTypeRef(cls.interfaces[1], null, null, 'E');
1277 }
1278
1279 test_class_mixin() {
1280 UnlinkedClass cls = serializeClassText('''
1281 class C extends Object with D {}
1282 class D {}
1283 ''');
1284 expect(cls.mixins, hasLength(1));
1285 checkTypeRef(cls.mixins[0], null, null, 'D');
1286 }
1287
1288 test_class_mixin_order() {
1289 UnlinkedClass cls = serializeClassText('''
1290 class C extends Object with D, E {}
1291 class D {}
1292 class E {}
1293 ''');
1294 expect(cls.mixins, hasLength(2));
1295 checkTypeRef(cls.mixins[0], null, null, 'D');
1296 checkTypeRef(cls.mixins[1], null, null, 'E');
1297 }
1298
1299 test_class_name() {
1300 var classText = 'class C {}';
1301 UnlinkedClass cls = serializeClassText(classText);
1302 expect(cls.name, 'C');
1303 expect(cls.nameOffset, classText.indexOf('C'));
1304 }
1305
1306 test_class_no_flags() {
1307 UnlinkedClass cls = serializeClassText('class C {}');
1308 expect(cls.isAbstract, false);
1309 expect(cls.isMixinApplication, false);
1310 }
1311
1312 test_class_no_interface() {
1313 UnlinkedClass cls = serializeClassText('class C {}');
1314 expect(cls.interfaces, isEmpty);
1315 }
1316
1317 test_class_no_mixins() {
1318 UnlinkedClass cls = serializeClassText('class C {}');
1319 expect(cls.mixins, isEmpty);
1320 }
1321
1322 test_class_no_type_param() {
1323 UnlinkedClass cls = serializeClassText('class C {}');
1324 expect(cls.typeParameters, isEmpty);
1325 }
1326
1327 test_class_non_alias_flag() {
1328 UnlinkedClass cls = serializeClassText('class C {}');
1329 expect(cls.isMixinApplication, false);
1330 }
1331
1332 test_class_private() {
1333 serializeClassText('class _C {}', className: '_C');
1334 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
1335 }
1336
1337 test_class_reference_generic() {
1338 TypeRef typeRef =
1339 serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
1340 checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
1341 }
1342
1343 test_class_reference_generic_imported() {
1344 addNamedSource('/lib.dart', 'class C<D, E> {}');
1345 TypeRef typeRef =
1346 serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
1347 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
1348 numTypeParameters: 2);
1349 }
1350
1351 test_class_superclass() {
1352 UnlinkedClass cls = serializeClassText('class C {}');
1353 expect(cls.supertype, isNull);
1354 expect(cls.hasNoSupertype, isFalse);
1355 }
1356
1357 test_class_superclass_explicit() {
1358 UnlinkedClass cls = serializeClassText('class C extends D {} class D {}');
1359 expect(cls.supertype, isNotNull);
1360 checkTypeRef(cls.supertype, null, null, 'D');
1361 expect(cls.hasNoSupertype, isFalse);
1362 }
1363
1364 test_class_type_param_bound() {
1365 UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
1366 expect(cls.typeParameters, hasLength(1));
1367 expect(cls.typeParameters[0].name, 'T');
1368 expect(cls.typeParameters[0].bound, isNotNull);
1369 checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
1370 allowTypeParameters: true, numTypeParameters: 1);
1371 }
1372
1373 test_class_type_param_f_bound() {
1374 UnlinkedClass cls = serializeClassText('class C<T, U extends List<T>> {}');
1375 TypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
1376 checkParamTypeRef(typeArgument, 2);
1377 }
1378
1379 test_class_type_param_f_bound_self_ref() {
1380 UnlinkedClass cls = serializeClassText('class C<T, U extends List<U>> {}');
1381 TypeRef typeArgument = cls.typeParameters[1].bound.typeArguments[0];
1382 checkParamTypeRef(typeArgument, 1);
1383 }
1384
1385 test_class_type_param_no_bound() {
1386 String text = 'class C<T> {}';
1387 UnlinkedClass cls = serializeClassText(text);
1388 expect(cls.typeParameters, hasLength(1));
1389 expect(cls.typeParameters[0].name, 'T');
1390 expect(cls.typeParameters[0].nameOffset, text.indexOf('T'));
1391 expect(cls.typeParameters[0].bound, isNull);
1392 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
1393 }
1394
1395 test_constExpr_binary_add() {
1396 UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;');
1397 _assertUnlinkedConst(variable.constExpr, operators: [
1398 UnlinkedConstOperation.pushInt,
1399 UnlinkedConstOperation.pushInt,
1400 UnlinkedConstOperation.add
1401 ], ints: [
1402 1,
1403 2
1404 ]);
1405 }
1406
1407 test_constExpr_binary_and() {
1408 UnlinkedVariable variable =
1409 serializeVariableText('const v = true && false;');
1410 _assertUnlinkedConst(variable.constExpr, operators: [
1411 UnlinkedConstOperation.pushTrue,
1412 UnlinkedConstOperation.pushFalse,
1413 UnlinkedConstOperation.and
1414 ]);
1415 }
1416
1417 test_constExpr_binary_bitAnd() {
1418 UnlinkedVariable variable = serializeVariableText('const v = 1 & 2;');
1419 _assertUnlinkedConst(variable.constExpr, operators: [
1420 UnlinkedConstOperation.pushInt,
1421 UnlinkedConstOperation.pushInt,
1422 UnlinkedConstOperation.bitAnd
1423 ], ints: [
1424 1,
1425 2
1426 ]);
1427 }
1428
1429 test_constExpr_binary_bitOr() {
1430 UnlinkedVariable variable = serializeVariableText('const v = 1 | 2;');
1431 _assertUnlinkedConst(variable.constExpr, operators: [
1432 UnlinkedConstOperation.pushInt,
1433 UnlinkedConstOperation.pushInt,
1434 UnlinkedConstOperation.bitOr
1435 ], ints: [
1436 1,
1437 2
1438 ]);
1439 }
1440
1441 test_constExpr_binary_bitShiftLeft() {
1442 UnlinkedVariable variable = serializeVariableText('const v = 1 << 2;');
1443 _assertUnlinkedConst(variable.constExpr, operators: [
1444 UnlinkedConstOperation.pushInt,
1445 UnlinkedConstOperation.pushInt,
1446 UnlinkedConstOperation.bitShiftLeft
1447 ], ints: [
1448 1,
1449 2
1450 ]);
1451 }
1452
1453 test_constExpr_binary_bitShiftRight() {
1454 UnlinkedVariable variable = serializeVariableText('const v = 1 >> 2;');
1455 _assertUnlinkedConst(variable.constExpr, operators: [
1456 UnlinkedConstOperation.pushInt,
1457 UnlinkedConstOperation.pushInt,
1458 UnlinkedConstOperation.bitShiftRight
1459 ], ints: [
1460 1,
1461 2
1462 ]);
1463 }
1464
1465 test_constExpr_binary_bitXor() {
1466 UnlinkedVariable variable = serializeVariableText('const v = 1 ^ 2;');
1467 _assertUnlinkedConst(variable.constExpr, operators: [
1468 UnlinkedConstOperation.pushInt,
1469 UnlinkedConstOperation.pushInt,
1470 UnlinkedConstOperation.bitXor
1471 ], ints: [
1472 1,
1473 2
1474 ]);
1475 }
1476
1477 test_constExpr_binary_divide() {
1478 UnlinkedVariable variable = serializeVariableText('const v = 1 / 2;');
1479 _assertUnlinkedConst(variable.constExpr, operators: [
1480 UnlinkedConstOperation.pushInt,
1481 UnlinkedConstOperation.pushInt,
1482 UnlinkedConstOperation.divide
1483 ], ints: [
1484 1,
1485 2
1486 ]);
1487 }
1488
1489 test_constExpr_binary_equal() {
1490 UnlinkedVariable variable = serializeVariableText('const v = 1 == 2;');
1491 _assertUnlinkedConst(variable.constExpr, operators: [
1492 UnlinkedConstOperation.pushInt,
1493 UnlinkedConstOperation.pushInt,
1494 UnlinkedConstOperation.equal
1495 ], ints: [
1496 1,
1497 2
1498 ]);
1499 }
1500
1501 test_constExpr_binary_equal_not() {
1502 UnlinkedVariable variable = serializeVariableText('const v = 1 != 2;');
1503 _assertUnlinkedConst(variable.constExpr, operators: [
1504 UnlinkedConstOperation.pushInt,
1505 UnlinkedConstOperation.pushInt,
1506 UnlinkedConstOperation.equal,
1507 UnlinkedConstOperation.not
1508 ], ints: [
1509 1,
1510 2
1511 ]);
1512 }
1513
1514 test_constExpr_binary_floorDivide() {
1515 UnlinkedVariable variable = serializeVariableText('const v = 1 ~/ 2;');
1516 _assertUnlinkedConst(variable.constExpr, operators: [
1517 UnlinkedConstOperation.pushInt,
1518 UnlinkedConstOperation.pushInt,
1519 UnlinkedConstOperation.floorDivide
1520 ], ints: [
1521 1,
1522 2
1523 ]);
1524 }
1525
1526 test_constExpr_binary_greater() {
1527 UnlinkedVariable variable = serializeVariableText('const v = 1 > 2;');
1528 _assertUnlinkedConst(variable.constExpr, operators: [
1529 UnlinkedConstOperation.pushInt,
1530 UnlinkedConstOperation.pushInt,
1531 UnlinkedConstOperation.greater
1532 ], ints: [
1533 1,
1534 2
1535 ]);
1536 }
1537
1538 test_constExpr_binary_greaterEqual() {
1539 UnlinkedVariable variable = serializeVariableText('const v = 1 >= 2;');
1540 _assertUnlinkedConst(variable.constExpr, operators: [
1541 UnlinkedConstOperation.pushInt,
1542 UnlinkedConstOperation.pushInt,
1543 UnlinkedConstOperation.greaterEqual
1544 ], ints: [
1545 1,
1546 2
1547 ]);
1548 }
1549
1550 test_constExpr_binary_less() {
1551 UnlinkedVariable variable = serializeVariableText('const v = 1 < 2;');
1552 _assertUnlinkedConst(variable.constExpr, operators: [
1553 UnlinkedConstOperation.pushInt,
1554 UnlinkedConstOperation.pushInt,
1555 UnlinkedConstOperation.less
1556 ], ints: [
1557 1,
1558 2
1559 ]);
1560 }
1561
1562 test_constExpr_binary_lessEqual() {
1563 UnlinkedVariable variable = serializeVariableText('const v = 1 <= 2;');
1564 _assertUnlinkedConst(variable.constExpr, operators: [
1565 UnlinkedConstOperation.pushInt,
1566 UnlinkedConstOperation.pushInt,
1567 UnlinkedConstOperation.lessEqual
1568 ], ints: [
1569 1,
1570 2
1571 ]);
1572 }
1573
1574 test_constExpr_binary_modulo() {
1575 UnlinkedVariable variable = serializeVariableText('const v = 1 % 2;');
1576 _assertUnlinkedConst(variable.constExpr, operators: [
1577 UnlinkedConstOperation.pushInt,
1578 UnlinkedConstOperation.pushInt,
1579 UnlinkedConstOperation.modulo
1580 ], ints: [
1581 1,
1582 2
1583 ]);
1584 }
1585
1586 test_constExpr_binary_multiply() {
1587 UnlinkedVariable variable = serializeVariableText('const v = 1 * 2;');
1588 _assertUnlinkedConst(variable.constExpr, operators: [
1589 UnlinkedConstOperation.pushInt,
1590 UnlinkedConstOperation.pushInt,
1591 UnlinkedConstOperation.multiply
1592 ], ints: [
1593 1,
1594 2
1595 ]);
1596 }
1597
1598 test_constExpr_binary_or() {
1599 UnlinkedVariable variable =
1600 serializeVariableText('const v = false || true;');
1601 _assertUnlinkedConst(variable.constExpr, operators: [
1602 UnlinkedConstOperation.pushFalse,
1603 UnlinkedConstOperation.pushTrue,
1604 UnlinkedConstOperation.or
1605 ]);
1606 }
1607
1608 test_constExpr_binary_subtract() {
1609 UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
1610 _assertUnlinkedConst(variable.constExpr, operators: [
1611 UnlinkedConstOperation.pushInt,
1612 UnlinkedConstOperation.pushInt,
1613 UnlinkedConstOperation.subtract
1614 ], ints: [
1615 1,
1616 2
1617 ]);
1618 }
1619
1620 test_constExpr_conditional() {
1621 UnlinkedVariable variable =
1622 serializeVariableText('const v = true ? 1 : 2;', allowErrors: true);
1623 _assertUnlinkedConst(variable.constExpr, operators: [
1624 UnlinkedConstOperation.pushTrue,
1625 UnlinkedConstOperation.pushInt,
1626 UnlinkedConstOperation.pushInt,
1627 UnlinkedConstOperation.conditional
1628 ], ints: [
1629 1,
1630 2
1631 ]);
1632 }
1633
1634 test_constExpr_identical() {
1635 UnlinkedVariable variable =
1636 serializeVariableText('const v = identical(42, null);');
1637 _assertUnlinkedConst(variable.constExpr, operators: [
1638 UnlinkedConstOperation.pushInt,
1639 UnlinkedConstOperation.pushNull,
1640 UnlinkedConstOperation.identical
1641 ], ints: [
1642 42
1643 ]);
1644 }
1645
1646 test_constExpr_invokeConstructor_named() {
1647 if (checkAstDerivedData) {
1648 // TODO(scheglov) at the moment we cannot link class member references
1649 return;
1650 }
1651 UnlinkedVariable variable = serializeVariableText('''
1652 class C {
1653 const C.named();
1654 }
1655 const v = const C.named();
1656 ''');
1657 _assertUnlinkedConst(variable.constExpr, operators: [
1658 UnlinkedConstOperation.invokeConstructor,
1659 ], ints: [
1660 0
1661 ], strings: [
1662 'named'
1663 ], referenceValidators: [
1664 (TypeRef r) => checkTypeRef(r, null, null, 'C',
1665 expectedKind: ReferenceKind.classOrEnum)
1666 ]);
1667 }
1668
1669 test_constExpr_invokeConstructor_named_imported() {
1670 if (checkAstDerivedData) {
1671 // TODO(scheglov) at the moment we cannot link class member references
1672 return;
1673 }
1674 addNamedSource(
1675 '/a.dart',
1676 '''
1677 class C {
1678 const C.named();
1679 }
1680 ''');
1681 UnlinkedVariable variable = serializeVariableText('''
1682 import 'a.dart';
1683 const v = const C.named();
1684 ''');
1685 _assertUnlinkedConst(variable.constExpr, operators: [
1686 UnlinkedConstOperation.invokeConstructor,
1687 ], ints: [
1688 0
1689 ], strings: [
1690 'named'
1691 ], referenceValidators: [
1692 (TypeRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
1693 expectedKind: ReferenceKind.classOrEnum)
1694 ]);
1695 }
1696
1697 test_constExpr_invokeConstructor_named_imported_withPrefix() {
1698 addNamedSource(
1699 '/a.dart',
1700 '''
1701 class C {
1702 const C.named();
1703 }
1704 ''');
1705 UnlinkedVariable variable = serializeVariableText('''
1706 import 'a.dart' as p;
1707 const v = const p.C.named();
1708 ''');
1709 _assertUnlinkedConst(variable.constExpr, operators: [
1710 UnlinkedConstOperation.invokeConstructor,
1711 ], ints: [
1712 0
1713 ], strings: [
1714 'named'
1715 ], referenceValidators: [
1716 (TypeRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
1717 expectedKind: ReferenceKind.classOrEnum, expectedPrefix: 'p')
1718 ]);
1719 }
1720
1721 test_constExpr_invokeConstructor_unnamed() {
1722 UnlinkedVariable variable = serializeVariableText('''
1723 class C {
1724 const C(int a, String b);
1725 }
1726 const v = const C(42, 'sss');
1727 ''');
1728 _assertUnlinkedConst(variable.constExpr, operators: [
1729 UnlinkedConstOperation.pushInt,
1730 UnlinkedConstOperation.pushString,
1731 UnlinkedConstOperation.invokeConstructor,
1732 ], ints: [
1733 42,
1734 2
1735 ], strings: [
1736 'sss',
1737 ''
1738 ], referenceValidators: [
1739 (TypeRef r) => checkTypeRef(r, null, null, 'C',
1740 expectedKind: ReferenceKind.classOrEnum)
1741 ]);
1742 }
1743
1744 test_constExpr_length() {
1745 UnlinkedVariable variable =
1746 serializeVariableText('const v = "abc".length;');
1747 _assertUnlinkedConst(variable.constExpr,
1748 operators:
1749 [UnlinkedConstOperation.pushString, UnlinkedConstOperation.length],
1750 strings: ['abc']);
1751 }
1752
1753 test_constExpr_makeList_typed() {
1754 UnlinkedVariable variable =
1755 serializeVariableText('const v = const <int>[11, 22, 33];');
1756 _assertUnlinkedConst(variable.constExpr, operators: [
1757 UnlinkedConstOperation.pushInt,
1758 UnlinkedConstOperation.pushInt,
1759 UnlinkedConstOperation.pushInt,
1760 UnlinkedConstOperation.makeList
1761 ], ints: [
1762 11,
1763 22,
1764 33,
1765 3
1766 ], referenceValidators: [
1767 (TypeRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int',
1768 expectedKind: ReferenceKind.classOrEnum)
1769 ]);
1770 }
1771
1772 test_constExpr_makeList_untyped() {
1773 UnlinkedVariable variable =
1774 serializeVariableText('const v = const [11, 22, 33];');
1775 _assertUnlinkedConst(variable.constExpr, operators: [
1776 UnlinkedConstOperation.pushInt,
1777 UnlinkedConstOperation.pushInt,
1778 UnlinkedConstOperation.pushInt,
1779 UnlinkedConstOperation.makeList
1780 ], ints: [
1781 11,
1782 22,
1783 33,
1784 3
1785 ], referenceValidators: [
1786 (TypeRef r) => checkTypeRef(r, null, null, '',
1787 expectedKind: ReferenceKind.classOrEnum)
1788 ]);
1789 }
1790
1791 test_constExpr_makeMap_typed() {
1792 UnlinkedVariable variable = serializeVariableText(
1793 'const v = const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
1794 _assertUnlinkedConst(variable.constExpr, operators: [
1795 UnlinkedConstOperation.pushInt,
1796 UnlinkedConstOperation.pushString,
1797 UnlinkedConstOperation.pushInt,
1798 UnlinkedConstOperation.pushString,
1799 UnlinkedConstOperation.pushInt,
1800 UnlinkedConstOperation.pushString,
1801 UnlinkedConstOperation.makeMap
1802 ], ints: [
1803 11,
1804 22,
1805 33,
1806 3
1807 ], strings: [
1808 'aaa',
1809 'bbb',
1810 'ccc'
1811 ], referenceValidators: [
1812 (TypeRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'int',
1813 expectedKind: ReferenceKind.classOrEnum),
1814 (TypeRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'String',
1815 expectedKind: ReferenceKind.classOrEnum)
1816 ]);
1817 }
1818
1819 test_constExpr_makeMap_untyped() {
1820 UnlinkedVariable variable = serializeVariableText(
1821 'const v = const {11: "aaa", 22: "bbb", 33: "ccc"};');
1822 _assertUnlinkedConst(variable.constExpr, operators: [
1823 UnlinkedConstOperation.pushInt,
1824 UnlinkedConstOperation.pushString,
1825 UnlinkedConstOperation.pushInt,
1826 UnlinkedConstOperation.pushString,
1827 UnlinkedConstOperation.pushInt,
1828 UnlinkedConstOperation.pushString,
1829 UnlinkedConstOperation.makeMap
1830 ], ints: [
1831 11,
1832 22,
1833 33,
1834 3
1835 ], strings: [
1836 'aaa',
1837 'bbb',
1838 'ccc'
1839 ], referenceValidators: [
1840 (TypeRef r) => checkTypeRef(r, null, null, '',
1841 expectedKind: ReferenceKind.classOrEnum),
1842 (TypeRef r) => checkTypeRef(r, null, null, '',
1843 expectedKind: ReferenceKind.classOrEnum)
1844 ]);
1845 }
1846
1847 test_constExpr_makeSymbol() {
1848 UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;');
1849 _assertUnlinkedConst(variable.constExpr, operators: [
1850 UnlinkedConstOperation.pushString,
1851 UnlinkedConstOperation.makeSymbol
1852 ], strings: [
1853 'a.bb.ccc'
1854 ]);
1855 }
1856
1857 test_constExpr_parenthesized() {
1858 UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;');
1859 _assertUnlinkedConst(variable.constExpr, operators: [
1860 UnlinkedConstOperation.pushInt,
1861 UnlinkedConstOperation.pushInt,
1862 UnlinkedConstOperation.add,
1863 UnlinkedConstOperation.pushInt,
1864 UnlinkedConstOperation.multiply,
1865 ], ints: [
1866 1,
1867 2,
1868 3
1869 ]);
1870 }
1871
1872 test_constExpr_prefix_complement() {
1873 UnlinkedVariable variable = serializeVariableText('const v = ~2;');
1874 _assertUnlinkedConst(variable.constExpr,
1875 operators:
1876 [UnlinkedConstOperation.pushInt, UnlinkedConstOperation.complement],
1877 ints: [2]);
1878 }
1879
1880 test_constExpr_prefix_negate() {
1881 UnlinkedVariable variable = serializeVariableText('const v = -(2);');
1882 _assertUnlinkedConst(variable.constExpr,
1883 operators:
1884 [UnlinkedConstOperation.pushInt, UnlinkedConstOperation.negate],
1885 ints: [2]);
1886 }
1887
1888 test_constExpr_prefix_not() {
1889 UnlinkedVariable variable = serializeVariableText('const v = !true;');
1890 _assertUnlinkedConst(variable.constExpr, operators:
1891 [UnlinkedConstOperation.pushTrue, UnlinkedConstOperation.not]);
1892 }
1893
1894 test_constExpr_pushDouble() {
1895 UnlinkedVariable variable = serializeVariableText('const v = 123.4567;');
1896 _assertUnlinkedConst(variable.constExpr,
1897 operators: [UnlinkedConstOperation.pushDouble], doubles: [123.4567]);
1898 }
1899
1900 test_constExpr_pushFalse() {
1901 UnlinkedVariable variable = serializeVariableText('const v = false;');
1902 _assertUnlinkedConst(variable.constExpr,
1903 operators: [UnlinkedConstOperation.pushFalse]);
1904 }
1905
1906 test_constExpr_pushInt() {
1907 UnlinkedVariable variable = serializeVariableText('const v = 1;');
1908 _assertUnlinkedConst(variable.constExpr,
1909 operators: [UnlinkedConstOperation.pushInt], ints: [1]);
1910 }
1911
1912 test_constExpr_pushNull() {
1913 UnlinkedVariable variable = serializeVariableText('const v = null;');
1914 _assertUnlinkedConst(variable.constExpr,
1915 operators: [UnlinkedConstOperation.pushNull]);
1916 }
1917
1918 test_constExpr_pushReference_class() {
1919 UnlinkedVariable variable = serializeVariableText('''
1920 class C {}
1921 const v = C;
1922 ''');
1923 _assertUnlinkedConst(variable.constExpr, operators: [
1924 UnlinkedConstOperation.pushReference
1925 ], referenceValidators: [
1926 (TypeRef r) => checkTypeRef(r, null, null, 'C',
1927 expectedKind: ReferenceKind.classOrEnum)
1928 ]);
1929 }
1930
1931 test_constExpr_pushReference_class_field() {
1932 // TODO(scheglov) Not sure for to represent a field reference
1933 // using TypeRef.
1934 // UnlinkedVariable variable = serializeVariableText('''
1935 //class C {
1936 // static const int F = 1;
1937 //}
1938 //const v = C.F;
1939 //''');
1940 // _assertUnlinkedConst(variable.constExpr, operators: [
1941 // UnlinkedConstOperation.pushReference
1942 // ], references: [
1943 // (TypeRef r) => checkTypeRef(r, null, null, 'F',
1944 // expectedKind: ReferenceKind.classOrEnum, expectedPrefix: 'C')
1945 // ]);
1946 }
1947
1948 test_constExpr_pushReference_enum() {
1949 UnlinkedVariable variable = serializeVariableText('''
1950 enum C {V1, V2, V3}
1951 const v = C;
1952 ''');
1953 _assertUnlinkedConst(variable.constExpr, operators: [
1954 UnlinkedConstOperation.pushReference
1955 ], referenceValidators: [
1956 (TypeRef r) => checkTypeRef(r, null, null, 'C',
1957 expectedKind: ReferenceKind.classOrEnum)
1958 ]);
1959 }
1960
1961 test_constExpr_pushReference_topLevelVariable_imported() {
1962 addNamedSource('/a.dart', 'const int a = 1;');
1963 UnlinkedVariable variable = serializeVariableText('''
1964 import 'a.dart';
1965 const v = a;
1966 ''');
1967 _assertUnlinkedConst(variable.constExpr, operators: [
1968 UnlinkedConstOperation.pushReference
1969 ], referenceValidators: [
1970 (TypeRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
1971 expectedKind: ReferenceKind.topLevelPropertyAccessor)
1972 ]);
1973 }
1974
1975 test_constExpr_pushReference_topLevelVariable_imported_withPrefix() {
1976 addNamedSource('/a.dart', 'const int a = 1;');
1977 UnlinkedVariable variable = serializeVariableText('''
1978 import 'a.dart' as p;
1979 const v = p.a;
1980 ''');
1981 _assertUnlinkedConst(variable.constExpr, operators: [
1982 UnlinkedConstOperation.pushReference
1983 ], referenceValidators: [
1984 (TypeRef r) {
1985 return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
1986 expectedKind: ReferenceKind.topLevelPropertyAccessor,
1987 expectedPrefix: 'p');
1988 }
1989 ]);
1990 }
1991
1992 test_constExpr_pushReference_topLevelVariable_local() {
1993 // TODO(scheglov) use `a + b`
1994 UnlinkedVariable variable = serializeVariableText('''
1995 const int a = 1;
1996 const v = a;
1997 ''');
1998 _assertUnlinkedConst(variable.constExpr, operators: [
1999 UnlinkedConstOperation.pushReference
2000 ], referenceValidators: [
2001 (TypeRef r) => checkTypeRef(r, null, null, 'a',
2002 expectedKind: ReferenceKind.topLevelPropertyAccessor)
2003 ]);
2004 }
2005
2006 test_constExpr_pushString_adjacent() {
2007 UnlinkedVariable variable =
2008 serializeVariableText('const v = "aaa" "b" "ccc";');
2009 _assertUnlinkedConst(variable.constExpr,
2010 operators: [UnlinkedConstOperation.pushString], strings: ['aaabccc']);
2011 }
2012
2013 test_constExpr_pushString_adjacent_interpolation() {
2014 UnlinkedVariable variable =
2015 serializeVariableText(r'const v = "aaa" "bb ${42} bbb" "cccc";');
2016 _assertUnlinkedConst(variable.constExpr, operators: [
2017 UnlinkedConstOperation.pushString,
2018 UnlinkedConstOperation.pushString,
2019 UnlinkedConstOperation.pushInt,
2020 UnlinkedConstOperation.pushString,
2021 UnlinkedConstOperation.concatenate,
2022 UnlinkedConstOperation.pushString,
2023 UnlinkedConstOperation.concatenate,
2024 ], ints: [
2025 42,
2026 3,
2027 3,
2028 ], strings: [
2029 'aaa',
2030 'bb ',
2031 ' bbb',
2032 'cccc'
2033 ]);
2034 }
2035
2036 test_constExpr_pushString_interpolation() {
2037 UnlinkedVariable variable =
2038 serializeVariableText(r'const v = "aaa ${42} bbb";');
2039 _assertUnlinkedConst(variable.constExpr, operators: [
2040 UnlinkedConstOperation.pushString,
2041 UnlinkedConstOperation.pushInt,
2042 UnlinkedConstOperation.pushString,
2043 UnlinkedConstOperation.concatenate
2044 ], ints: [
2045 42,
2046 3
2047 ], strings: [
2048 'aaa ',
2049 ' bbb'
2050 ]);
2051 }
2052
2053 test_constExpr_pushString_simple() {
2054 UnlinkedVariable variable = serializeVariableText('const v = "abc";');
2055 _assertUnlinkedConst(variable.constExpr,
2056 operators: [UnlinkedConstOperation.pushString], strings: ['abc']);
2057 }
2058
2059 test_constExpr_pushTrue() {
2060 UnlinkedVariable variable = serializeVariableText('const v = true;');
2061 _assertUnlinkedConst(variable.constExpr,
2062 operators: [UnlinkedConstOperation.pushTrue]);
2063 }
2064
2065 test_constructor() {
2066 String text = 'class C { C(); }';
2067 UnlinkedExecutable executable =
2068 findExecutable('', executables: serializeClassText(text).executables);
2069 expect(executable.kind, UnlinkedExecutableKind.constructor);
2070 expect(executable.hasImplicitReturnType, isFalse);
2071 expect(executable.isExternal, isFalse);
2072 expect(executable.nameOffset, text.indexOf('C();'));
2073 }
2074
2075 test_constructor_anonymous() {
2076 UnlinkedExecutable executable = findExecutable('',
2077 executables: serializeClassText('class C { C(); }').executables);
2078 expect(executable.name, isEmpty);
2079 }
2080
2081 test_constructor_const() {
2082 UnlinkedExecutable executable = findExecutable('',
2083 executables: serializeClassText('class C { const C(); }').executables);
2084 expect(executable.isConst, isTrue);
2085 expect(executable.isExternal, isFalse);
2086 }
2087
2088 test_constructor_const_external() {
2089 UnlinkedExecutable executable = findExecutable('',
2090 executables:
2091 serializeClassText('class C { external const C(); }').executables);
2092 expect(executable.isConst, isTrue);
2093 expect(executable.isExternal, isTrue);
2094 }
2095
2096 test_constructor_documented() {
2097 String text = '''
2098 class C {
2099 /**
2100 * Docs
2101 */
2102 C();
2103 }''';
2104 UnlinkedExecutable executable = serializeClassText(text).executables[0];
2105 expect(executable.documentationComment, isNotNull);
2106 checkDocumentationComment(executable.documentationComment, text);
2107 }
2108
2109 test_constructor_external() {
2110 UnlinkedExecutable executable = findExecutable('',
2111 executables:
2112 serializeClassText('class C { external C(); }').executables);
2113 expect(executable.isExternal, isTrue);
2114 }
2115
2116 test_constructor_factory() {
2117 UnlinkedExecutable executable = findExecutable('',
2118 executables:
2119 serializeClassText('class C { factory C() => null; }').executables);
2120 expect(executable.isFactory, isTrue);
2121 }
2122
2123 test_constructor_implicit() {
2124 // Implicit constructors are not serialized.
2125 UnlinkedExecutable executable = findExecutable(null,
2126 executables: serializeClassText('class C { C(); }').executables,
2127 failIfAbsent: false);
2128 expect(executable, isNull);
2129 }
2130
2131 test_constructor_initializing_formal() {
2132 UnlinkedExecutable executable = findExecutable('',
2133 executables:
2134 serializeClassText('class C { C(this.x); final x; }').executables);
2135 UnlinkedParam parameter = executable.parameters[0];
2136 expect(parameter.isInitializingFormal, isTrue);
2137 }
2138
2139 test_constructor_initializing_formal_explicit_type() {
2140 UnlinkedExecutable executable = findExecutable('',
2141 executables: serializeClassText('class C { C(int this.x); final x; }')
2142 .executables);
2143 UnlinkedParam parameter = executable.parameters[0];
2144 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
2145 }
2146
2147 test_constructor_initializing_formal_function_typed() {
2148 UnlinkedExecutable executable = findExecutable('',
2149 executables: serializeClassText('class C { C(this.x()); final x; }')
2150 .executables);
2151 UnlinkedParam parameter = executable.parameters[0];
2152 expect(parameter.isFunctionTyped, isTrue);
2153 }
2154
2155 test_constructor_initializing_formal_function_typed_explicit_return_type() {
2156 UnlinkedExecutable executable = findExecutable('',
2157 executables:
2158 serializeClassText('class C { C(int this.x()); Function x; }')
2159 .executables);
2160 UnlinkedParam parameter = executable.parameters[0];
2161 checkTypeRef(parameter.type, 'dart:core', 'dart:core', 'int');
2162 }
2163
2164 test_constructor_initializing_formal_function_typed_implicit_return_type() {
2165 UnlinkedExecutable executable = findExecutable('',
2166 executables: serializeClassText('class C { C(this.x()); Function x; }')
2167 .executables);
2168 UnlinkedParam parameter = executable.parameters[0];
2169 // Since the parameter is function-typed it is considered to have an
2170 // explicit type, even though that explicit type itself has an implicit
2171 // return type.
2172 expect(parameter.hasImplicitType, isFalse);
2173 checkDynamicTypeRef(parameter.type);
2174 }
2175
2176 test_constructor_initializing_formal_function_typed_no_parameters() {
2177 UnlinkedExecutable executable = findExecutable('',
2178 executables: serializeClassText('class C { C(this.x()); final x; }')
2179 .executables);
2180 UnlinkedParam parameter = executable.parameters[0];
2181 expect(parameter.parameters, isEmpty);
2182 }
2183
2184 test_constructor_initializing_formal_function_typed_parameter() {
2185 UnlinkedExecutable executable = findExecutable('',
2186 executables: serializeClassText('class C { C(this.x(a)); final x; }')
2187 .executables);
2188 UnlinkedParam parameter = executable.parameters[0];
2189 expect(parameter.parameters, hasLength(1));
2190 }
2191
2192 test_constructor_initializing_formal_function_typed_parameter_order() {
2193 UnlinkedExecutable executable = findExecutable('',
2194 executables: serializeClassText('class C { C(this.x(a, b)); final x; }')
2195 .executables);
2196 UnlinkedParam parameter = executable.parameters[0];
2197 expect(parameter.parameters, hasLength(2));
2198 expect(parameter.parameters[0].name, 'a');
2199 expect(parameter.parameters[1].name, 'b');
2200 }
2201
2202 test_constructor_initializing_formal_implicit_type() {
2203 // Note: the implicit type of an initializing formal is the type of the
2204 // field.
2205 UnlinkedExecutable executable = findExecutable('',
2206 executables:
2207 serializeClassText('class C { C(this.x); int x; }').executables);
2208 UnlinkedParam parameter = executable.parameters[0];
2209 expect(parameter.type, isNull);
2210 expect(parameter.hasImplicitType, isTrue);
2211 }
2212
2213 test_constructor_initializing_formal_name() {
2214 UnlinkedExecutable executable = findExecutable('',
2215 executables:
2216 serializeClassText('class C { C(this.x); final x; }').executables);
2217 UnlinkedParam parameter = executable.parameters[0];
2218 expect(parameter.name, 'x');
2219 }
2220
2221 test_constructor_initializing_formal_named() {
2222 // TODO(paulberry): also test default value
2223 UnlinkedExecutable executable = findExecutable('',
2224 executables: serializeClassText('class C { C({this.x}); final x; }')
2225 .executables);
2226 UnlinkedParam parameter = executable.parameters[0];
2227 expect(parameter.kind, UnlinkedParamKind.named);
2228 }
2229
2230 test_constructor_initializing_formal_non_function_typed() {
2231 UnlinkedExecutable executable = findExecutable('',
2232 executables:
2233 serializeClassText('class C { C(this.x); final x; }').executables);
2234 UnlinkedParam parameter = executable.parameters[0];
2235 expect(parameter.isFunctionTyped, isFalse);
2236 }
2237
2238 test_constructor_initializing_formal_positional() {
2239 // TODO(paulberry): also test default value
2240 UnlinkedExecutable executable = findExecutable('',
2241 executables: serializeClassText('class C { C([this.x]); final x; }')
2242 .executables);
2243 UnlinkedParam parameter = executable.parameters[0];
2244 expect(parameter.kind, UnlinkedParamKind.positional);
2245 }
2246
2247 test_constructor_initializing_formal_required() {
2248 UnlinkedExecutable executable = findExecutable('',
2249 executables:
2250 serializeClassText('class C { C(this.x); final x; }').executables);
2251 UnlinkedParam parameter = executable.parameters[0];
2252 expect(parameter.kind, UnlinkedParamKind.required);
2253 }
2254
2255 test_constructor_initializing_formal_typedef() {
2256 UnlinkedExecutable executable = findExecutable('',
2257 executables: serializeClassText(
2258 'typedef F<T>(T x); class C<X> { C(this.f); F<X> f; }')
2259 .executables);
2260 UnlinkedParam parameter = executable.parameters[0];
2261 expect(parameter.isFunctionTyped, isFalse);
2262 expect(parameter.parameters, isEmpty);
2263 }
2264
2265 test_constructor_named() {
2266 String text = 'class C { C.foo(); }';
2267 UnlinkedExecutable executable = findExecutable('foo',
2268 executables: serializeClassText(text).executables);
2269 expect(executable.name, 'foo');
2270 expect(executable.nameOffset, text.indexOf('foo'));
2271 }
2272
2273 test_constructor_non_const() {
2274 UnlinkedExecutable executable = findExecutable('',
2275 executables: serializeClassText('class C { C(); }').executables);
2276 expect(executable.isConst, isFalse);
2277 }
2278
2279 test_constructor_non_factory() {
2280 UnlinkedExecutable executable = findExecutable('',
2281 executables: serializeClassText('class C { C(); }').executables);
2282 expect(executable.isFactory, isFalse);
2283 }
2284
2285 test_constructor_return_type() {
2286 UnlinkedExecutable executable = findExecutable('',
2287 executables: serializeClassText('class C { C(); }').executables);
2288 expect(executable.returnType, isNull);
2289 }
2290
2291 test_constructor_return_type_parameterized() {
2292 UnlinkedExecutable executable = findExecutable('',
2293 executables: serializeClassText('class C<T, U> { C(); }').executables);
2294 expect(executable.returnType, isNull);
2295 }
2296
2297 test_dependencies_export_to_export_unused() {
2298 // TODO(paulberry): fix this test.
2299 addNamedSource('/a.dart', 'export "b.dart";');
2300 addNamedSource('/b.dart', '');
2301 serializeLibraryText('export "a.dart";');
2302 // The main test library depends on b.dart, even though it doesn't
2303 // re-export any names defined in b.dart, because a change to b.dart might
2304 // cause it to start exporting a name that the main test library *does*
2305 // use.
2306 checkHasDependency(absUri('/b.dart'), 'b.dart');
2307 }
2308
2309 test_dependencies_export_unused() {
2310 // TODO(paulberry): fix this test.
2311 addNamedSource('/a.dart', '');
2312 serializeLibraryText('export "a.dart";');
2313 // The main test library depends on a.dart, even though it doesn't
2314 // re-export any names defined in a.dart, because a change to a.dart might
2315 // cause it to start exporting a name that the main test library *will*
2316 // re-export.
2317 checkHasDependency(absUri('/a.dart'), 'a.dart');
2318 }
2319
2320 test_dependencies_import_to_export() {
2321 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
2322 addNamedSource('/b.dart', 'library b;');
2323 serializeLibraryText('import "a.dart"; A a;');
2324 checkHasDependency(absUri('/a.dart'), 'a.dart');
2325 // The main test library depends on b.dart, because names defined in
2326 // b.dart are exported by a.dart.
2327 checkHasDependency(absUri('/b.dart'), 'b.dart');
2328 }
2329
2330 test_dependencies_import_to_export_in_subdirs_absolute_export() {
2331 addNamedSource('/a/a.dart',
2332 'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
2333 addNamedSource('/a/b/b.dart', 'library b;');
2334 serializeLibraryText('import "a/a.dart"; A a;');
2335 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
2336 // The main test library depends on b.dart, because names defined in
2337 // b.dart are exported by a.dart.
2338 checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
2339 }
2340
2341 test_dependencies_import_to_export_in_subdirs_absolute_import() {
2342 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
2343 addNamedSource('/a/b/b.dart', 'library b;');
2344 serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
2345 checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
2346 // The main test library depends on b.dart, because names defined in
2347 // b.dart are exported by a.dart.
2348 checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
2349 }
2350
2351 test_dependencies_import_to_export_in_subdirs_relative() {
2352 addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
2353 addNamedSource('/a/b/b.dart', 'library b;');
2354 serializeLibraryText('import "a/a.dart"; A a;');
2355 checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
2356 // The main test library depends on b.dart, because names defined in
2357 // b.dart are exported by a.dart.
2358 checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
2359 }
2360
2361 test_dependencies_import_to_export_loop() {
2362 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
2363 addNamedSource('/b.dart', 'library b; export "a.dart";');
2364 serializeLibraryText('import "a.dart"; A a;');
2365 checkHasDependency(absUri('/a.dart'), 'a.dart');
2366 // Serialization should have been able to walk the transitive export
2367 // dependencies to b.dart without going into an infinite loop.
2368 checkHasDependency(absUri('/b.dart'), 'b.dart');
2369 }
2370
2371 test_dependencies_import_to_export_transitive_closure() {
2372 addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
2373 addNamedSource('/b.dart', 'library b; export "c.dart";');
2374 addNamedSource('/c.dart', 'library c;');
2375 serializeLibraryText('import "a.dart"; A a;');
2376 checkHasDependency(absUri('/a.dart'), 'a.dart');
2377 // The main test library depends on c.dart, because names defined in
2378 // c.dart are exported by b.dart and then re-exported by a.dart.
2379 checkHasDependency(absUri('/c.dart'), 'c.dart');
2380 }
2381
2382 test_dependencies_import_to_export_unused() {
2383 addNamedSource('/a.dart', 'export "b.dart";');
2384 addNamedSource('/b.dart', '');
2385 serializeLibraryText('import "a.dart";', allowErrors: true);
2386 // The main test library depends on b.dart, even though it doesn't use any
2387 // names defined in b.dart, because a change to b.dart might cause it to
2388 // start exporting a name that the main test library *does* use.
2389 checkHasDependency(absUri('/b.dart'), 'b.dart');
2390 }
2391
2392 test_dependencies_import_transitive_closure() {
2393 addNamedSource(
2394 '/a.dart', 'library a; import "b.dart"; class A extends B {}');
2395 addNamedSource('/b.dart', 'library b; class B {}');
2396 serializeLibraryText('import "a.dart"; A a;');
2397 checkHasDependency(absUri('/a.dart'), 'a.dart');
2398 // The main test library doesn't depend on b.dart, because no change to
2399 // b.dart can possibly affect the serialized element model for it.
2400 checkLacksDependency(absUri('/b.dart'), 'b.dart');
2401 }
2402
2403 test_dependencies_import_unused() {
2404 addNamedSource('/a.dart', '');
2405 serializeLibraryText('import "a.dart";', allowErrors: true);
2406 // The main test library depends on a.dart, even though it doesn't use any
2407 // names defined in a.dart, because a change to a.dart might cause it to
2408 // start exporting a name that the main test library *does* use.
2409 checkHasDependency(absUri('/a.dart'), 'a.dart');
2410 }
2411
2412 test_dependencies_parts() {
2413 addNamedSource(
2414 '/a.dart', 'library a; part "b.dart"; part "c.dart"; class A {}');
2415 addNamedSource('/b.dart', 'part of a;');
2416 addNamedSource('/c.dart', 'part of a;');
2417 serializeLibraryText('import "a.dart"; A a;');
2418 int dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
2419 checkDependencyParts(linked.dependencies[dep],
2420 [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
2421 }
2422
2423 test_dependencies_parts_relative_to_importing_library() {
2424 addNamedSource('/a/b.dart', 'export "c/d.dart";');
2425 addNamedSource('/a/c/d.dart',
2426 'library d; part "e/f.dart"; part "g/h.dart"; class D {}');
2427 addNamedSource('/a/c/e/f.dart', 'part of d;');
2428 addNamedSource('/a/c/g/h.dart', 'part of d;');
2429 serializeLibraryText('import "a/b.dart"; D d;');
2430 int dep = checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
2431 checkDependencyParts(
2432 linked.dependencies[dep],
2433 [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
2434 ['a/c/e/f.dart', 'a/c/g/h.dart']);
2435 }
2436
2437 test_elements_in_part() {
2438 addNamedSource(
2439 '/part1.dart',
2440 '''
2441 part of my.lib;
2442
2443 class C {}
2444 enum E { v }
2445 var v;
2446 f() {}
2447 typedef F();
2448 ''');
2449 serializeLibraryText('library my.lib; part "part1.dart";');
2450 UnlinkedUnit unit = unlinkedUnits[1];
2451 expect(findClass('C', unit: unit), isNotNull);
2452 expect(findEnum('E', unit: unit), isNotNull);
2453 expect(findVariable('v', variables: unit.variables), isNotNull);
2454 expect(findExecutable('f', executables: unit.executables), isNotNull);
2455 expect(findTypedef('F', unit: unit), isNotNull);
2456 }
2457
2458 test_enum() {
2459 String text = 'enum E { v1 }';
2460 UnlinkedEnum e = serializeEnumText(text);
2461 expect(e.name, 'E');
2462 expect(e.nameOffset, text.indexOf('E'));
2463 expect(e.values, hasLength(1));
2464 expect(e.values[0].name, 'v1');
2465 expect(e.values[0].nameOffset, text.indexOf('v1'));
2466 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
2467 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
2468 ReferenceKind.classOrEnum);
2469 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'E');
2470 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
2471 }
2472
2473 test_enum_documented() {
2474 String text = '''
2475 // Extra comment so doc comment offset != 0
2476 /**
2477 * Docs
2478 */
2479 enum E { v }''';
2480 UnlinkedEnum enm = serializeEnumText(text);
2481 expect(enm.documentationComment, isNotNull);
2482 checkDocumentationComment(enm.documentationComment, text);
2483 }
2484
2485 test_enum_order() {
2486 UnlinkedEnum e = serializeEnumText('enum E { v1, v2 }');
2487 expect(e.values, hasLength(2));
2488 expect(e.values[0].name, 'v1');
2489 expect(e.values[1].name, 'v2');
2490 }
2491
2492 test_enum_private() {
2493 serializeEnumText('enum _E { v1 }', '_E');
2494 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
2495 }
2496
2497 test_executable_abstract() {
2498 UnlinkedExecutable executable =
2499 serializeClassText('abstract class C { f(); }').executables[0];
2500 expect(executable.isAbstract, isTrue);
2501 }
2502
2503 test_executable_concrete() {
2504 UnlinkedExecutable executable =
2505 serializeClassText('abstract class C { f() {} }').executables[0];
2506 expect(executable.isAbstract, isFalse);
2507 }
2508
2509 test_executable_function() {
2510 String text = ' f() {}';
2511 UnlinkedExecutable executable = serializeExecutableText(text);
2512 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
2513 expect(executable.hasImplicitReturnType, isTrue);
2514 checkDynamicTypeRef(executable.returnType);
2515 expect(executable.isExternal, isFalse);
2516 expect(executable.nameOffset, text.indexOf('f'));
2517 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
2518 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
2519 ReferenceKind.topLevelFunction);
2520 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
2521 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
2522 }
2523
2524 test_executable_function_explicit_return() {
2525 UnlinkedExecutable executable =
2526 serializeExecutableText('dynamic f() => null;');
2527 expect(executable.hasImplicitReturnType, isFalse);
2528 checkDynamicTypeRef(executable.returnType);
2529 }
2530
2531 test_executable_function_external() {
2532 UnlinkedExecutable executable = serializeExecutableText('external f();');
2533 expect(executable.isExternal, isTrue);
2534 }
2535
2536 test_executable_function_private() {
2537 serializeExecutableText('_f() {}', '_f');
2538 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
2539 }
2540
2541 test_executable_getter() {
2542 String text = 'int get f => 1;';
2543 UnlinkedExecutable executable = serializeExecutableText(text);
2544 expect(executable.kind, UnlinkedExecutableKind.getter);
2545 expect(executable.hasImplicitReturnType, isFalse);
2546 expect(executable.isExternal, isFalse);
2547 expect(executable.nameOffset, text.indexOf('f'));
2548 expect(findVariable('f'), isNull);
2549 expect(findExecutable('f='), isNull);
2550 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
2551 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
2552 ReferenceKind.topLevelPropertyAccessor);
2553 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f');
2554 }
2555
2556 test_executable_getter_external() {
2557 UnlinkedExecutable executable =
2558 serializeExecutableText('external int get f;');
2559 expect(executable.isExternal, isTrue);
2560 }
2561
2562 test_executable_getter_private() {
2563 serializeExecutableText('int get _f => 1;', '_f');
2564 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
2565 }
2566
2567 test_executable_getter_type() {
2568 UnlinkedExecutable executable = serializeExecutableText('int get f => 1;');
2569 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
2570 expect(executable.parameters, isEmpty);
2571 }
2572
2573 test_executable_getter_type_implicit() {
2574 UnlinkedExecutable executable = serializeExecutableText('get f => 1;');
2575 checkDynamicTypeRef(executable.returnType);
2576 expect(executable.hasImplicitReturnType, isTrue);
2577 expect(executable.parameters, isEmpty);
2578 }
2579
2580 test_executable_member_function() {
2581 UnlinkedExecutable executable = findExecutable('f',
2582 executables: serializeClassText('class C { f() {} }').executables);
2583 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
2584 expect(executable.hasImplicitReturnType, isTrue);
2585 expect(executable.isExternal, isFalse);
2586 }
2587
2588 test_executable_member_function_explicit_return() {
2589 UnlinkedExecutable executable = findExecutable('f',
2590 executables:
2591 serializeClassText('class C { dynamic f() => null; }').executables);
2592 expect(executable.hasImplicitReturnType, isFalse);
2593 }
2594
2595 test_executable_member_function_external() {
2596 UnlinkedExecutable executable = findExecutable('f',
2597 executables:
2598 serializeClassText('class C { external f(); }').executables);
2599 expect(executable.isExternal, isTrue);
2600 }
2601
2602 test_executable_member_getter() {
2603 UnlinkedClass cls = serializeClassText('class C { int get f => 1; }');
2604 UnlinkedExecutable executable =
2605 findExecutable('f', executables: cls.executables, failIfAbsent: true);
2606 expect(executable.kind, UnlinkedExecutableKind.getter);
2607 expect(executable.hasImplicitReturnType, isFalse);
2608 expect(executable.isExternal, isFalse);
2609 expect(findVariable('f', variables: cls.fields), isNull);
2610 expect(findExecutable('f=', executables: cls.executables), isNull);
2611 }
2612
2613 test_executable_member_getter_external() {
2614 UnlinkedClass cls = serializeClassText('class C { external int get f; }');
2615 UnlinkedExecutable executable =
2616 findExecutable('f', executables: cls.executables, failIfAbsent: true);
2617 expect(executable.isExternal, isTrue);
2618 }
2619
2620 test_executable_member_setter() {
2621 UnlinkedClass cls = serializeClassText('class C { void set f(value) {} }');
2622 UnlinkedExecutable executable =
2623 findExecutable('f=', executables: cls.executables, failIfAbsent: true);
2624 expect(executable.kind, UnlinkedExecutableKind.setter);
2625 expect(executable.hasImplicitReturnType, isFalse);
2626 expect(executable.isExternal, isFalse);
2627 expect(findVariable('f', variables: cls.fields), isNull);
2628 expect(findExecutable('f', executables: cls.executables), isNull);
2629 }
2630
2631 test_executable_member_setter_external() {
2632 UnlinkedClass cls =
2633 serializeClassText('class C { external void set f(value); }');
2634 UnlinkedExecutable executable =
2635 findExecutable('f=', executables: cls.executables, failIfAbsent: true);
2636 expect(executable.isExternal, isTrue);
2637 }
2638
2639 test_executable_member_setter_implicit_return() {
2640 UnlinkedClass cls = serializeClassText('class C { set f(value) {} }');
2641 UnlinkedExecutable executable =
2642 findExecutable('f=', executables: cls.executables, failIfAbsent: true);
2643 expect(executable.hasImplicitReturnType, isTrue);
2644 checkDynamicTypeRef(executable.returnType);
2645 }
2646
2647 test_executable_name() {
2648 UnlinkedExecutable executable = serializeExecutableText('f() {}');
2649 expect(executable.name, 'f');
2650 }
2651
2652 test_executable_no_flags() {
2653 UnlinkedExecutable executable = serializeExecutableText('f() {}');
2654 expect(executable.isAbstract, isFalse);
2655 expect(executable.isConst, isFalse);
2656 expect(executable.isFactory, isFalse);
2657 expect(executable.isStatic, isFalse);
2658 }
2659
2660 test_executable_non_static() {
2661 UnlinkedExecutable executable =
2662 serializeClassText('class C { f() {} }').executables[0];
2663 expect(executable.isStatic, isFalse);
2664 }
2665
2666 test_executable_non_static_top_level() {
2667 // Top level executables are considered non-static.
2668 UnlinkedExecutable executable = serializeExecutableText('f() {}');
2669 expect(executable.isStatic, isFalse);
2670 }
2671
2672 test_executable_operator() {
2673 UnlinkedExecutable executable =
2674 serializeClassText('class C { C operator+(C c) => null; }').executables[
2675 0];
2676 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
2677 expect(executable.name, '+');
2678 expect(executable.hasImplicitReturnType, false);
2679 expect(executable.isAbstract, false);
2680 expect(executable.isConst, false);
2681 expect(executable.isFactory, false);
2682 expect(executable.isStatic, false);
2683 expect(executable.parameters, hasLength(1));
2684 checkTypeRef(executable.returnType, null, null, 'C');
2685 expect(executable.typeParameters, isEmpty);
2686 expect(executable.isExternal, false);
2687 }
2688
2689 test_executable_operator_equal() {
2690 UnlinkedExecutable executable =
2691 serializeClassText('class C { bool operator==(C other) => false; }')
2692 .executables[0];
2693 expect(executable.name, '==');
2694 }
2695
2696 test_executable_operator_external() {
2697 UnlinkedExecutable executable =
2698 serializeClassText('class C { external C operator+(C c); }')
2699 .executables[0];
2700 expect(executable.isExternal, true);
2701 }
2702
2703 test_executable_operator_greater_equal() {
2704 UnlinkedExecutable executable =
2705 serializeClassText('class C { bool operator>=(C other) => false; }')
2706 .executables[0];
2707 expect(executable.name, '>=');
2708 }
2709
2710 test_executable_operator_index() {
2711 UnlinkedExecutable executable =
2712 serializeClassText('class C { bool operator[](int i) => null; }')
2713 .executables[0];
2714 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
2715 expect(executable.name, '[]');
2716 expect(executable.hasImplicitReturnType, false);
2717 expect(executable.isAbstract, false);
2718 expect(executable.isConst, false);
2719 expect(executable.isFactory, false);
2720 expect(executable.isStatic, false);
2721 expect(executable.parameters, hasLength(1));
2722 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'bool');
2723 expect(executable.typeParameters, isEmpty);
2724 }
2725
2726 test_executable_operator_index_set() {
2727 UnlinkedExecutable executable = serializeClassText(
2728 'class C { void operator[]=(int i, bool v) => null; }').executables[0];
2729 expect(executable.kind, UnlinkedExecutableKind.functionOrMethod);
2730 expect(executable.name, '[]=');
2731 expect(executable.hasImplicitReturnType, false);
2732 expect(executable.isAbstract, false);
2733 expect(executable.isConst, false);
2734 expect(executable.isFactory, false);
2735 expect(executable.isStatic, false);
2736 expect(executable.parameters, hasLength(2));
2737 expect(executable.returnType, isNull);
2738 expect(executable.typeParameters, isEmpty);
2739 }
2740
2741 test_executable_operator_less_equal() {
2742 UnlinkedExecutable executable =
2743 serializeClassText('class C { bool operator<=(C other) => false; }')
2744 .executables[0];
2745 expect(executable.name, '<=');
2746 }
2747
2748 test_executable_param_function_typed() {
2749 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
2750 expect(executable.parameters[0].isFunctionTyped, isTrue);
2751 // Since the parameter is function-typed it is considered to have an
2752 // explicit type, even though that explicit type itself has an implicit
2753 // return type.
2754 expect(executable.parameters[0].hasImplicitType, isFalse);
2755 }
2756
2757 test_executable_param_function_typed_explicit_return_type() {
2758 UnlinkedExecutable executable =
2759 serializeExecutableText('f(dynamic g()) {}');
2760 expect(executable.parameters[0].hasImplicitType, isFalse);
2761 }
2762
2763 test_executable_param_function_typed_param() {
2764 UnlinkedExecutable executable = serializeExecutableText('f(g(x)) {}');
2765 expect(executable.parameters[0].parameters, hasLength(1));
2766 }
2767
2768 test_executable_param_function_typed_param_none() {
2769 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
2770 expect(executable.parameters[0].parameters, isEmpty);
2771 }
2772
2773 test_executable_param_function_typed_param_order() {
2774 UnlinkedExecutable executable = serializeExecutableText('f(g(x, y)) {}');
2775 expect(executable.parameters[0].parameters, hasLength(2));
2776 expect(executable.parameters[0].parameters[0].name, 'x');
2777 expect(executable.parameters[0].parameters[1].name, 'y');
2778 }
2779
2780 test_executable_param_function_typed_return_type() {
2781 UnlinkedExecutable executable = serializeExecutableText('f(int g()) {}');
2782 checkTypeRef(
2783 executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
2784 }
2785
2786 test_executable_param_function_typed_return_type_implicit() {
2787 UnlinkedExecutable executable = serializeExecutableText('f(g()) {}');
2788 checkDynamicTypeRef(executable.parameters[0].type);
2789 }
2790
2791 test_executable_param_function_typed_return_type_void() {
2792 UnlinkedExecutable executable = serializeExecutableText('f(void g()) {}');
2793 expect(executable.parameters[0].type, isNull);
2794 }
2795
2796 test_executable_param_kind_named() {
2797 UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
2798 expect(executable.parameters[0].kind, UnlinkedParamKind.named);
2799 }
2800
2801 test_executable_param_kind_positional() {
2802 UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
2803 expect(executable.parameters[0].kind, UnlinkedParamKind.positional);
2804 }
2805
2806 test_executable_param_kind_required() {
2807 UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
2808 expect(executable.parameters[0].kind, UnlinkedParamKind.required);
2809 }
2810
2811 test_executable_param_name() {
2812 String text = 'f(x) {}';
2813 UnlinkedExecutable executable = serializeExecutableText(text);
2814 expect(executable.parameters, hasLength(1));
2815 expect(executable.parameters[0].name, 'x');
2816 expect(executable.parameters[0].nameOffset, text.indexOf('x'));
2817 }
2818
2819 test_executable_param_no_flags() {
2820 UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
2821 expect(executable.parameters[0].isFunctionTyped, isFalse);
2822 expect(executable.parameters[0].isInitializingFormal, isFalse);
2823 }
2824
2825 test_executable_param_non_function_typed() {
2826 UnlinkedExecutable executable = serializeExecutableText('f(g) {}');
2827 expect(executable.parameters[0].isFunctionTyped, isFalse);
2828 }
2829
2830 test_executable_param_none() {
2831 UnlinkedExecutable executable = serializeExecutableText('f() {}');
2832 expect(executable.parameters, isEmpty);
2833 }
2834
2835 test_executable_param_order() {
2836 UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
2837 expect(executable.parameters, hasLength(2));
2838 expect(executable.parameters[0].name, 'x');
2839 expect(executable.parameters[1].name, 'y');
2840 }
2841
2842 test_executable_param_type_explicit() {
2843 UnlinkedExecutable executable = serializeExecutableText('f(dynamic x) {}');
2844 checkDynamicTypeRef(executable.parameters[0].type);
2845 expect(executable.parameters[0].hasImplicitType, isFalse);
2846 }
2847
2848 test_executable_param_type_implicit() {
2849 UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
2850 checkDynamicTypeRef(executable.parameters[0].type);
2851 expect(executable.parameters[0].hasImplicitType, isTrue);
2852 }
2853
2854 test_executable_return_type() {
2855 UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
2856 checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
2857 expect(executable.hasImplicitReturnType, isFalse);
2858 }
2859
2860 test_executable_return_type_implicit() {
2861 UnlinkedExecutable executable = serializeExecutableText('f() {}');
2862 checkDynamicTypeRef(executable.returnType);
2863 expect(executable.hasImplicitReturnType, isTrue);
2864 }
2865
2866 test_executable_return_type_void() {
2867 UnlinkedExecutable executable = serializeExecutableText('void f() {}');
2868 expect(executable.returnType, isNull);
2869 }
2870
2871 test_executable_setter() {
2872 String text = 'void set f(value) {}';
2873 UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
2874 expect(executable.kind, UnlinkedExecutableKind.setter);
2875 expect(executable.hasImplicitReturnType, isFalse);
2876 expect(executable.isExternal, isFalse);
2877 expect(executable.nameOffset, text.indexOf('f'));
2878 expect(findVariable('f'), isNull);
2879 expect(findExecutable('f'), isNull);
2880 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
2881 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
2882 ReferenceKind.topLevelPropertyAccessor);
2883 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'f=');
2884 }
2885
2886 test_executable_setter_external() {
2887 UnlinkedExecutable executable =
2888 serializeExecutableText('external void set f(value);', 'f=');
2889 expect(executable.isExternal, isTrue);
2890 }
2891
2892 test_executable_setter_implicit_return() {
2893 UnlinkedExecutable executable =
2894 serializeExecutableText('set f(value) {}', 'f=');
2895 expect(executable.hasImplicitReturnType, isTrue);
2896 checkDynamicTypeRef(executable.returnType);
2897 }
2898
2899 test_executable_setter_private() {
2900 serializeExecutableText('void set _f(value) {}', '_f=');
2901 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
2902 }
2903
2904 test_executable_setter_type() {
2905 UnlinkedExecutable executable =
2906 serializeExecutableText('void set f(int value) {}', 'f=');
2907 expect(executable.returnType, isNull);
2908 expect(executable.parameters, hasLength(1));
2909 expect(executable.parameters[0].name, 'value');
2910 checkTypeRef(
2911 executable.parameters[0].type, 'dart:core', 'dart:core', 'int');
2912 }
2913
2914 test_executable_static() {
2915 UnlinkedExecutable executable =
2916 serializeClassText('class C { static f() {} }').executables[0];
2917 expect(executable.isStatic, isTrue);
2918 }
2919
2920 test_executable_type_param_f_bound_function() {
2921 UnlinkedExecutable ex =
2922 serializeExecutableText('void f<T, U extends List<T>>() {}');
2923 TypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
2924 checkParamTypeRef(typeArgument, 2);
2925 }
2926
2927 test_executable_type_param_f_bound_method() {
2928 UnlinkedExecutable ex =
2929 serializeMethodText('void f<T, U extends List<T>>() {}');
2930 TypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
2931 checkParamTypeRef(typeArgument, 2);
2932 }
2933
2934 test_executable_type_param_f_bound_self_ref_function() {
2935 UnlinkedExecutable ex =
2936 serializeExecutableText('void f<T, U extends List<U>>() {}');
2937 TypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
2938 checkParamTypeRef(typeArgument, 1);
2939 }
2940
2941 test_executable_type_param_f_bound_self_ref_method() {
2942 UnlinkedExecutable ex =
2943 serializeMethodText('void f<T, U extends List<U>>() {}');
2944 TypeRef typeArgument = ex.typeParameters[1].bound.typeArguments[0];
2945 checkParamTypeRef(typeArgument, 1);
2946 }
2947
2948 test_executable_type_param_in_parameter_function() {
2949 UnlinkedExecutable ex = serializeExecutableText('void f<T>(T t) {}');
2950 checkParamTypeRef(ex.parameters[0].type, 1);
2951 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
2952 }
2953
2954 test_executable_type_param_in_parameter_method() {
2955 UnlinkedExecutable ex = serializeMethodText('void f<T>(T t) {}');
2956 checkParamTypeRef(ex.parameters[0].type, 1);
2957 }
2958
2959 test_executable_type_param_in_return_type_function() {
2960 UnlinkedExecutable ex = serializeExecutableText('T f<T>() => null;');
2961 checkParamTypeRef(ex.returnType, 1);
2962 }
2963
2964 test_executable_type_param_in_return_type_method() {
2965 UnlinkedExecutable ex = serializeMethodText('T f<T>() => null;');
2966 checkParamTypeRef(ex.returnType, 1);
2967 }
2968
2969 test_export_class() {
2970 addNamedSource('/a.dart', 'class C {}');
2971 serializeLibraryText('export "a.dart";');
2972 expect(linked.exportNames, hasLength(1));
2973 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C',
2974 ReferenceKind.classOrEnum);
2975 }
2976
2977 test_export_class_alias() {
2978 addNamedSource(
2979 '/a.dart', 'class C extends _D with _E {} class _D {} class _E {}');
2980 serializeLibraryText('export "a.dart";');
2981 expect(linked.exportNames, hasLength(1));
2982 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'C',
2983 ReferenceKind.classOrEnum);
2984 }
2985
2986 test_export_enum() {
2987 addNamedSource('/a.dart', 'enum E { v }');
2988 serializeLibraryText('export "a.dart";');
2989 expect(linked.exportNames, hasLength(1));
2990 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'E',
2991 ReferenceKind.classOrEnum);
2992 }
2993
2994 test_export_from_part() {
2995 addNamedSource('/a.dart', 'library foo; part "b.dart";');
2996 addNamedSource('/b.dart', 'part of foo; f() {}');
2997 serializeLibraryText('export "a.dart";');
2998 expect(linked.exportNames, hasLength(1));
2999 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3000 ReferenceKind.topLevelFunction,
3001 expectedTargetUnit: 1);
3002 }
3003
3004 test_export_function() {
3005 addNamedSource('/a.dart', 'f() {}');
3006 serializeLibraryText('export "a.dart";');
3007 expect(linked.exportNames, hasLength(1));
3008 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3009 ReferenceKind.topLevelFunction);
3010 }
3011
3012 test_export_getter() {
3013 addNamedSource('/a.dart', 'get f => null');
3014 serializeLibraryText('export "a.dart";');
3015 expect(linked.exportNames, hasLength(1));
3016 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3017 ReferenceKind.topLevelPropertyAccessor);
3018 }
3019
3020 test_export_hide() {
3021 addNamedSource('/a.dart', 'f() {} g() {}');
3022 serializeLibraryText('export "a.dart" hide g;');
3023 expect(linked.exportNames, hasLength(1));
3024 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3025 ReferenceKind.topLevelFunction);
3026 }
3027
3028 test_export_hide_order() {
3029 serializeLibraryText('export "dart:async" hide Future, Stream;');
3030 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
3031 expect(
3032 unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
3033 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
3034 isEmpty);
3035 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
3036 hasLength(2));
3037 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[0],
3038 'Future');
3039 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
3040 'Stream');
3041 expect(linked.exportNames, isNotEmpty);
3042 }
3043
3044 test_export_names_excludes_names_from_library() {
3045 addNamedSource('/a.dart', 'part of my.lib; int y; int _y;');
3046 serializeLibraryText('library my.lib; part "a.dart"; int x; int _x;');
3047 expect(linked.exportNames, isEmpty);
3048 }
3049
3050 test_export_no_combinators() {
3051 serializeLibraryText('export "dart:async";');
3052 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
3053 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators, isEmpty);
3054 }
3055
3056 test_export_not_shadowed_by_prefix() {
3057 addNamedSource('/a.dart', 'f() {}');
3058 serializeLibraryText('export "a.dart"; import "dart:core" as f; f.int _x;');
3059 expect(linked.exportNames, hasLength(1));
3060 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3061 ReferenceKind.topLevelFunction);
3062 }
3063
3064 test_export_offset() {
3065 String libraryText = ' export "dart:async";';
3066 serializeLibraryText(libraryText);
3067 expect(unlinkedUnits[0].exports[0].uriOffset,
3068 libraryText.indexOf('"dart:async"'));
3069 expect(unlinkedUnits[0].exports[0].uriEnd, libraryText.indexOf(';'));
3070 expect(unlinkedUnits[0].exports[0].offset, libraryText.indexOf('export'));
3071 }
3072
3073 test_export_private() {
3074 // Private names should not be exported.
3075 addNamedSource('/a.dart', '_f() {}');
3076 serializeLibraryText('export "a.dart";');
3077 expect(linked.exportNames, isEmpty);
3078 }
3079
3080 test_export_setter() {
3081 addNamedSource('/a.dart', 'void set f(value) {}');
3082 serializeLibraryText('export "a.dart";');
3083 expect(linked.exportNames, hasLength(1));
3084 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f=',
3085 ReferenceKind.topLevelPropertyAccessor);
3086 }
3087
3088 test_export_shadowed() {
3089 // f() is not shown in exportNames because it is already defined at top
3090 // level in the library.
3091 addNamedSource('/a.dart', 'f() {}');
3092 serializeLibraryText('export "a.dart"; f() {}');
3093 expect(linked.exportNames, isEmpty);
3094 }
3095
3096 test_export_shadowed_variable() {
3097 // Neither `v` nor `v=` is shown in exportNames because both are defined at
3098 // top level in the library by the declaration `var v;`.
3099 addNamedSource('/a.dart', 'var v;');
3100 serializeLibraryText('export "a.dart"; var v;');
3101 expect(linked.exportNames, isEmpty);
3102 }
3103
3104 test_export_shadowed_variable_const() {
3105 // `v=` is shown in exportNames because the top level declaration
3106 // `const v = 0;` only shadows `v`, not `v=`.
3107 addNamedSource('/a.dart', 'var v;');
3108 serializeLibraryText('export "a.dart"; const v = 0;');
3109 expect(linked.exportNames, hasLength(1));
3110 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=',
3111 ReferenceKind.topLevelPropertyAccessor);
3112 }
3113
3114 test_export_shadowed_variable_final() {
3115 // `v=` is shown in exportNames because the top level declaration
3116 // `final v = 0;` only shadows `v`, not `v=`.
3117 addNamedSource('/a.dart', 'var v;');
3118 serializeLibraryText('export "a.dart"; final v = 0;');
3119 expect(linked.exportNames, hasLength(1));
3120 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'v=',
3121 ReferenceKind.topLevelPropertyAccessor);
3122 }
3123
3124 test_export_show() {
3125 addNamedSource('/a.dart', 'f() {} g() {}');
3126 serializeLibraryText('export "a.dart" show f;');
3127 expect(linked.exportNames, hasLength(1));
3128 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'f',
3129 ReferenceKind.topLevelFunction);
3130 }
3131
3132 test_export_show_order() {
3133 serializeLibraryText('export "dart:async" show Future, Stream;');
3134 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
3135 expect(
3136 unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
3137 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows,
3138 hasLength(2));
3139 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides,
3140 isEmpty);
3141 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[0],
3142 'Future');
3143 expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
3144 'Stream');
3145 }
3146
3147 test_export_typedef() {
3148 addNamedSource('/a.dart', 'typedef F();');
3149 serializeLibraryText('export "a.dart";');
3150 expect(linked.exportNames, hasLength(1));
3151 checkExportName(linked.exportNames[0], absUri('/a.dart'), 'a.dart', 'F',
3152 ReferenceKind.typedef);
3153 }
3154
3155 test_export_uri() {
3156 addNamedSource('/a.dart', 'library my.lib;');
3157 String uriString = '"a.dart"';
3158 String libraryText = 'export $uriString;';
3159 serializeLibraryText(libraryText);
3160 expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
3161 expect(unlinkedUnits[0].publicNamespace.exports[0].uri, 'a.dart');
3162 }
3163
3164 test_export_variable() {
3165 addNamedSource('/a.dart', 'var v;');
3166 serializeLibraryText('export "a.dart";');
3167 expect(linked.exportNames, hasLength(2));
3168 LinkedExportName getter =
3169 linked.exportNames.firstWhere((e) => e.name == 'v');
3170 expect(getter, isNotNull);
3171 checkExportName(getter, absUri('/a.dart'), 'a.dart', 'v',
3172 ReferenceKind.topLevelPropertyAccessor);
3173 LinkedExportName setter =
3174 linked.exportNames.firstWhere((e) => e.name == 'v=');
3175 expect(setter, isNotNull);
3176 checkExportName(setter, absUri('/a.dart'), 'a.dart', 'v=',
3177 ReferenceKind.topLevelPropertyAccessor);
3178 }
3179
3180 test_field() {
3181 UnlinkedClass cls = serializeClassText('class C { int i; }');
3182 UnlinkedVariable variable = findVariable('i', variables: cls.fields);
3183 expect(variable, isNotNull);
3184 expect(variable.isConst, isFalse);
3185 expect(variable.isStatic, isFalse);
3186 expect(variable.isFinal, isFalse);
3187 expect(findExecutable('i', executables: cls.executables), isNull);
3188 expect(findExecutable('i=', executables: cls.executables), isNull);
3189 }
3190
3191 test_field_const() {
3192 UnlinkedVariable variable =
3193 serializeClassText('class C { static const int i = 0; }').fields[0];
3194 expect(variable.isConst, isTrue);
3195 _assertUnlinkedConst(variable.constExpr,
3196 operators: [UnlinkedConstOperation.pushInt], ints: [0]);
3197 }
3198
3199 test_field_documented() {
3200 String text = '''
3201 class C {
3202 /**
3203 * Docs
3204 */
3205 var v;
3206 }''';
3207 UnlinkedVariable variable = serializeClassText(text).fields[0];
3208 expect(variable.documentationComment, isNotNull);
3209 checkDocumentationComment(variable.documentationComment, text);
3210 }
3211
3212 test_field_final() {
3213 UnlinkedVariable variable =
3214 serializeClassText('class C { final int i = 0; }').fields[0];
3215 expect(variable.isFinal, isTrue);
3216 }
3217
3218 test_field_propagated_type_final_immediate() {
3219 UnlinkedVariable v =
3220 serializeClassText('class C { final v = 0; }').fields[0];
3221 checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
3222 }
3223
3224 test_field_static() {
3225 UnlinkedVariable variable =
3226 serializeClassText('class C { static int i; }').fields[0];
3227 expect(variable.isStatic, isTrue);
3228 }
3229
3230 test_fully_linked_references_follow_other_references() {
3231 if (skipFullyLinkedData) {
3232 return;
3233 }
3234 serializeLibraryText('final x = 0; String y;');
3235 checkLinkedTypeSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot,
3236 'dart:core', 'dart:core', 'int');
3237 checkTypeRef(
3238 unlinkedUnits[0].variables[1].type, 'dart:core', 'dart:core', 'String');
3239 // Even though the definition of y follows the definition of x, the linked
3240 // type reference for x should use a higher numbered reference than the
3241 // unlinked type reference for y.
3242 TypeRef propagatedType =
3243 getTypeRefForSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot);
3244 expect(unlinkedUnits[0].variables[1].type.reference,
3245 lessThan(propagatedType.reference));
3246 }
3247
3248 test_function_documented() {
3249 String text = '''
3250 // Extra comment so doc comment offset != 0
3251 /**
3252 * Docs
3253 */
3254 f() {}''';
3255 UnlinkedExecutable executable = serializeExecutableText(text);
3256 expect(executable.documentationComment, isNotNull);
3257 checkDocumentationComment(executable.documentationComment, text);
3258 }
3259
3260 test_generic_method_in_generic_class() {
3261 UnlinkedClass cls = serializeClassText(
3262 'class C<T, U> { void m<V, W>(T t, U u, V v, W w) {} }');
3263 List<UnlinkedParam> params = cls.executables[0].parameters;
3264 checkParamTypeRef(params[0].type, 4);
3265 checkParamTypeRef(params[1].type, 3);
3266 checkParamTypeRef(params[2].type, 2);
3267 checkParamTypeRef(params[3].type, 1);
3268 }
3269
3270 test_getter_documented() {
3271 String text = '''
3272 // Extra comment so doc comment offset != 0
3273 /**
3274 * Docs
3275 */
3276 get f => null;''';
3277 UnlinkedExecutable executable = serializeExecutableText(text);
3278 expect(executable.documentationComment, isNotNull);
3279 checkDocumentationComment(executable.documentationComment, text);
3280 }
3281
3282 test_implicit_dependencies_follow_other_dependencies() {
3283 if (skipFullyLinkedData) {
3284 return;
3285 }
3286 addNamedSource('/a.dart', 'import "b.dart"; class C {} D f() => null;');
3287 addNamedSource('/b.dart', 'class D {}');
3288 serializeLibraryText('import "a.dart"; final x = f(); C y;');
3289 // The dependency on b.dart is implicit, so it should be placed at the end
3290 // of the dependency list, after a.dart, even though the code that refers
3291 // to b.dart comes before the code that refers to a.dart.
3292 int aDep =
3293 checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
3294 int bDep =
3295 checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
3296 expect(aDep, lessThan(bDep));
3297 }
3298
3299 test_import_deferred() {
3300 serializeLibraryText(
3301 'import "dart:async" deferred as a; main() { print(a.Future); }');
3302 expect(unlinkedUnits[0].imports[0].isDeferred, isTrue);
3303 }
3304
3305 test_import_dependency() {
3306 serializeLibraryText('import "dart:async"; Future x;');
3307 // Second import is the implicit import of dart:core
3308 expect(unlinkedUnits[0].imports, hasLength(2));
3309 checkDependency(linked.importDependencies[0], 'dart:async', 'dart:async');
3310 }
3311
3312 test_import_explicit() {
3313 serializeLibraryText('import "dart:core"; int i;');
3314 expect(unlinkedUnits[0].imports, hasLength(1));
3315 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
3316 }
3317
3318 test_import_hide_order() {
3319 serializeLibraryText(
3320 'import "dart:async" hide Future, Stream; Completer c;');
3321 // Second import is the implicit import of dart:core
3322 expect(unlinkedUnits[0].imports, hasLength(2));
3323 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
3324 expect(unlinkedUnits[0].imports[0].combinators[0].shows, isEmpty);
3325 expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
3326 expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
3327 expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
3328 }
3329
3330 test_import_implicit() {
3331 // The implicit import of dart:core is represented in the model.
3332 serializeLibraryText('');
3333 expect(unlinkedUnits[0].imports, hasLength(1));
3334 checkDependency(linked.importDependencies[0], 'dart:core', 'dart:core');
3335 expect(unlinkedUnits[0].imports[0].uri, isEmpty);
3336 expect(unlinkedUnits[0].imports[0].uriOffset, 0);
3337 expect(unlinkedUnits[0].imports[0].uriEnd, 0);
3338 expect(unlinkedUnits[0].imports[0].prefixReference, 0);
3339 expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
3340 expect(unlinkedUnits[0].imports[0].isImplicit, isTrue);
3341 }
3342
3343 test_import_missing() {
3344 if (!checkAstDerivedData) {
3345 // TODO(paulberry): At the moment unresolved imports are not included in
3346 // the element model, so we can't pass this test.
3347 return;
3348 }
3349 // Unresolved imports are included since this is necessary for proper
3350 // dependency tracking.
3351 allowMissingFiles = true;
3352 serializeLibraryText('import "foo.dart";', allowErrors: true);
3353 // Second import is the implicit import of dart:core
3354 expect(unlinkedUnits[0].imports, hasLength(2));
3355 checkDependency(
3356 linked.importDependencies[0], absUri('/foo.dart'), 'foo.dart');
3357 }
3358
3359 test_import_no_combinators() {
3360 serializeLibraryText('import "dart:async"; Future x;');
3361 // Second import is the implicit import of dart:core
3362 expect(unlinkedUnits[0].imports, hasLength(2));
3363 expect(unlinkedUnits[0].imports[0].combinators, isEmpty);
3364 }
3365
3366 test_import_no_flags() {
3367 serializeLibraryText('import "dart:async"; Future x;');
3368 expect(unlinkedUnits[0].imports[0].isImplicit, isFalse);
3369 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
3370 }
3371
3372 test_import_non_deferred() {
3373 serializeLibraryText(
3374 'import "dart:async" as a; main() { print(a.Future); }');
3375 expect(unlinkedUnits[0].imports[0].isDeferred, isFalse);
3376 }
3377
3378 test_import_of_file_with_missing_part() {
3379 // Other references in foo.dart should be resolved even though foo.dart's
3380 // part declaration for bar.dart refers to a non-existent file.
3381 allowMissingFiles = true;
3382 addNamedSource('/foo.dart', 'part "bar.dart"; class C {}');
3383 serializeLibraryText('import "foo.dart"; C x;');
3384 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
3385 }
3386
3387 test_import_of_missing_export() {
3388 // Other references in foo.dart should be resolved even though foo.dart's
3389 // re-export of bar.dart refers to a non-existent file.
3390 allowMissingFiles = true;
3391 addNamedSource('/foo.dart', 'export "bar.dart"; class C {}');
3392 serializeLibraryText('import "foo.dart"; C x;');
3393 checkTypeRef(findVariable('x').type, absUri('/foo.dart'), 'foo.dart', 'C');
3394 }
3395
3396 test_import_offset() {
3397 String libraryText = ' import "dart:async"; Future x;';
3398 serializeLibraryText(libraryText);
3399 expect(unlinkedUnits[0].imports[0].offset, libraryText.indexOf('import'));
3400 expect(unlinkedUnits[0].imports[0].uriOffset,
3401 libraryText.indexOf('"dart:async"'));
3402 expect(unlinkedUnits[0].imports[0].uriEnd, libraryText.indexOf('; Future'));
3403 }
3404
3405 test_import_prefix_name() {
3406 String libraryText = 'import "dart:async" as a; a.Future x;';
3407 serializeLibraryText(libraryText);
3408 // Second import is the implicit import of dart:core
3409 expect(unlinkedUnits[0].imports, hasLength(2));
3410 checkPrefix(unlinkedUnits[0].imports[0].prefixReference, 'a');
3411 expect(unlinkedUnits[0].imports[0].prefixOffset, libraryText.indexOf('a;'));
3412 }
3413
3414 test_import_prefix_none() {
3415 serializeLibraryText('import "dart:async"; Future x;');
3416 // Second import is the implicit import of dart:core
3417 expect(unlinkedUnits[0].imports, hasLength(2));
3418 expect(unlinkedUnits[0].imports[0].prefixReference, 0);
3419 }
3420
3421 test_import_prefix_not_in_public_namespace() {
3422 serializeLibraryText('import "dart:async" as a; a.Future v;');
3423 expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
3424 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'v');
3425 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'v=');
3426 }
3427
3428 test_import_prefix_reference() {
3429 UnlinkedVariable variable =
3430 serializeVariableText('import "dart:async" as a; a.Future v;');
3431 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
3432 expectedPrefix: 'a', numTypeParameters: 1);
3433 }
3434
3435 test_import_prefixes_take_precedence_over_imported_names() {
3436 addNamedSource('/a.dart', 'class b {} class A');
3437 addNamedSource('/b.dart', 'class Cls {}');
3438 addNamedSource('/c.dart', 'class Cls {}');
3439 addNamedSource('/d.dart', 'class c {} class D');
3440 serializeLibraryText('''
3441 import 'a.dart';
3442 import 'b.dart' as b;
3443 import 'c.dart' as c;
3444 import 'd.dart';
3445 A aCls;
3446 b.Cls bCls;
3447 c.Cls cCls;
3448 D dCls;
3449 ''');
3450 checkTypeRef(findVariable('aCls').type, absUri('/a.dart'), 'a.dart', 'A');
3451 checkTypeRef(findVariable('bCls').type, absUri('/b.dart'), 'b.dart', 'Cls',
3452 expectedPrefix: 'b');
3453 checkTypeRef(findVariable('cCls').type, absUri('/c.dart'), 'c.dart', 'Cls',
3454 expectedPrefix: 'c');
3455 checkTypeRef(findVariable('dCls').type, absUri('/d.dart'), 'd.dart', 'D');
3456 }
3457
3458 test_import_reference() {
3459 UnlinkedVariable variable =
3460 serializeVariableText('import "dart:async"; Future v;');
3461 checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
3462 numTypeParameters: 1);
3463 }
3464
3465 test_import_reference_merged_no_prefix() {
3466 serializeLibraryText('''
3467 import "dart:async" show Future;
3468 import "dart:async" show Stream;
3469
3470 Future f;
3471 Stream s;
3472 ''');
3473 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
3474 numTypeParameters: 1);
3475 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
3476 numTypeParameters: 1);
3477 }
3478
3479 test_import_reference_merged_prefixed() {
3480 serializeLibraryText('''
3481 import "dart:async" as a show Future;
3482 import "dart:async" as a show Stream;
3483
3484 a.Future f;
3485 a.Stream s;
3486 ''');
3487 checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
3488 expectedPrefix: 'a', numTypeParameters: 1);
3489 checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
3490 expectedPrefix: 'a', numTypeParameters: 1);
3491 }
3492
3493 test_import_reference_merged_prefixed_separate_libraries() {
3494 addNamedSource('/a.dart', 'class A {}');
3495 addNamedSource('/b.dart', 'class B {}');
3496 serializeLibraryText('''
3497 import 'a.dart' as p;
3498 import 'b.dart' as p;
3499
3500 p.A a;
3501 p.B b;
3502 ''');
3503 checkTypeRef(findVariable('a').type, absUri('/a.dart'), 'a.dart', 'A',
3504 expectedPrefix: 'p');
3505 checkTypeRef(findVariable('b').type, absUri('/b.dart'), 'b.dart', 'B',
3506 expectedPrefix: 'p');
3507 }
3508
3509 test_import_show_order() {
3510 String libraryText =
3511 'import "dart:async" show Future, Stream; Future x; Stream y;';
3512 serializeLibraryText(libraryText);
3513 // Second import is the implicit import of dart:core
3514 expect(unlinkedUnits[0].imports, hasLength(2));
3515 expect(unlinkedUnits[0].imports[0].combinators, hasLength(1));
3516 expect(unlinkedUnits[0].imports[0].combinators[0].shows, hasLength(2));
3517 expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty);
3518 expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
3519 expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
3520 }
3521
3522 test_import_uri() {
3523 String uriString = '"dart:async"';
3524 String libraryText = 'import $uriString; Future x;';
3525 serializeLibraryText(libraryText);
3526 // Second import is the implicit import of dart:core
3527 expect(unlinkedUnits[0].imports, hasLength(2));
3528 expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
3529 }
3530
3531 test_invalid_prefix_dynamic() {
3532 if (checkAstDerivedData) {
3533 // TODO(paulberry): get this to work properly.
3534 return;
3535 }
3536 checkUnresolvedTypeRef(
3537 serializeTypeText('dynamic.T', allowErrors: true), 'dynamic', 'T');
3538 }
3539
3540 test_invalid_prefix_type_parameter() {
3541 if (checkAstDerivedData) {
3542 // TODO(paulberry): get this to work properly.
3543 return;
3544 }
3545 checkUnresolvedTypeRef(
3546 serializeClassText('class C<T> { T.U x; }', allowErrors: true).fields[0]
3547 .type,
3548 'T',
3549 'U');
3550 }
3551
3552 test_invalid_prefix_void() {
3553 if (checkAstDerivedData) {
3554 // TODO(paulberry): get this to work properly.
3555 return;
3556 }
3557 checkUnresolvedTypeRef(
3558 serializeTypeText('void.T', allowErrors: true), 'void', 'T');
3559 }
3560
3561 test_library_documented() {
3562 String text = '''
3563 // Extra comment so doc comment offset != 0
3564 /**
3565 * Docs
3566 */
3567 library foo;''';
3568 serializeLibraryText(text);
3569 expect(unlinkedUnits[0].libraryDocumentationComment, isNotNull);
3570 checkDocumentationComment(
3571 unlinkedUnits[0].libraryDocumentationComment, text);
3572 }
3573
3574 test_library_name_with_spaces() {
3575 String text = 'library foo . bar ;';
3576 serializeLibraryText(text);
3577 expect(unlinkedUnits[0].libraryName, 'foo.bar');
3578 expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo . bar'));
3579 expect(unlinkedUnits[0].libraryNameLength, 'foo . bar'.length);
3580 }
3581
3582 test_library_named() {
3583 String text = 'library foo.bar;';
3584 serializeLibraryText(text);
3585 expect(unlinkedUnits[0].libraryName, 'foo.bar');
3586 expect(unlinkedUnits[0].libraryNameOffset, text.indexOf('foo.bar'));
3587 expect(unlinkedUnits[0].libraryNameLength, 'foo.bar'.length);
3588 }
3589
3590 test_library_unnamed() {
3591 serializeLibraryText('');
3592 expect(unlinkedUnits[0].libraryName, isEmpty);
3593 expect(unlinkedUnits[0].libraryNameOffset, 0);
3594 expect(unlinkedUnits[0].libraryNameLength, 0);
3595 }
3596
3597 test_library_with_missing_part() {
3598 // References to other parts should still be resolved.
3599 allowMissingFiles = true;
3600 addNamedSource('/bar.dart', 'part of my.lib; class C {}');
3601 serializeLibraryText(
3602 'library my.lib; part "foo.dart"; part "bar.dart"; C c;',
3603 allowErrors: true);
3604 checkTypeRef(findVariable('c').type, null, null, 'C',
3605 expectedTargetUnit: 2);
3606 }
3607
3608 test_linked_reference_reuse() {
3609 if (skipFullyLinkedData) {
3610 return;
3611 }
3612 // When the reference for a linked type is the same as an explicitly
3613 // referenced type, the explicit reference should be re-used.
3614 addNamedSource('/a.dart', 'class C {}');
3615 addNamedSource('/b.dart', 'import "a.dart"; C f() => null;');
3616 serializeLibraryText(
3617 'import "a.dart"; import "b.dart"; C c1; final c2 = f();');
3618 int explicitReference = findVariable('c1').type.reference;
3619 expect(getTypeRefForSlot(findVariable('c2').propagatedTypeSlot).reference,
3620 explicitReference);
3621 }
3622
3623 test_linked_type_dependency_reuse() {
3624 if (skipFullyLinkedData) {
3625 return;
3626 }
3627 // When the dependency for a linked type is the same as an explicit
3628 // dependency, the explicit dependency should be re-used.
3629 addNamedSource('/a.dart', 'class C {} class D {}');
3630 addNamedSource('/b.dart', 'import "a.dart"; D f() => null;');
3631 serializeLibraryText(
3632 'import "a.dart"; import "b.dart"; C c; final d = f();');
3633 int cReference = findVariable('c').type.reference;
3634 int explicitDependency = linked.units[0].references[cReference].dependency;
3635 int dReference =
3636 getTypeRefForSlot(findVariable('d').propagatedTypeSlot).reference;
3637 expect(
3638 linked.units[0].references[dReference].dependency, explicitDependency);
3639 }
3640
3641 test_local_names_take_precedence_over_imported_names() {
3642 addNamedSource('/a.dart', 'class C {} class D {}');
3643 serializeLibraryText('''
3644 import 'a.dart';
3645 class C {}
3646 C c;
3647 D d;''');
3648 checkTypeRef(findVariable('c').type, null, null, 'C');
3649 checkTypeRef(findVariable('d').type, absUri('/a.dart'), 'a.dart', 'D');
3650 }
3651
3652 test_method_documented() {
3653 String text = '''
3654 class C {
3655 /**
3656 * Docs
3657 */
3658 f() {}
3659 }''';
3660 UnlinkedExecutable executable = serializeClassText(text).executables[0];
3661 expect(executable.documentationComment, isNotNull);
3662 checkDocumentationComment(executable.documentationComment, text);
3663 }
3664
3665 test_part_declaration() {
3666 addNamedSource('/a.dart', 'part of my.lib;');
3667 String text = 'library my.lib; part "a.dart"; // <-part';
3668 serializeLibraryText(text);
3669 expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
3670 expect(unlinkedUnits[0].publicNamespace.parts[0], 'a.dart');
3671 expect(unlinkedUnits[0].parts, hasLength(1));
3672 expect(unlinkedUnits[0].parts[0].uriOffset, text.indexOf('"a.dart"'));
3673 expect(unlinkedUnits[0].parts[0].uriEnd, text.indexOf('; // <-part'));
3674 }
3675
3676 test_parts_defining_compilation_unit() {
3677 serializeLibraryText('');
3678 expect(linked.units, hasLength(1));
3679 expect(unlinkedUnits[0].publicNamespace.parts, isEmpty);
3680 }
3681
3682 test_parts_included() {
3683 addNamedSource('/part1.dart', 'part of my.lib;');
3684 String partString = '"part1.dart"';
3685 String libraryText = 'library my.lib; part $partString;';
3686 serializeLibraryText(libraryText);
3687 expect(linked.units, hasLength(2));
3688 expect(unlinkedUnits[0].publicNamespace.parts, hasLength(1));
3689 expect(unlinkedUnits[0].publicNamespace.parts[0], 'part1.dart');
3690 }
3691
3692 test_public_namespace_of_part() {
3693 addNamedSource('/a.dart', 'part of foo; class C {}');
3694 serializeLibraryText('library foo; part "a.dart";');
3695 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
3696 expect(unlinkedUnits[1].publicNamespace.names, hasLength(1));
3697 expect(unlinkedUnits[1].publicNamespace.names[0].name, 'C');
3698 }
3699
3700 test_setter_documented() {
3701 String text = '''
3702 // Extra comment so doc comment offset != 0
3703 /**
3704 * Docs
3705 */
3706 void set f(value) {}''';
3707 UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
3708 expect(executable.documentationComment, isNotNull);
3709 checkDocumentationComment(executable.documentationComment, text);
3710 }
3711
3712 test_slot_reuse() {
3713 // Different compilation units have independent notions of slot id, so slot
3714 // ids should be reused.
3715 addNamedSource('/a.dart', 'part of foo; final v = 0;');
3716 serializeLibraryText('library foo; part "a.dart"; final w = 0;');
3717 expect(unlinkedUnits[0].variables[0].propagatedTypeSlot, 1);
3718 expect(unlinkedUnits[1].variables[0].propagatedTypeSlot, 1);
3719 }
3720
3721 test_type_arguments_explicit() {
3722 TypeRef typeRef = serializeTypeText('List<int>');
3723 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
3724 allowTypeParameters: true, numTypeParameters: 1);
3725 expect(typeRef.typeArguments, hasLength(1));
3726 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
3727 }
3728
3729 test_type_arguments_explicit_dynamic() {
3730 TypeRef typeRef = serializeTypeText('List<dynamic>');
3731 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
3732 allowTypeParameters: true, numTypeParameters: 1);
3733 expect(typeRef.typeArguments, isEmpty);
3734 }
3735
3736 test_type_arguments_explicit_dynamic_dynamic() {
3737 TypeRef typeRef = serializeTypeText('Map<dynamic, dynamic>');
3738 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
3739 allowTypeParameters: true, numTypeParameters: 2);
3740 // Trailing type arguments of type `dynamic` are omitted.
3741 expect(typeRef.typeArguments, isEmpty);
3742 }
3743
3744 test_type_arguments_explicit_dynamic_int() {
3745 TypeRef typeRef = serializeTypeText('Map<dynamic, int>');
3746 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
3747 allowTypeParameters: true, numTypeParameters: 2);
3748 // Leading type arguments of type `dynamic` are not omitted.
3749 expect(typeRef.typeArguments.length, 2);
3750 checkDynamicTypeRef(typeRef.typeArguments[0]);
3751 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
3752 }
3753
3754 test_type_arguments_explicit_dynamic_typedef() {
3755 TypeRef typeRef =
3756 serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
3757 checkTypeRef(typeRef, null, null, 'F',
3758 allowTypeParameters: true,
3759 expectedKind: ReferenceKind.typedef,
3760 numTypeParameters: 1);
3761 expect(typeRef.typeArguments, isEmpty);
3762 }
3763
3764 test_type_arguments_explicit_String_dynamic() {
3765 TypeRef typeRef = serializeTypeText('Map<String, dynamic>');
3766 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
3767 allowTypeParameters: true, numTypeParameters: 2);
3768 // Trailing type arguments of type `dynamic` are omitted.
3769 expect(typeRef.typeArguments.length, 1);
3770 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
3771 }
3772
3773 test_type_arguments_explicit_String_int() {
3774 TypeRef typeRef = serializeTypeText('Map<String, int>');
3775 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
3776 allowTypeParameters: true, numTypeParameters: 2);
3777 expect(typeRef.typeArguments.length, 2);
3778 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
3779 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
3780 }
3781
3782 test_type_arguments_explicit_typedef() {
3783 TypeRef typeRef =
3784 serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
3785 checkTypeRef(typeRef, null, null, 'F',
3786 allowTypeParameters: true,
3787 expectedKind: ReferenceKind.typedef,
3788 numTypeParameters: 1);
3789 expect(typeRef.typeArguments, hasLength(1));
3790 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
3791 }
3792
3793 test_type_arguments_implicit() {
3794 TypeRef typeRef = serializeTypeText('List');
3795 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
3796 allowTypeParameters: true, numTypeParameters: 1);
3797 expect(typeRef.typeArguments, isEmpty);
3798 }
3799
3800 test_type_arguments_implicit_typedef() {
3801 TypeRef typeRef =
3802 serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
3803 checkTypeRef(typeRef, null, null, 'F',
3804 allowTypeParameters: true,
3805 expectedKind: ReferenceKind.typedef,
3806 numTypeParameters: 1);
3807 expect(typeRef.typeArguments, isEmpty);
3808 }
3809
3810 test_type_arguments_order() {
3811 TypeRef typeRef = serializeTypeText('Map<int, Object>');
3812 checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
3813 allowTypeParameters: true, numTypeParameters: 2);
3814 expect(typeRef.typeArguments, hasLength(2));
3815 checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
3816 checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
3817 }
3818
3819 test_type_dynamic() {
3820 checkDynamicTypeRef(serializeTypeText('dynamic'));
3821 }
3822
3823 test_type_param_not_shadowed_by_constructor() {
3824 UnlinkedClass cls =
3825 serializeClassText('class C<D> { D x; C.D(); } class D {}');
3826 checkParamTypeRef(cls.fields[0].type, 1);
3827 }
3828
3829 test_type_param_not_shadowed_by_field_in_extends() {
3830 UnlinkedClass cls =
3831 serializeClassText('class C<T> extends D<T> { T x; } class D<T> {}');
3832 checkParamTypeRef(cls.supertype.typeArguments[0], 1);
3833 }
3834
3835 test_type_param_not_shadowed_by_field_in_implements() {
3836 UnlinkedClass cls =
3837 serializeClassText('class C<T> implements D<T> { T x; } class D<T> {}');
3838 checkParamTypeRef(cls.interfaces[0].typeArguments[0], 1);
3839 }
3840
3841 test_type_param_not_shadowed_by_field_in_with() {
3842 UnlinkedClass cls = serializeClassText(
3843 'class C<T> extends Object with D<T> { T x; } class D<T> {}');
3844 checkParamTypeRef(cls.mixins[0].typeArguments[0], 1);
3845 }
3846
3847 test_type_param_not_shadowed_by_method_parameter() {
3848 UnlinkedClass cls = serializeClassText('class C<T> { f(int T, T x) {} }');
3849 checkParamTypeRef(cls.executables[0].parameters[1].type, 1);
3850 }
3851
3852 test_type_param_not_shadowed_by_setter() {
3853 // The code under test should not produce a compile-time error, but it
3854 // does.
3855 bool workAroundBug25525 = true;
3856 UnlinkedClass cls = serializeClassText(
3857 'class C<D> { D x; void set D(value) {} } class D {}',
3858 allowErrors: workAroundBug25525);
3859 checkParamTypeRef(cls.fields[0].type, 1);
3860 }
3861
3862 test_type_param_not_shadowed_by_typedef_parameter() {
3863 UnlinkedTypedef typedef =
3864 serializeTypedefText('typedef void F<T>(int T, T x);');
3865 checkParamTypeRef(typedef.parameters[1].type, 1);
3866 }
3867
3868 test_type_param_shadowed_by_field() {
3869 UnlinkedClass cls = serializeClassText(
3870 'class C<D> { D x; int D; } class D {}',
3871 allowErrors: true);
3872 checkDynamicTypeRef(cls.fields[0].type);
3873 }
3874
3875 test_type_param_shadowed_by_getter() {
3876 UnlinkedClass cls = serializeClassText(
3877 'class C<D> { D x; int get D => null; } class D {}',
3878 allowErrors: true);
3879 checkDynamicTypeRef(cls.fields[0].type);
3880 }
3881
3882 test_type_param_shadowed_by_method() {
3883 UnlinkedClass cls = serializeClassText(
3884 'class C<D> { D x; void D() {} } class D {}',
3885 allowErrors: true);
3886 checkDynamicTypeRef(cls.fields[0].type);
3887 }
3888
3889 test_type_param_shadowed_by_type_param() {
3890 UnlinkedClass cls =
3891 serializeClassText('class C<T> { T f<T>(T x) => null; }');
3892 checkParamTypeRef(cls.executables[0].returnType, 1);
3893 checkParamTypeRef(cls.executables[0].parameters[0].type, 1);
3894 }
3895
3896 test_type_reference_from_part() {
3897 addNamedSource('/a.dart', 'part of foo; C v;');
3898 serializeLibraryText('library foo; part "a.dart"; class C {}');
3899 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
3900 null, null, 'C',
3901 expectedKind: ReferenceKind.classOrEnum,
3902 linkedSourceUnit: linked.units[1],
3903 unlinkedSourceUnit: unlinkedUnits[1]);
3904 }
3905
3906 test_type_reference_from_part_withPrefix() {
3907 addNamedSource('/a.dart', 'class C {}');
3908 addNamedSource('/p.dart', 'part of foo; a.C v;');
3909 serializeLibraryText(
3910 'library foo; import "a.dart"; import "a.dart" as a; part "p.dart";',
3911 allowErrors: true);
3912 checkTypeRef(findVariable('v', variables: unlinkedUnits[1].variables).type,
3913 absUri('/a.dart'), 'a.dart', 'C',
3914 expectedPrefix: 'a',
3915 linkedSourceUnit: linked.units[1],
3916 unlinkedSourceUnit: unlinkedUnits[1]);
3917 }
3918
3919 test_type_reference_to_class_argument() {
3920 UnlinkedClass cls = serializeClassText('class C<T, U> { T t; U u; }');
3921 {
3922 TypeRef typeRef =
3923 findVariable('t', variables: cls.fields, failIfAbsent: true).type;
3924 checkParamTypeRef(typeRef, 2);
3925 }
3926 {
3927 TypeRef typeRef =
3928 findVariable('u', variables: cls.fields, failIfAbsent: true).type;
3929 checkParamTypeRef(typeRef, 1);
3930 }
3931 }
3932
3933 test_type_reference_to_import_of_export() {
3934 addNamedSource('/a.dart', 'library a; export "b.dart";');
3935 addNamedSource('/b.dart', 'library b; class C {}');
3936 checkTypeRef(serializeTypeText('C', otherDeclarations: 'import "a.dart";'),
3937 absUri('/b.dart'), 'b.dart', 'C');
3938 }
3939
3940 test_type_reference_to_import_of_export_via_prefix() {
3941 addNamedSource('/a.dart', 'library a; export "b.dart";');
3942 addNamedSource('/b.dart', 'library b; class C {}');
3943 checkTypeRef(
3944 serializeTypeText('p.C', otherDeclarations: 'import "a.dart" as p;'),
3945 absUri('/b.dart'),
3946 'b.dart',
3947 'C',
3948 expectedPrefix: 'p');
3949 }
3950
3951 test_type_reference_to_imported_part() {
3952 addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
3953 addNamedSource('/b.dart', 'part of my.lib; class C {}');
3954 checkTypeRef(
3955 serializeTypeText('C',
3956 otherDeclarations: 'library my.lib; import "a.dart";'),
3957 absUri('/a.dart'),
3958 'a.dart',
3959 'C',
3960 expectedTargetUnit: 1);
3961 }
3962
3963 test_type_reference_to_imported_part_with_prefix() {
3964 addNamedSource('/a.dart', 'library my.lib; part "b.dart";');
3965 addNamedSource('/b.dart', 'part of my.lib; class C {}');
3966 checkTypeRef(
3967 serializeTypeText('p.C',
3968 otherDeclarations: 'library my.lib; import "a.dart" as p;'),
3969 absUri('/a.dart'),
3970 'a.dart',
3971 'C',
3972 expectedPrefix: 'p',
3973 expectedTargetUnit: 1);
3974 }
3975
3976 test_type_reference_to_internal_class() {
3977 checkTypeRef(serializeTypeText('C', otherDeclarations: 'class C {}'), null,
3978 null, 'C');
3979 }
3980
3981 test_type_reference_to_internal_class_alias() {
3982 checkTypeRef(
3983 serializeTypeText('C',
3984 otherDeclarations: 'class C = D with E; class D {} class E {}'),
3985 null,
3986 null,
3987 'C');
3988 }
3989
3990 test_type_reference_to_internal_enum() {
3991 checkTypeRef(serializeTypeText('E', otherDeclarations: 'enum E { value }'),
3992 null, null, 'E');
3993 }
3994
3995 test_type_reference_to_local_part() {
3996 addNamedSource('/a.dart', 'part of my.lib; class C {}');
3997 checkTypeRef(
3998 serializeTypeText('C',
3999 otherDeclarations: 'library my.lib; part "a.dart";'),
4000 null,
4001 null,
4002 'C',
4003 expectedTargetUnit: 1);
4004 }
4005
4006 test_type_reference_to_nonexistent_file_via_prefix() {
4007 if (!checkAstDerivedData) {
4008 // TODO(paulberry): this test currently fails because there is not enough
4009 // information in the element model to figure out that the unresolved
4010 // reference `p.C` uses the prefix `p`.
4011 return;
4012 }
4013 allowMissingFiles = true;
4014 TypeRef typeRef = serializeTypeText('p.C',
4015 otherDeclarations: 'import "foo.dart" as p;', allowErrors: true);
4016 checkUnresolvedTypeRef(typeRef, 'p', 'C');
4017 }
4018
4019 test_type_reference_to_part() {
4020 addNamedSource('/a.dart', 'part of foo; class C { C(); }');
4021 serializeLibraryText('library foo; part "a.dart"; C c;');
4022 checkTypeRef(unlinkedUnits[0].variables.single.type, null, null, 'C',
4023 expectedKind: ReferenceKind.classOrEnum, expectedTargetUnit: 1);
4024 }
4025
4026 test_type_reference_to_type_visible_via_multiple_import_prefixes() {
4027 if (!checkAstDerivedData) {
4028 // TODO(paulberry): this test currently fails because the element model
4029 // doesn't record enough information to track which prefix is used to
4030 // refer to a type.
4031 return;
4032 }
4033 addNamedSource('/lib1.dart', 'class C');
4034 addNamedSource('/lib2.dart', 'export "lib1.dart";');
4035 addNamedSource('/lib3.dart', 'export "lib1.dart";');
4036 addNamedSource('/lib4.dart', 'export "lib1.dart";');
4037 serializeLibraryText('''
4038 import 'lib2.dart';
4039 import 'lib3.dart' as a;
4040 import 'lib4.dart' as b;
4041 C c2;
4042 a.C c3;
4043 b.C c4;''');
4044 // Note: it is important that each reference to class C records the prefix
4045 // used to find it; otherwise it's possible that relinking might produce an
4046 // incorrect result after a change to lib2.dart, lib3.dart, or lib4.dart.
4047 checkTypeRef(
4048 findVariable('c2').type, absUri('/lib1.dart'), 'lib1.dart', 'C');
4049 checkTypeRef(
4050 findVariable('c3').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
4051 expectedPrefix: 'a');
4052 checkTypeRef(
4053 findVariable('c4').type, absUri('/lib1.dart'), 'lib1.dart', 'C',
4054 expectedPrefix: 'b');
4055 }
4056
4057 test_type_reference_to_typedef() {
4058 checkTypeRef(serializeTypeText('F', otherDeclarations: 'typedef void F();'),
4059 null, null, 'F',
4060 expectedKind: ReferenceKind.typedef);
4061 }
4062
4063 test_type_unit_counts_unreferenced_units() {
4064 addNamedSource('/a.dart', 'library a; part "b.dart"; part "c.dart";');
4065 addNamedSource('/b.dart', 'part of a;');
4066 addNamedSource('/c.dart', 'part of a; class C {}');
4067 TypeRef typeRef =
4068 serializeTypeText('C', otherDeclarations: 'import "a.dart";');
4069 // The referenced unit should be 2, since unit 0 is a.dart and unit 1 is
4070 // b.dart. a.dart and b.dart are counted even though nothing is imported
4071 // from them.
4072 checkTypeRef(typeRef, absUri('/a.dart'), 'a.dart', 'C',
4073 expectedTargetUnit: 2);
4074 }
4075
4076 test_type_unresolved() {
4077 TypeRef typeRef = serializeTypeText('Foo', allowErrors: true);
4078 checkUnresolvedTypeRef(typeRef, null, 'Foo');
4079 }
4080
4081 test_typedef_documented() {
4082 String text = '''
4083 // Extra comment so doc comment offset != 0
4084 /**
4085 * Docs
4086 */
4087 typedef F();''';
4088 UnlinkedTypedef typedef = serializeTypedefText(text);
4089 expect(typedef.documentationComment, isNotNull);
4090 checkDocumentationComment(typedef.documentationComment, text);
4091 }
4092
4093 test_typedef_name() {
4094 String text = 'typedef F();';
4095 UnlinkedTypedef type = serializeTypedefText(text);
4096 expect(type.name, 'F');
4097 expect(type.nameOffset, text.indexOf('F'));
4098 expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
4099 expect(
4100 unlinkedUnits[0].publicNamespace.names[0].kind, ReferenceKind.typedef);
4101 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'F');
4102 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
4103 }
4104
4105 test_typedef_param_none() {
4106 UnlinkedTypedef type = serializeTypedefText('typedef F();');
4107 expect(type.parameters, isEmpty);
4108 }
4109
4110 test_typedef_param_order() {
4111 UnlinkedTypedef type = serializeTypedefText('typedef F(x, y);');
4112 expect(type.parameters, hasLength(2));
4113 expect(type.parameters[0].name, 'x');
4114 expect(type.parameters[1].name, 'y');
4115 }
4116
4117 test_typedef_private() {
4118 serializeTypedefText('typedef _F();', '_F');
4119 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
4120 }
4121
4122 test_typedef_reference_generic() {
4123 TypeRef typeRef =
4124 serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
4125 checkTypeRef(typeRef, null, null, 'F',
4126 numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
4127 }
4128
4129 test_typedef_reference_generic_imported() {
4130 addNamedSource('/lib.dart', 'typedef void F<A, B>();');
4131 TypeRef typeRef =
4132 serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
4133 checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
4134 numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
4135 }
4136
4137 test_typedef_return_type_explicit() {
4138 UnlinkedTypedef type = serializeTypedefText('typedef int F();');
4139 checkTypeRef(type.returnType, 'dart:core', 'dart:core', 'int');
4140 }
4141
4142 test_typedef_type_param_in_parameter() {
4143 UnlinkedTypedef type = serializeTypedefText('typedef F<T>(T t);');
4144 checkParamTypeRef(type.parameters[0].type, 1);
4145 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
4146 }
4147
4148 test_typedef_type_param_in_return_type() {
4149 UnlinkedTypedef type = serializeTypedefText('typedef T F<T>();');
4150 checkParamTypeRef(type.returnType, 1);
4151 }
4152
4153 test_typedef_type_param_none() {
4154 UnlinkedTypedef type = serializeTypedefText('typedef F();');
4155 expect(type.typeParameters, isEmpty);
4156 }
4157
4158 test_typedef_type_param_order() {
4159 UnlinkedTypedef type = serializeTypedefText('typedef F<T, U>();');
4160 expect(type.typeParameters, hasLength(2));
4161 expect(type.typeParameters[0].name, 'T');
4162 expect(type.typeParameters[1].name, 'U');
4163 }
4164
4165 test_unresolved_reference_in_multiple_parts() {
4166 addNamedSource('/a.dart', 'part of foo; int x; Unresolved y;');
4167 serializeLibraryText('library foo; part "a.dart"; Unresolved z;',
4168 allowErrors: true);
4169 // The unresolved types in the defining compilation unit and the part
4170 // should both work correctly even though they use different reference
4171 // indices.
4172 checkUnresolvedTypeRef(
4173 unlinkedUnits[0].variables[0].type, null, 'Unresolved');
4174 checkUnresolvedTypeRef(
4175 unlinkedUnits[1].variables[1].type, null, 'Unresolved',
4176 linkedSourceUnit: linked.units[1],
4177 unlinkedSourceUnit: unlinkedUnits[1]);
4178 }
4179
4180 test_variable() {
4181 String text = 'int i;';
4182 UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
4183 expect(v.nameOffset, text.indexOf('i;'));
4184 expect(findExecutable('i'), isNull);
4185 expect(findExecutable('i='), isNull);
4186 expect(unlinkedUnits[0].publicNamespace.names, hasLength(2));
4187 expect(unlinkedUnits[0].publicNamespace.names[0].kind,
4188 ReferenceKind.topLevelPropertyAccessor);
4189 expect(unlinkedUnits[0].publicNamespace.names[0].name, 'i');
4190 expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 0);
4191 expect(unlinkedUnits[0].publicNamespace.names[1].kind,
4192 ReferenceKind.topLevelPropertyAccessor);
4193 expect(unlinkedUnits[0].publicNamespace.names[1].name, 'i=');
4194 expect(unlinkedUnits[0].publicNamespace.names[1].numTypeParameters, 0);
4195 }
4196
4197 test_variable_const() {
4198 UnlinkedVariable variable =
4199 serializeVariableText('const int i = 0;', variableName: 'i');
4200 expect(variable.isConst, isTrue);
4201 }
4202
4203 test_variable_documented() {
4204 String text = '''
4205 // Extra comment so doc comment offset != 0
4206 /**
4207 * Docs
4208 */
4209 var v;''';
4210 UnlinkedVariable variable = serializeVariableText(text);
4211 expect(variable.documentationComment, isNotNull);
4212 checkDocumentationComment(variable.documentationComment, text);
4213 }
4214
4215 test_variable_explicit_dynamic() {
4216 UnlinkedVariable variable = serializeVariableText('dynamic v;');
4217 checkDynamicTypeRef(variable.type);
4218 expect(variable.hasImplicitType, isFalse);
4219 }
4220
4221 test_variable_final_top_level() {
4222 UnlinkedVariable variable =
4223 serializeVariableText('final int i = 0;', variableName: 'i');
4224 expect(variable.isFinal, isTrue);
4225 }
4226
4227 test_variable_implicit_dynamic() {
4228 UnlinkedVariable variable = serializeVariableText('var v;');
4229 checkDynamicTypeRef(variable.type);
4230 expect(variable.hasImplicitType, isTrue);
4231 }
4232
4233 test_variable_name() {
4234 UnlinkedVariable variable =
4235 serializeVariableText('int i;', variableName: 'i');
4236 expect(variable.name, 'i');
4237 }
4238
4239 test_variable_no_flags() {
4240 UnlinkedVariable variable =
4241 serializeVariableText('int i;', variableName: 'i');
4242 expect(variable.isStatic, isFalse);
4243 expect(variable.isConst, isFalse);
4244 expect(variable.isFinal, isFalse);
4245 }
4246
4247 test_variable_non_const() {
4248 UnlinkedVariable variable =
4249 serializeVariableText('int i = 0;', variableName: 'i');
4250 expect(variable.isConst, isFalse);
4251 }
4252
4253 test_variable_non_final() {
4254 UnlinkedVariable variable =
4255 serializeVariableText('int i;', variableName: 'i');
4256 expect(variable.isFinal, isFalse);
4257 }
4258
4259 test_variable_non_static() {
4260 UnlinkedVariable variable =
4261 serializeClassText('class C { int i; }').fields[0];
4262 expect(variable.isStatic, isFalse);
4263 }
4264
4265 test_variable_non_static_top_level() {
4266 // Top level variables are considered non-static.
4267 UnlinkedVariable variable =
4268 serializeVariableText('int i;', variableName: 'i');
4269 expect(variable.isStatic, isFalse);
4270 }
4271
4272 test_variable_private() {
4273 serializeVariableText('int _i;', variableName: '_i');
4274 expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
4275 }
4276
4277 test_variable_propagated_type_final_immediate() {
4278 UnlinkedVariable v = serializeVariableText('final v = 0;');
4279 checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
4280 }
4281
4282 test_variable_propagated_type_new_reference() {
4283 if (skipFullyLinkedData) {
4284 return;
4285 }
4286 UnlinkedVariable v = serializeVariableText('final v = 0;');
4287 // Since the propagated type of `v` is `int`, and there are no references
4288 // to `int` elsewhere in the source file, a new linked reference should
4289 // have been created for it, with no associated unlinked reference.
4290 expect(v.propagatedTypeSlot, isNot(0));
4291 TypeRef type = getTypeRefForSlot(v.propagatedTypeSlot);
4292 expect(type, isNotNull);
4293 expect(type.reference,
4294 greaterThanOrEqualTo(unlinkedUnits[0].references.length));
4295 }
4296
4297 test_variable_propagated_type_omit_dynamic() {
4298 if (skipFullyLinkedData) {
4299 return;
4300 }
4301 UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
4302 TypeRef type = getTypeRefForSlot(v.propagatedTypeSlot);
4303 checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
4304 allowTypeParameters: true, numTypeParameters: 2);
4305 expect(type.typeArguments, hasLength(1));
4306 checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
4307 }
4308
4309 test_variable_propagatedTypeSlot_const() {
4310 // Const variables are propagable so they have a nonzero
4311 // propagatedTypeSlot.
4312 UnlinkedVariable variable = serializeVariableText('const v = 0;');
4313 expect(variable.propagatedTypeSlot, isNot(0));
4314 }
4315
4316 test_variable_propagatedTypeSlot_final() {
4317 // Final variables are propagable so they have a nonzero
4318 // propagatedTypeSlot.
4319 UnlinkedVariable variable = serializeVariableText('final v = 0;');
4320 expect(variable.propagatedTypeSlot, isNot(0));
4321 }
4322
4323 test_variable_propagatedTypeSlot_non_propagable() {
4324 // Non-final non-const variables aren't propagable so they don't have a
4325 // propagatedTypeSlot.
4326 UnlinkedVariable variable = serializeVariableText('var v;');
4327 expect(variable.propagatedTypeSlot, 0);
4328 }
4329
4330 test_variable_static() {
4331 UnlinkedVariable variable =
4332 serializeClassText('class C { static int i; }').fields[0];
4333 expect(variable.isStatic, isTrue);
4334 }
4335
4336 test_variable_type() {
4337 UnlinkedVariable variable =
4338 serializeVariableText('int i;', variableName: 'i');
4339 checkTypeRef(variable.type, 'dart:core', 'dart:core', 'int');
4340 }
4341
4342 void _assertUnlinkedConst(UnlinkedConst constExpr,
4343 {List<UnlinkedConstOperation> operators,
4344 List<int> ints: const <int>[],
4345 List<double> doubles: const <double>[],
4346 List<String> strings: const <String>[],
4347 List<_TypeRefValidator> referenceValidators:
4348 const <_TypeRefValidator>[]}) {
4349 expect(constExpr, isNotNull);
4350 expect(constExpr.operations, operators);
4351 expect(constExpr.ints, ints);
4352 expect(constExpr.doubles, doubles);
4353 expect(constExpr.strings, strings);
4354 expect(constExpr.references, hasLength(referenceValidators.length));
4355 for (int i = 0; i < referenceValidators.length; i++) {
4356 referenceValidators[i](constExpr.references[i]);
4357 }
4358 }
4359 }
4360
4361 /**
4362 * Override of [SummaryTest] which creates unlinked summaries directly from the
4363 * AST.
4364 */
4365 @reflectiveTest
4366 class UnlinkedSummarizeAstTest extends Object with SummaryTest {
4367 @override
4368 LinkedLibrary linked;
4369
4370 @override
4371 List<UnlinkedUnit> unlinkedUnits;
4372
4373 /**
4374 * Map from absolute URI to the [UnlinkedUnit] for each compilation unit
4375 * passed to [addNamedSource].
4376 */
4377 Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
4378
4379 @override
4380 bool get checkAstDerivedData => true;
4381
4382 @override
4383 bool get expectAbsoluteUrisInDependencies => false;
4384
4385 @override
4386 bool get skipFullyLinkedData => true;
4387
4388 @override
4389 addNamedSource(String filePath, String contents) {
4390 CompilationUnit unit = _parseText(contents);
4391 UnlinkedUnit unlinkedUnit =
4392 new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer());
4393 uriToUnit[absUri(filePath)] = unlinkedUnit;
4394 }
4395
4396 @override
4397 void serializeLibraryText(String text, {bool allowErrors: false}) {
4398 Uri testDartUri = Uri.parse(absUri('/test.dart'));
4399 String resolveToAbsoluteUri(String relativeUri) =>
4400 testDartUri.resolve(relativeUri).toString();
4401 CompilationUnit unit = _parseText(text);
4402 UnlinkedUnit definingUnit =
4403 new UnlinkedUnit.fromBuffer(serializeAstUnlinked(unit).toBuffer());
4404 UnlinkedUnit getPart(String relativeUri) {
4405 String absoluteUri = resolveToAbsoluteUri(relativeUri);
4406 UnlinkedUnit unit = uriToUnit[absoluteUri];
4407 if (unit == null && !allowMissingFiles) {
4408 fail('Prelinker unexpectedly requested unit for "$relativeUri"'
4409 ' (resolves to "$absoluteUri").');
4410 }
4411 return unit;
4412 }
4413 UnlinkedPublicNamespace getImport(String relativeUri) {
4414 String absoluteUri = resolveToAbsoluteUri(relativeUri);
4415 UnlinkedPublicNamespace namespace = sdkPublicNamespace[absoluteUri];
4416 if (namespace == null) {
4417 namespace = uriToUnit[absoluteUri]?.publicNamespace;
4418 }
4419 if (namespace == null && !allowMissingFiles) {
4420 fail('Prelinker unexpectedly requested namespace for "$relativeUri"'
4421 ' (resolves to "$absoluteUri").'
4422 ' Namespaces available: ${uriToUnit.keys}');
4423 }
4424 return namespace;
4425 }
4426 linked = new LinkedLibrary.fromBuffer(
4427 prelink(definingUnit, getPart, getImport).toBuffer());
4428 unlinkedUnits = <UnlinkedUnit>[definingUnit];
4429 for (String relativeUri in definingUnit.publicNamespace.parts) {
4430 UnlinkedUnit unit = uriToUnit[resolveToAbsoluteUri(relativeUri)];
4431 if (unit == null) {
4432 if (!allowMissingFiles) {
4433 fail('Test referred to unknown unit $relativeUri');
4434 }
4435 } else {
4436 unlinkedUnits.add(unit);
4437 }
4438 }
4439 }
4440
4441 CompilationUnit _parseText(String text) {
4442 CharSequenceReader reader = new CharSequenceReader(text);
4443 Scanner scanner =
4444 new Scanner(null, reader, AnalysisErrorListener.NULL_LISTENER);
4445 Token token = scanner.tokenize();
4446 Parser parser = new Parser(null, AnalysisErrorListener.NULL_LISTENER);
4447 parser.parseGenericMethods = true;
4448 return parser.parseCompilationUnit(token);
4449 }
4450 }
OLDNEW
« no previous file with comments | « pkg/analyzer/test/src/summary/summary_common.dart ('k') | pkg/analyzer/test/src/summary/test_all.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698