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

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

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

Powered by Google App Engine
This is Rietveld 408576698