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

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

Issue 2353773002: Remove 'serializeLibrary(LibraryElement)' and its tests. (Closed)
Patch Set: Actually run strong mode AST based resynthesize. Created 4 years, 3 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 test.src.serialization.elements_test;
6
7 import 'dart:convert';
8
9 import 'package:analyzer/dart/ast/ast.dart';
10 import 'package:analyzer/dart/constant/value.dart';
11 import 'package:analyzer/dart/element/element.dart';
12 import 'package:analyzer/dart/element/type.dart';
13 import 'package:analyzer/error/error.dart';
14 import 'package:analyzer/src/dart/ast/ast.dart';
15 import 'package:analyzer/src/dart/element/element.dart';
16 import 'package:analyzer/src/dart/element/handle.dart';
17 import 'package:analyzer/src/dart/element/member.dart';
18 import 'package:analyzer/src/dart/element/type.dart';
19 import 'package:analyzer/src/error/codes.dart';
20 import 'package:analyzer/src/generated/engine.dart';
21 import 'package:analyzer/src/generated/resolver.dart' show Namespace;
22 import 'package:analyzer/src/generated/sdk.dart';
23 import 'package:analyzer/src/generated/source.dart';
24 import 'package:analyzer/src/generated/testing/ast_factory.dart';
25 import 'package:analyzer/src/summary/idl.dart';
26 import 'package:analyzer/src/summary/resynthesize.dart';
27 import 'package:analyzer/src/summary/summarize_elements.dart';
28 import 'package:test_reflective_loader/test_reflective_loader.dart';
29 import 'package:unittest/unittest.dart';
30
31 import '../../generated/test_support.dart';
32 import '../abstract_single_unit.dart';
33 import '../context/abstract_context.dart';
34 import 'summary_common.dart' show canonicalize;
35
36 main() {
37 groupSep = ' | ';
38 defineReflectiveTests(ResynthesizeElementTest);
39 }
40
41 /**
42 * Abstract base class for resynthesizing and comparing elements.
43 */
44 abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest {
45 Set<Source> otherLibrarySources = new Set<Source>();
46
47 /**
48 * Names of variables which have initializers that are not valid constants,
49 * so they are not resynthesized.
50 */
51 Set<String> variablesWithNotConstInitializers = new Set<String>();
52
53 /**
54 * Tests may set this to `true` to indicate that a missing file at the time of
55 * summary resynthesis shouldn't trigger an error.
56 */
57 bool allowMissingFiles = false;
58
59 bool get checkPropagatedTypes => true;
60
61 void addLibrary(String uri) {
62 otherLibrarySources.add(context.sourceFactory.forUri(uri));
63 }
64
65 Source addLibrarySource(String filePath, String contents) {
66 Source source = addSource(filePath, contents);
67 otherLibrarySources.add(source);
68 return source;
69 }
70
71 void assertNoErrors(Source source) {
72 GatheringErrorListener errorListener = new GatheringErrorListener();
73 for (AnalysisError error in context.computeErrors(source)) {
74 expect(error.source, source);
75 ErrorCode errorCode = error.errorCode;
76 if (errorCode == HintCode.UNUSED_ELEMENT ||
77 errorCode == HintCode.UNUSED_FIELD) {
78 continue;
79 }
80 if (errorCode == HintCode.UNUSED_CATCH_CLAUSE ||
81 errorCode == HintCode.UNUSED_CATCH_STACK ||
82 errorCode == HintCode.UNUSED_LOCAL_VARIABLE) {
83 continue;
84 }
85 errorListener.onError(error);
86 }
87 errorListener.assertNoErrors();
88 }
89
90 /**
91 * Verify that the given prefix is safe to elide from a resynthesized AST.
92 */
93 void checkElidablePrefix(SimpleIdentifier prefix) {
94 if (prefix.staticElement is! PrefixElement &&
95 prefix.staticElement is! ClassElement) {
96 fail('Prefix of type ${prefix.staticElement.runtimeType}'
97 ' should not have been elided');
98 }
99 }
100
101 void checkLibraryElements(
102 LibraryElementImpl original, LibraryElementImpl resynthesized) {
103 compareElements(resynthesized, original, '(library)');
104 expect(resynthesized.displayName, original.displayName);
105 expect(original.enclosingElement, isNull);
106 expect(resynthesized.enclosingElement, isNull);
107 expect(resynthesized.hasExtUri, original.hasExtUri);
108 compareCompilationUnitElements(resynthesized.definingCompilationUnit,
109 original.definingCompilationUnit);
110 expect(resynthesized.parts.length, original.parts.length, reason: 'parts');
111 for (int i = 0; i < resynthesized.parts.length; i++) {
112 compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]);
113 }
114 expect(resynthesized.imports.length, original.imports.length,
115 reason: 'imports');
116 for (int i = 0; i < resynthesized.imports.length; i++) {
117 ImportElement originalImport = original.imports[i];
118 compareImportElements(
119 resynthesized.imports[i], originalImport, originalImport.toString());
120 }
121 expect(resynthesized.exports.length, original.exports.length,
122 reason: 'exports');
123 for (int i = 0; i < resynthesized.exports.length; i++) {
124 ExportElement originalExport = original.exports[i];
125 compareExportElements(
126 resynthesized.exports[i], originalExport, originalExport.toString());
127 }
128 expect(resynthesized.nameLength, original.nameLength);
129 compareNamespaces(resynthesized.publicNamespace, original.publicNamespace,
130 '(public namespace)');
131 compareNamespaces(resynthesized.exportNamespace, original.exportNamespace,
132 '(export namespace)');
133 if (original.entryPoint == null) {
134 expect(resynthesized.entryPoint, isNull);
135 } else {
136 expect(resynthesized.entryPoint, isNotNull);
137 compareFunctionElements(
138 resynthesized.entryPoint, original.entryPoint, '(entry point)');
139 }
140 // The libraries `dart:core` and `dart:async` cannot create their
141 // `loadLibrary` functions until after both are created.
142 if (original.name != 'dart.core' && original.name != 'dart.async') {
143 compareExecutableElements(
144 resynthesized.loadLibraryFunction as ExecutableElementImpl,
145 original.loadLibraryFunction as ExecutableElementImpl,
146 '(loadLibraryFunction)');
147 }
148 expect(resynthesized.libraryCycle.toSet(), original.libraryCycle.toSet());
149 }
150
151 /**
152 * Verify that the [resynthesizer] didn't do any unnecessary work when
153 * resynthesizing [library].
154 */
155 void checkMinimalResynthesisWork(
156 TestSummaryResynthesizer resynthesizer, LibraryElement library) {
157 // Check that no other summaries needed to be resynthesized to resynthesize
158 // the library element.
159 expect(resynthesizer.resynthesisCount, 1);
160 // Check that the only linked summary consulted was that for [uri].
161 expect(resynthesizer.linkedSummariesRequested, hasLength(1));
162 expect(resynthesizer.linkedSummariesRequested.first,
163 library.source.uri.toString());
164 // Check that the only unlinked summaries consulted were those for the
165 // library in question.
166 Set<String> expectedCompilationUnitUris = library.units
167 .map((CompilationUnitElement unit) => unit.source.uri.toString())
168 .toSet();
169 for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
170 expect(expectedCompilationUnitUris, contains(requestedUri));
171 }
172 }
173
174 void checkPossibleLocalElements(Element resynthesized, Element original) {
175 if (original is! LocalElement && resynthesized is! LocalElement) {
176 return;
177 }
178 if (original is LocalElement && resynthesized is LocalElement) {
179 expect(resynthesized.visibleRange, original.visibleRange);
180 } else {
181 fail('Incompatible local elements '
182 '${resynthesized.runtimeType} vs. ${original.runtimeType}');
183 }
184 }
185
186 void checkPossibleMember(
187 Element resynthesized, Element original, String desc) {
188 Element resynthesizedNonHandle = resynthesized is ElementHandle
189 ? resynthesized.actualElement
190 : resynthesized;
191 if (original is Member) {
192 expect(resynthesizedNonHandle, new isInstanceOf<Member>(), reason: desc);
193 if (resynthesizedNonHandle is Member) {
194 List<DartType> resynthesizedTypeArguments =
195 resynthesizedNonHandle.definingType.typeArguments;
196 List<DartType> originalTypeArguments =
197 original.definingType.typeArguments;
198 expect(
199 resynthesizedTypeArguments, hasLength(originalTypeArguments.length),
200 reason: desc);
201 for (int i = 0; i < originalTypeArguments.length; i++) {
202 compareTypeImpls(resynthesizedTypeArguments[i],
203 originalTypeArguments[i], '$desc type argument $i');
204 }
205 }
206 } else {
207 expect(
208 resynthesizedNonHandle, isNot(new isInstanceOf<ConstructorMember>()),
209 reason: desc);
210 }
211 }
212
213 void compareClassElements(ClassElement r, ClassElement o, String desc) {
214 compareElements(r, o, desc);
215 expect(r.fields.length, o.fields.length, reason: '$desc fields.length');
216 for (int i = 0; i < r.fields.length; i++) {
217 String name = o.fields[i].name;
218 compareFieldElements(r.fields[i], o.fields[i], '$desc.field $name');
219 }
220 compareTypes(r.supertype, o.supertype, '$desc supertype');
221 expect(r.interfaces.length, o.interfaces.length,
222 reason: '$desc interfaces.length');
223 for (int i = 0; i < r.interfaces.length; i++) {
224 compareTypes(r.interfaces[i], o.interfaces[i],
225 '$desc interface ${o.interfaces[i].name}');
226 }
227 expect(r.mixins.length, o.mixins.length, reason: '$desc mixins.length');
228 for (int i = 0; i < r.mixins.length; i++) {
229 compareTypes(r.mixins[i], o.mixins[i], '$desc mixin ${o.mixins[i].name}');
230 }
231 expect(r.typeParameters.length, o.typeParameters.length,
232 reason: '$desc typeParameters.length');
233 for (int i = 0; i < r.typeParameters.length; i++) {
234 compareTypeParameterElements(r.typeParameters[i], o.typeParameters[i],
235 '$desc type parameter ${o.typeParameters[i].name}');
236 }
237 expect(r.constructors.length, o.constructors.length,
238 reason: '$desc constructors.length');
239 for (int i = 0; i < r.constructors.length; i++) {
240 compareConstructorElements(r.constructors[i], o.constructors[i],
241 '$desc constructor ${o.constructors[i].name}');
242 }
243 expect(r.accessors.length, o.accessors.length,
244 reason: '$desc accessors.length');
245 List<PropertyAccessorElement> rAccessors = _getSortedPropertyAccessors(r);
246 List<PropertyAccessorElement> oAccessors = _getSortedPropertyAccessors(o);
247 for (int i = 0; i < r.accessors.length; i++) {
248 comparePropertyAccessorElements(
249 rAccessors[i], oAccessors[i], '$desc accessor ${oAccessors[i].name}');
250 }
251 expect(r.methods.length, o.methods.length, reason: '$desc methods.length');
252 for (int i = 0; i < r.methods.length; i++) {
253 compareMethodElements(
254 r.methods[i], o.methods[i], '$desc.${o.methods[i].name}');
255 }
256 compareTypes(r.type, o.type, desc);
257 if (r is ClassElementImpl && o is ClassElementImpl) {
258 expect(r.hasBeenInferred, o.hasBeenInferred, reason: desc);
259 }
260 }
261
262 void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized,
263 CompilationUnitElementImpl original) {
264 String desc = 'Compilation unit ${original.source.uri}';
265 compareUriReferencedElements(resynthesized, original, desc);
266 expect(resynthesized.source, original.source);
267 expect(resynthesized.librarySource, original.librarySource);
268 expect(resynthesized.types.length, original.types.length,
269 reason: '$desc types');
270 for (int i = 0; i < resynthesized.types.length; i++) {
271 compareClassElements(
272 resynthesized.types[i], original.types[i], original.types[i].name);
273 }
274 expect(resynthesized.topLevelVariables.length,
275 original.topLevelVariables.length,
276 reason: '$desc topLevelVariables');
277 for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
278 String name = resynthesized.topLevelVariables[i].name;
279 compareTopLevelVariableElements(
280 resynthesized.topLevelVariables[i],
281 original.topLevelVariables
282 .singleWhere((TopLevelVariableElement e) => e.name == name),
283 'variable $name');
284 }
285 expect(resynthesized.functions.length, original.functions.length,
286 reason: '$desc functions');
287 for (int i = 0; i < resynthesized.functions.length; i++) {
288 compareFunctionElements(resynthesized.functions[i], original.functions[i],
289 'function ${original.functions[i].name}');
290 }
291 expect(resynthesized.functionTypeAliases.length,
292 original.functionTypeAliases.length,
293 reason: '$desc functionTypeAliases');
294 for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) {
295 compareFunctionTypeAliasElements(
296 resynthesized.functionTypeAliases[i],
297 original.functionTypeAliases[i],
298 original.functionTypeAliases[i].name);
299 }
300 expect(resynthesized.enums.length, original.enums.length,
301 reason: '$desc enums');
302 for (int i = 0; i < resynthesized.enums.length; i++) {
303 compareClassElements(
304 resynthesized.enums[i], original.enums[i], original.enums[i].name);
305 }
306 expect(resynthesized.accessors.length, original.accessors.length,
307 reason: '$desc accessors');
308 for (int i = 0; i < resynthesized.accessors.length; i++) {
309 String name = resynthesized.accessors[i].name;
310 if (original.accessors[i].isGetter) {
311 comparePropertyAccessorElements(
312 resynthesized.accessors[i],
313 original.accessors
314 .singleWhere((PropertyAccessorElement e) => e.name == name),
315 'getter $name');
316 } else {
317 comparePropertyAccessorElements(
318 resynthesized.accessors[i],
319 original.accessors
320 .singleWhere((PropertyAccessorElement e) => e.name == name),
321 'setter $name');
322 }
323 }
324 // Note: no need to test CompilationUnitElementImpl._offsetToElementMap
325 // since it is built on demand when needed (see
326 // CompilationUnitElementImpl.getElementAt])
327 }
328
329 void compareConstAstLists(
330 List<Object> rItems, List<Object> oItems, String desc) {
331 if (rItems == null && oItems == null) {
332 return;
333 }
334 expect(rItems != null && oItems != null, isTrue);
335 expect(rItems, hasLength(oItems.length));
336 for (int i = 0; i < oItems.length; i++) {
337 Object rItem = rItems[i];
338 Object oItem = oItems[i];
339 if (rItem is Expression && oItem is Expression) {
340 compareConstAsts(rItem, oItem, desc);
341 } else if (rItem is TypeName && oItem is TypeName) {
342 compareConstAsts(rItem.name, oItem.name, desc);
343 } else if (rItem is InterpolationString && oItem is InterpolationString) {
344 expect(rItem.value, oItem.value);
345 } else if (rItem is InterpolationExpression &&
346 oItem is InterpolationExpression) {
347 compareConstAsts(rItem.expression, oItem.expression, desc);
348 } else if (rItem is MapLiteralEntry && oItem is MapLiteralEntry) {
349 compareConstAsts(rItem.key, oItem.key, desc);
350 compareConstAsts(rItem.value, oItem.value, desc);
351 } else if (oItem is ConstructorFieldInitializer &&
352 rItem is ConstructorFieldInitializer) {
353 compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
354 if (variablesWithNotConstInitializers.contains(rItem.fieldName.name)) {
355 _assertUnresolvedIdentifier(rItem.expression, desc);
356 } else {
357 compareConstAsts(rItem.expression, oItem.expression, desc);
358 }
359 } else if (oItem is SuperConstructorInvocation &&
360 rItem is SuperConstructorInvocation) {
361 compareElements(rItem.staticElement, oItem.staticElement, desc);
362 compareConstAsts(rItem.constructorName, oItem.constructorName, desc);
363 compareConstAstLists(
364 rItem.argumentList.arguments, oItem.argumentList.arguments, desc);
365 } else if (oItem is RedirectingConstructorInvocation &&
366 rItem is RedirectingConstructorInvocation) {
367 compareElements(rItem.staticElement, oItem.staticElement, desc);
368 compareConstAsts(rItem.constructorName, oItem.constructorName, desc);
369 compareConstAstLists(
370 rItem.argumentList.arguments, oItem.argumentList.arguments, desc);
371 } else {
372 fail('$desc Incompatible item types: '
373 '${rItem.runtimeType} vs. ${oItem.runtimeType}');
374 }
375 }
376 }
377
378 void compareConstAsts(AstNode r, AstNode o, String desc) {
379 if (o == null) {
380 expect(r, isNull, reason: desc);
381 } else {
382 expect(r, isNotNull, reason: desc);
383 // ConstantAstCloner does not copy static types, and constant values
384 // computer does not use static types. So, we don't set them during
385 // resynthesis and should not check them here.
386 if (o is ParenthesizedExpression) {
387 // We don't resynthesize parenthesis, so just ignore it.
388 compareConstAsts(r, o.expression, desc);
389 } else if (o is SimpleIdentifier && r is SimpleIdentifier) {
390 expect(r.name, o.name, reason: desc);
391 compareElements(r.staticElement, o.staticElement, desc);
392 } else if (o is PrefixedIdentifier && r is SimpleIdentifier) {
393 // We don't resynthesize prefixed identifiers when the prefix refers to
394 // a PrefixElement or a ClassElement. We use simple identifiers with
395 // correct elements.
396 if (o.prefix.staticElement is PrefixElement ||
397 o.prefix.staticElement is ClassElement) {
398 compareConstAsts(r, o.identifier, desc);
399 } else {
400 fail('Prefix of type ${o.prefix.staticElement.runtimeType} should not'
401 ' have been elided');
402 }
403 } else if (o is SimpleIdentifier && r is PrefixedIdentifier) {
404 // In 'class C {static const a = 0; static const b = a;}' the reference
405 // to 'a' in 'b' is serialized as a fully qualified 'C.a' reference.
406 if (r.prefix.staticElement is ClassElement) {
407 compareElements(
408 r.prefix.staticElement, o.staticElement?.enclosingElement, desc);
409 compareConstAsts(r.identifier, o, desc);
410 } else {
411 fail('Prefix of type ${r.prefix.staticElement.runtimeType} should not'
412 ' have been elided');
413 }
414 } else if (o is PropertyAccess &&
415 o.target is PrefixedIdentifier &&
416 r is PrefixedIdentifier) {
417 // We don't resynthesize prefixed identifiers when the prefix refers to
418 // a PrefixElement or a ClassElement. Which means that if the original
419 // expression was e.g. `prefix.topLevelVariableName.length`, it will get
420 // resynthesized as `topLevelVariableName.length`
421 PrefixedIdentifier oTarget = o.target;
422 checkElidablePrefix(oTarget.prefix);
423 compareConstAsts(
424 r, AstFactory.identifier(oTarget.identifier, o.propertyName), desc);
425 } else if (o is PrefixedIdentifier && r is PrefixedIdentifier) {
426 compareConstAsts(r.prefix, o.prefix, desc);
427 compareConstAsts(r.identifier, o.identifier, desc);
428 } else if (o is PropertyAccess && r is PropertyAccess) {
429 compareConstAsts(r.target, o.target, desc);
430 String oName = o.propertyName.name;
431 String rName = r.propertyName.name;
432 expect(rName, oName, reason: desc);
433 if (oName == 'length') {
434 compareElements(
435 r.propertyName.staticElement, o.propertyName.staticElement, desc);
436 }
437 } else if (o is PropertyAccess &&
438 o.target is PrefixedIdentifier &&
439 r is SimpleIdentifier) {
440 // We don't resynthesize property access when it takes the form
441 // `prefixName.className.staticMember`. We just resynthesize a
442 // SimpleIdentifier correctly resolved to the static member.
443 PrefixedIdentifier oTarget = o.target;
444 checkElidablePrefix(oTarget.prefix);
445 checkElidablePrefix(oTarget.identifier);
446 compareConstAsts(r, o.propertyName, desc);
447 } else if (o is NullLiteral) {
448 expect(r, new isInstanceOf<NullLiteral>(), reason: desc);
449 } else if (o is BooleanLiteral && r is BooleanLiteral) {
450 expect(r.value, o.value, reason: desc);
451 } else if (o is IntegerLiteral && r is IntegerLiteral) {
452 expect(r.value, o.value, reason: desc);
453 } else if (o is DoubleLiteral && r is DoubleLiteral) {
454 if (r.value != null &&
455 r.value.isNaN &&
456 o.value != null &&
457 o.value.isNaN) {
458 // NaN is not comparable.
459 } else {
460 expect(r.value, o.value, reason: desc);
461 }
462 } else if (o is StringInterpolation && r is StringInterpolation) {
463 compareConstAstLists(r.elements, o.elements, desc);
464 } else if (o is StringLiteral && r is StringLiteral) {
465 // We don't keep all the tokens of AdjacentStrings.
466 // So, we can compare only their values.
467 expect(r.stringValue, o.stringValue, reason: desc);
468 } else if (o is SymbolLiteral && r is SymbolLiteral) {
469 // We don't keep all the tokens of symbol literals.
470 // So, we can compare only their values.
471 expect(r.components.map((t) => t.lexeme).join('.'),
472 o.components.map((t) => t.lexeme).join('.'),
473 reason: desc);
474 } else if (o is NamedExpression && r is NamedExpression) {
475 expect(r.name.label.name, o.name.label.name, reason: desc);
476 compareConstAsts(r.expression, o.expression, desc);
477 } else if (o is BinaryExpression && r is BinaryExpression) {
478 expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
479 compareConstAsts(r.leftOperand, o.leftOperand, desc);
480 compareConstAsts(r.rightOperand, o.rightOperand, desc);
481 } else if (o is PrefixExpression && r is PrefixExpression) {
482 expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
483 compareConstAsts(r.operand, o.operand, desc);
484 } else if (o is ConditionalExpression && r is ConditionalExpression) {
485 compareConstAsts(r.condition, o.condition, desc);
486 compareConstAsts(r.thenExpression, o.thenExpression, desc);
487 compareConstAsts(r.elseExpression, o.elseExpression, desc);
488 } else if (o is ListLiteral && r is ListLiteral) {
489 compareConstAstLists(
490 r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
491 compareConstAstLists(r.elements, o.elements, desc);
492 } else if (o is MapLiteral && r is MapLiteral) {
493 compareConstAstLists(
494 r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
495 compareConstAstLists(r.entries, o.entries, desc);
496 } else if (o is MethodInvocation && r is MethodInvocation) {
497 compareConstAsts(r.target, o.target, desc);
498 compareConstAsts(r.methodName, o.methodName, desc);
499 compareConstAstLists(
500 r.typeArguments?.arguments, o.typeArguments?.arguments, desc);
501 compareConstAstLists(
502 r.argumentList?.arguments, o.argumentList?.arguments, desc);
503 } else if (o is InstanceCreationExpression &&
504 r is InstanceCreationExpression) {
505 compareElements(r.staticElement, o.staticElement, desc);
506 ConstructorName oConstructor = o.constructorName;
507 ConstructorName rConstructor = r.constructorName;
508 expect(oConstructor, isNotNull, reason: desc);
509 expect(rConstructor, isNotNull, reason: desc);
510 // Note: just compare rConstructor.staticElement and
511 // oConstructor.staticElement as elements, because we just want to
512 // check that they're pointing to the correct elements; we don't want
513 // to check that their constructor initializers match, because that
514 // could lead to infinite regress.
515 compareElements(
516 rConstructor.staticElement, oConstructor.staticElement, desc);
517 TypeName oType = oConstructor.type;
518 TypeName rType = rConstructor.type;
519 expect(oType, isNotNull, reason: desc);
520 expect(rType, isNotNull, reason: desc);
521 compareConstAsts(rType.name, oType.name, desc);
522 compareConstAsts(rConstructor.name, oConstructor.name, desc);
523 // In strong mode type inference is performed, so that
524 // `C<int> v = new C();` is serialized as `C<int> v = new C<int>();`.
525 // So, if there are not type arguments originally, not need to check.
526 if (oType.typeArguments?.arguments?.isNotEmpty ?? false) {
527 compareConstAstLists(rType.typeArguments?.arguments,
528 oType.typeArguments?.arguments, desc);
529 }
530 compareConstAstLists(
531 r.argumentList.arguments, o.argumentList.arguments, desc);
532 } else if (o is AnnotationImpl && r is AnnotationImpl) {
533 expect(o.atSign.lexeme, r.atSign.lexeme, reason: desc);
534 Identifier rName = r.name;
535 Identifier oName = o.name;
536 if (oName is PrefixedIdentifier && o.constructorName != null) {
537 // E.g. `@prefix.cls.ctor`. This gets resynthesized as `@cls.ctor`,
538 // with `cls.ctor` represented as a PrefixedIdentifier.
539 expect(rName, new isInstanceOf<PrefixedIdentifier>(), reason: desc);
540 if (rName is PrefixedIdentifier) {
541 compareConstAsts(rName.prefix, oName.identifier, desc);
542 expect(rName.period.lexeme, '.', reason: desc);
543 compareConstAsts(rName.identifier, o.constructorName, desc);
544 expect(r.period, isNull, reason: desc);
545 expect(r.constructorName, isNull, reason: desc);
546 }
547 } else {
548 compareConstAsts(r.name, o.name, desc);
549 expect(r.period?.lexeme, o.period?.lexeme, reason: desc);
550 compareConstAsts(r.constructorName, o.constructorName, desc);
551 }
552 compareConstAstLists(
553 r.arguments?.arguments, o.arguments?.arguments, desc);
554 Element expectedElement = o.element;
555 if (oName is PrefixedIdentifier && o.constructorName != null) {
556 // Due to dartbug.com/25706, [o.element] incorrectly points to the
557 // class rather than the named constructor. Hack around this.
558 // TODO(paulberry): when dartbug.com/25706 is fixed, remove this.
559 expectedElement = (expectedElement as ClassElement)
560 .getNamedConstructor(o.constructorName.name);
561 expect(expectedElement, isNotNull, reason: desc);
562 }
563 compareElements(r.element, expectedElement, desc);
564 // elementAnnotation should be null; it is only used in the full AST.
565 expect(o.elementAnnotation, isNull);
566 expect(r.elementAnnotation, isNull);
567 } else {
568 fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}');
569 }
570 }
571 }
572
573 void compareConstructorElements(ConstructorElement resynthesized,
574 ConstructorElement original, String desc) {
575 if (original == null && resynthesized == null) {
576 return;
577 }
578 compareExecutableElements(resynthesized, original, desc);
579 ConstructorElementImpl resynthesizedImpl =
580 getActualElement(resynthesized, desc);
581 ConstructorElementImpl originalImpl = getActualElement(original, desc);
582 if (original.isConst) {
583 compareConstAstLists(resynthesizedImpl.constantInitializers,
584 originalImpl.constantInitializers, desc);
585 }
586 if (original.redirectedConstructor == null) {
587 expect(resynthesized.redirectedConstructor, isNull, reason: desc);
588 } else {
589 compareConstructorElements(resynthesized.redirectedConstructor,
590 original.redirectedConstructor, '$desc redirectedConstructor');
591 }
592 checkPossibleMember(resynthesized, original, desc);
593 expect(resynthesized.nameEnd, original.nameEnd, reason: desc);
594 expect(resynthesized.periodOffset, original.periodOffset, reason: desc);
595 expect(resynthesizedImpl.isCycleFree, originalImpl.isCycleFree,
596 reason: desc);
597 }
598
599 void compareConstValues(
600 DartObject resynthesized, DartObject original, String desc) {
601 if (original == null) {
602 expect(resynthesized, isNull, reason: desc);
603 } else {
604 expect(resynthesized, isNotNull, reason: desc);
605 compareTypes(resynthesized.type, original.type, desc);
606 expect(resynthesized.hasKnownValue, original.hasKnownValue, reason: desc);
607 if (original.isNull) {
608 expect(resynthesized.isNull, isTrue, reason: desc);
609 } else if (original.toBoolValue() != null) {
610 expect(resynthesized.toBoolValue(), original.toBoolValue(),
611 reason: desc);
612 } else if (original.toIntValue() != null) {
613 expect(resynthesized.toIntValue(), original.toIntValue(), reason: desc);
614 } else if (original.toDoubleValue() != null) {
615 expect(resynthesized.toDoubleValue(), original.toDoubleValue(),
616 reason: desc);
617 } else if (original.toListValue() != null) {
618 List<DartObject> resynthesizedList = resynthesized.toListValue();
619 List<DartObject> originalList = original.toListValue();
620 expect(resynthesizedList, hasLength(originalList.length));
621 for (int i = 0; i < originalList.length; i++) {
622 compareConstValues(resynthesizedList[i], originalList[i], desc);
623 }
624 } else if (original.toMapValue() != null) {
625 Map<DartObject, DartObject> resynthesizedMap =
626 resynthesized.toMapValue();
627 Map<DartObject, DartObject> originalMap = original.toMapValue();
628 expect(resynthesizedMap, hasLength(originalMap.length));
629 List<DartObject> resynthesizedKeys = resynthesizedMap.keys.toList();
630 List<DartObject> originalKeys = originalMap.keys.toList();
631 for (int i = 0; i < originalKeys.length; i++) {
632 DartObject resynthesizedKey = resynthesizedKeys[i];
633 DartObject originalKey = originalKeys[i];
634 compareConstValues(resynthesizedKey, originalKey, desc);
635 DartObject resynthesizedValue = resynthesizedMap[resynthesizedKey];
636 DartObject originalValue = originalMap[originalKey];
637 compareConstValues(resynthesizedValue, originalValue, desc);
638 }
639 } else if (original.toStringValue() != null) {
640 expect(resynthesized.toStringValue(), original.toStringValue(),
641 reason: desc);
642 } else if (original.toSymbolValue() != null) {
643 expect(resynthesized.toSymbolValue(), original.toSymbolValue(),
644 reason: desc);
645 } else if (original.toTypeValue() != null) {
646 fail('Not implemented');
647 }
648 }
649 }
650
651 void compareElementAnnotations(ElementAnnotationImpl resynthesized,
652 ElementAnnotationImpl original, String desc) {
653 expect(resynthesized.element, isNotNull, reason: desc);
654 expect(resynthesized.element.kind, original.element.kind, reason: desc);
655 expect(resynthesized.element.location, original.element.location,
656 reason: desc);
657 expect(resynthesized.compilationUnit, isNotNull, reason: desc);
658 expect(resynthesized.compilationUnit.location,
659 original.compilationUnit.location,
660 reason: desc);
661 expect(resynthesized.annotationAst, isNotNull, reason: desc);
662 compareConstAsts(resynthesized.annotationAst, original.annotationAst, desc);
663 }
664
665 void compareElements(Element resynthesized, Element original, String desc) {
666 ElementImpl rImpl = getActualElement(resynthesized, desc);
667 ElementImpl oImpl = getActualElement(original, desc);
668 if (oImpl == null && rImpl == null) {
669 return;
670 }
671 if (oImpl is PrefixElement) {
672 // TODO(scheglov) prefixes cannot be resynthesized
673 return;
674 }
675 expect(original, isNotNull);
676 expect(resynthesized, isNotNull, reason: desc);
677 if (rImpl is DefaultParameterElementImpl && oImpl is ParameterElementImpl) {
678 // This is ok provided the resynthesized parameter element doesn't have
679 // any evaluation result.
680 expect(rImpl.evaluationResult, isNull);
681 } else {
682 Type rRuntimeType;
683 if (rImpl is ConstFieldElementImpl) {
684 rRuntimeType = ConstFieldElementImpl;
685 } else if (rImpl is FunctionElementImpl) {
686 rRuntimeType = FunctionElementImpl;
687 } else {
688 rRuntimeType = rImpl.runtimeType;
689 }
690 expect(rRuntimeType, oImpl.runtimeType);
691 }
692 expect(resynthesized.kind, original.kind);
693 expect(resynthesized.location, original.location, reason: desc);
694 expect(resynthesized.name, original.name);
695 expect(resynthesized.nameOffset, original.nameOffset, reason: desc);
696 expect(rImpl.codeOffset, oImpl.codeOffset, reason: desc);
697 expect(rImpl.codeLength, oImpl.codeLength, reason: desc);
698 expect(resynthesized.documentationComment, original.documentationComment,
699 reason: desc);
700 compareMetadata(resynthesized.metadata, original.metadata, desc);
701
702 // Validate modifiers.
703 for (Modifier modifier in Modifier.values) {
704 bool got = _hasModifier(resynthesized, modifier);
705 bool want = _hasModifier(original, modifier);
706 expect(got, want,
707 reason: 'Mismatch in $desc.$modifier: got $got, want $want');
708 }
709
710 // Validate members.
711 if (oImpl is Member) {
712 expect(rImpl, new isInstanceOf<Member>(), reason: desc);
713 } else {
714 expect(rImpl, isNot(new isInstanceOf<Member>()), reason: desc);
715 }
716 }
717
718 void compareExecutableElements(
719 ExecutableElement resynthesized, ExecutableElement original, String desc,
720 {bool shallow: false}) {
721 compareElements(resynthesized, original, desc);
722 compareParameterElementLists(
723 resynthesized.parameters, original.parameters, desc);
724 if (checkPropagatedTypes || !original.hasImplicitReturnType) {
725 compareTypes(
726 resynthesized.returnType, original.returnType, '$desc return type');
727 }
728 if (!shallow) {
729 compareTypes(resynthesized.type, original.type, desc);
730 }
731 expect(resynthesized.typeParameters.length, original.typeParameters.length);
732 for (int i = 0; i < resynthesized.typeParameters.length; i++) {
733 compareTypeParameterElements(
734 resynthesized.typeParameters[i],
735 original.typeParameters[i],
736 '$desc type parameter ${original.typeParameters[i].name}');
737 }
738 compareLocalElementsOfExecutable(resynthesized, original, desc);
739 }
740
741 void compareExportElements(ExportElementImpl resynthesized,
742 ExportElementImpl original, String desc) {
743 compareUriReferencedElements(resynthesized, original, desc);
744 expect(resynthesized.exportedLibrary.location,
745 original.exportedLibrary.location);
746 expect(resynthesized.combinators.length, original.combinators.length);
747 for (int i = 0; i < resynthesized.combinators.length; i++) {
748 compareNamespaceCombinators(
749 resynthesized.combinators[i], original.combinators[i]);
750 }
751 }
752
753 void compareFieldElements(
754 FieldElementImpl resynthesized, FieldElementImpl original, String desc) {
755 comparePropertyInducingElements(resynthesized, original, desc);
756 }
757
758 void compareFunctionElements(
759 FunctionElement resynthesized, FunctionElement original, String desc,
760 {bool shallow: false}) {
761 if (original == null && resynthesized == null) {
762 return;
763 }
764 expect(resynthesized, isNotNull, reason: desc);
765 compareExecutableElements(resynthesized, original, desc, shallow: shallow);
766 checkPossibleLocalElements(resynthesized, original);
767 }
768
769 void compareFunctionTypeAliasElements(
770 FunctionTypeAliasElementImpl resynthesized,
771 FunctionTypeAliasElementImpl original,
772 String desc) {
773 compareElements(resynthesized, original, desc);
774 compareParameterElementLists(
775 resynthesized.parameters, original.parameters, desc);
776 compareTypes(
777 resynthesized.returnType, original.returnType, '$desc return type');
778 compareTypes(resynthesized.type, original.type, desc);
779 expect(resynthesized.typeParameters.length, original.typeParameters.length);
780 for (int i = 0; i < resynthesized.typeParameters.length; i++) {
781 compareTypeParameterElements(
782 resynthesized.typeParameters[i],
783 original.typeParameters[i],
784 '$desc type parameter ${original.typeParameters[i].name}');
785 }
786 }
787
788 void compareImportElements(ImportElementImpl resynthesized,
789 ImportElementImpl original, String desc) {
790 compareUriReferencedElements(resynthesized, original, desc);
791 expect(resynthesized.importedLibrary.location,
792 original.importedLibrary.location,
793 reason: '$desc importedLibrary location');
794 expect(resynthesized.prefixOffset, original.prefixOffset,
795 reason: '$desc prefixOffset');
796 if (original.prefix == null) {
797 expect(resynthesized.prefix, isNull, reason: '$desc prefix');
798 } else {
799 comparePrefixElements(
800 resynthesized.prefix, original.prefix, original.prefix.name);
801 }
802 expect(resynthesized.combinators.length, original.combinators.length,
803 reason: '$desc combinators');
804 for (int i = 0; i < resynthesized.combinators.length; i++) {
805 compareNamespaceCombinators(
806 resynthesized.combinators[i], original.combinators[i]);
807 }
808 }
809
810 void compareLabelElements(
811 LabelElementImpl resynthesized, LabelElementImpl original, String desc) {
812 expect(resynthesized.isOnSwitchMember, original.isOnSwitchMember,
813 reason: desc);
814 expect(resynthesized.isOnSwitchStatement, original.isOnSwitchStatement,
815 reason: desc);
816 compareElements(resynthesized, original, desc);
817 }
818
819 void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
820 ExecutableElement original, String desc) {
821 if (original is! Member) {
822 List<FunctionElement> rFunctions = resynthesized.functions;
823 List<FunctionElement> oFunctions = original.functions;
824 expect(rFunctions, hasLength(oFunctions.length));
825 for (int i = 0; i < oFunctions.length; i++) {
826 compareFunctionElements(rFunctions[i], oFunctions[i],
827 '$desc local function ${oFunctions[i].name}');
828 }
829 }
830 if (original is! Member) {
831 List<LabelElement> rLabels = resynthesized.labels;
832 List<LabelElement> oLabels = original.labels;
833 expect(rLabels, hasLength(oLabels.length));
834 for (int i = 0; i < oLabels.length; i++) {
835 compareLabelElements(
836 rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
837 }
838 }
839 if (original is! Member) {
840 List<LocalVariableElement> rVariables = resynthesized.localVariables;
841 List<LocalVariableElement> oVariables = original.localVariables;
842 expect(rVariables, hasLength(oVariables.length));
843 for (int i = 0; i < oVariables.length; i++) {
844 compareVariableElements(rVariables[i], oVariables[i],
845 '$desc local variable ${oVariables[i].name}');
846 }
847 }
848 }
849
850 void compareMetadata(List<ElementAnnotation> resynthesized,
851 List<ElementAnnotation> original, String desc) {
852 expect(resynthesized, hasLength(original.length), reason: desc);
853 for (int i = 0; i < original.length; i++) {
854 compareElementAnnotations(
855 resynthesized[i], original[i], '$desc annotation $i');
856 }
857 }
858
859 void compareMethodElements(MethodElementImpl resynthesized,
860 MethodElementImpl original, String desc) {
861 // TODO(paulberry): do we need to deal with
862 // MultiplyInheritedMethodElementImpl?
863 compareExecutableElements(resynthesized, original, desc);
864 }
865
866 void compareNamespaceCombinators(
867 NamespaceCombinator resynthesized, NamespaceCombinator original) {
868 if (original is ShowElementCombinatorImpl &&
869 resynthesized is ShowElementCombinatorImpl) {
870 expect(resynthesized.shownNames, original.shownNames,
871 reason: 'shownNames');
872 expect(resynthesized.offset, original.offset, reason: 'offset');
873 expect(resynthesized.end, original.end, reason: 'end');
874 } else if (original is HideElementCombinatorImpl &&
875 resynthesized is HideElementCombinatorImpl) {
876 expect(resynthesized.hiddenNames, original.hiddenNames,
877 reason: 'hiddenNames');
878 } else if (resynthesized.runtimeType != original.runtimeType) {
879 fail(
880 'Type mismatch: expected ${original.runtimeType}, got ${resynthesized. runtimeType}');
881 } else {
882 fail('Unimplemented comparison for ${original.runtimeType}');
883 }
884 }
885
886 void compareNamespaces(
887 Namespace resynthesized, Namespace original, String desc) {
888 Map<String, Element> resynthesizedMap = resynthesized.definedNames;
889 Map<String, Element> originalMap = original.definedNames;
890 expect(resynthesizedMap.keys.toSet(), originalMap.keys.toSet(),
891 reason: desc);
892 for (String key in originalMap.keys) {
893 Element resynthesizedElement = resynthesizedMap[key];
894 Element originalElement = originalMap[key];
895 compareElements(resynthesizedElement, originalElement, key);
896 }
897 }
898
899 void compareParameterElementLists(
900 List<ParameterElement> resynthesizedParameters,
901 List<ParameterElement> originalParameters,
902 String desc) {
903 expect(resynthesizedParameters.length, originalParameters.length);
904 for (int i = 0; i < resynthesizedParameters.length; i++) {
905 compareParameterElements(
906 resynthesizedParameters[i],
907 originalParameters[i],
908 '$desc parameter ${originalParameters[i].name}');
909 }
910 }
911
912 void compareParameterElements(
913 ParameterElement resynthesized, ParameterElement original, String desc) {
914 compareVariableElements(resynthesized, original, desc);
915 compareParameterElementLists(
916 resynthesized.parameters, original.parameters, desc);
917 expect(resynthesized.parameterKind, original.parameterKind, reason: desc);
918 expect(resynthesized.isInitializingFormal, original.isInitializingFormal,
919 reason: desc);
920 expect(resynthesized is FieldFormalParameterElementImpl,
921 original is FieldFormalParameterElementImpl);
922 if (resynthesized is FieldFormalParameterElementImpl &&
923 original is FieldFormalParameterElementImpl) {
924 if (original.field == null) {
925 expect(resynthesized.field, isNull, reason: '$desc field');
926 } else {
927 expect(resynthesized.field, isNotNull, reason: '$desc field');
928 compareFieldElements(
929 resynthesized.field, original.field, '$desc field');
930 }
931 }
932 expect(resynthesized.defaultValueCode, original.defaultValueCode,
933 reason: desc);
934 ParameterElementImpl resynthesizedActual =
935 getActualElement(resynthesized, desc);
936 ParameterElementImpl originalActual = getActualElement(original, desc);
937 compareFunctionElements(
938 resynthesizedActual.initializer, originalActual.initializer, desc);
939 }
940
941 void comparePrefixElements(PrefixElementImpl resynthesized,
942 PrefixElementImpl original, String desc) {
943 compareElements(resynthesized, original, desc);
944 }
945
946 void comparePropertyAccessorElements(
947 PropertyAccessorElementImpl resynthesized,
948 PropertyAccessorElementImpl original,
949 String desc) {
950 // TODO(paulberry): do I need to worry about
951 // MultiplyInheritedPropertyAccessorElementImpl?
952 compareExecutableElements(resynthesized, original, desc);
953 expect(resynthesized.variable, isNotNull);
954 expect(resynthesized.variable.location, original.variable.location);
955 }
956
957 void comparePropertyInducingElements(
958 PropertyInducingElementImpl resynthesized,
959 PropertyInducingElementImpl original,
960 String desc) {
961 compareVariableElements(resynthesized, original, desc);
962 if (checkPropagatedTypes) {
963 compareTypes(resynthesized.propagatedType, original.propagatedType, desc);
964 }
965 if (original.getter == null) {
966 expect(resynthesized.getter, isNull);
967 } else {
968 expect(resynthesized.getter, isNotNull);
969 expect(resynthesized.getter.location, original.getter.location);
970 }
971 if (original.setter == null) {
972 expect(resynthesized.setter, isNull);
973 } else {
974 expect(resynthesized.setter, isNotNull);
975 expect(resynthesized.setter.location, original.setter.location);
976 }
977 }
978
979 void compareTopLevelVariableElements(
980 TopLevelVariableElementImpl resynthesized,
981 TopLevelVariableElementImpl original,
982 String desc) {
983 comparePropertyInducingElements(resynthesized, original, desc);
984 }
985
986 void compareTypeImpls(
987 TypeImpl resynthesized, TypeImpl original, String desc) {
988 expect(resynthesized.element.location, original.element.location,
989 reason: desc);
990 expect(resynthesized.name, original.name, reason: desc);
991 }
992
993 void compareTypeParameterElements(TypeParameterElementImpl resynthesized,
994 TypeParameterElementImpl original, String desc) {
995 compareElements(resynthesized, original, desc);
996 compareTypes(resynthesized.type, original.type, desc);
997 compareTypes(resynthesized.bound, original.bound, '$desc bound');
998 }
999
1000 void compareTypes(DartType resynthesized, DartType original, String desc) {
1001 if (original == null) {
1002 expect(resynthesized, isNull, reason: desc);
1003 } else if (resynthesized is InterfaceTypeImpl &&
1004 original is InterfaceTypeImpl) {
1005 compareTypeImpls(resynthesized, original, desc);
1006 expect(resynthesized.typeArguments.length, original.typeArguments.length);
1007 for (int i = 0; i < resynthesized.typeArguments.length; i++) {
1008 compareTypes(resynthesized.typeArguments[i], original.typeArguments[i],
1009 '$desc type argument ${original.typeArguments[i].name}');
1010 }
1011 } else if (resynthesized is TypeParameterTypeImpl &&
1012 original is TypeParameterTypeImpl) {
1013 compareTypeImpls(resynthesized, original, desc);
1014 } else if (resynthesized is DynamicTypeImpl &&
1015 original is DynamicTypeImpl) {
1016 expect(resynthesized, same(original));
1017 } else if (resynthesized is UndefinedTypeImpl &&
1018 original is UndefinedTypeImpl) {
1019 expect(resynthesized, same(original));
1020 } else if (resynthesized is FunctionTypeImpl &&
1021 original is FunctionTypeImpl) {
1022 compareTypeImpls(resynthesized, original, desc);
1023 expect(resynthesized.isInstantiated, original.isInstantiated,
1024 reason: desc);
1025 if (original.element.isSynthetic &&
1026 original.element is FunctionTypeAliasElementImpl &&
1027 resynthesized.element is FunctionTypeAliasElementImpl) {
1028 compareFunctionTypeAliasElements(
1029 resynthesized.element, original.element, desc);
1030 }
1031 if (original.element.enclosingElement == null &&
1032 original.element is FunctionElement) {
1033 expect(resynthesized.element, new isInstanceOf<FunctionElement>());
1034 expect(resynthesized.element.enclosingElement, isNull, reason: desc);
1035 compareFunctionElements(
1036 resynthesized.element, original.element, '$desc element',
1037 shallow: true);
1038 expect(resynthesized.element.type, same(resynthesized));
1039 }
1040 expect(resynthesized.typeArguments.length, original.typeArguments.length,
1041 reason: '$desc typeArguments.length');
1042 for (int i = 0; i < resynthesized.typeArguments.length; i++) {
1043 if (resynthesized.typeArguments[i].isDynamic &&
1044 original.typeArguments[i] is TypeParameterType) {
1045 // It's ok for type arguments to get converted to `dynamic` if they
1046 // are not used.
1047 expect(
1048 isTypeParameterUsed(
1049 original.typeArguments[i], original.element.type),
1050 isFalse);
1051 } else {
1052 compareTypes(
1053 resynthesized.typeArguments[i],
1054 original.typeArguments[i],
1055 '$desc type argument ${original.typeArguments[i].name}');
1056 }
1057 }
1058 if (original.typeParameters == null) {
1059 expect(resynthesized.typeParameters, isNull, reason: desc);
1060 } else {
1061 expect(resynthesized.typeParameters, isNotNull, reason: desc);
1062 expect(
1063 resynthesized.typeParameters.length, original.typeParameters.length,
1064 reason: desc);
1065 for (int i = 0; i < resynthesized.typeParameters.length; i++) {
1066 compareTypeParameterElements(resynthesized.typeParameters[i],
1067 original.typeParameters[i], '$desc type parameter $i');
1068 }
1069 }
1070 expect(resynthesized.typeFormals.length, original.typeFormals.length,
1071 reason: desc);
1072 for (int i = 0; i < resynthesized.typeFormals.length; i++) {
1073 compareTypeParameterElements(resynthesized.typeFormals[i],
1074 original.typeFormals[i], '$desc bound type parameter $i');
1075 }
1076 } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) {
1077 expect(resynthesized, same(original));
1078 } else if (resynthesized is DynamicTypeImpl &&
1079 original is UndefinedTypeImpl) {
1080 // TODO(scheglov) In the strong mode constant variable like
1081 // `var V = new Unresolved()` gets `UndefinedTypeImpl`, and it gets
1082 // `DynamicTypeImpl` in the spec mode.
1083 } else if (resynthesized is BottomTypeImpl && original is BottomTypeImpl) {
1084 expect(resynthesized, same(original));
1085 } else if (resynthesized.runtimeType != original.runtimeType) {
1086 fail('Type mismatch: expected ${original.runtimeType},'
1087 ' got ${resynthesized.runtimeType} ($desc)');
1088 } else {
1089 fail('Unimplemented comparison for ${original.runtimeType}');
1090 }
1091 }
1092
1093 void compareUriReferencedElements(UriReferencedElementImpl resynthesized,
1094 UriReferencedElementImpl original, String desc) {
1095 compareElements(resynthesized, original, desc);
1096 expect(resynthesized.uri, original.uri, reason: '$desc uri');
1097 expect(resynthesized.uriOffset, original.uriOffset,
1098 reason: '$desc uri uriOffset');
1099 expect(resynthesized.uriEnd, original.uriEnd, reason: '$desc uriEnd');
1100 }
1101
1102 void compareVariableElements(
1103 VariableElement resynthesized, VariableElement original, String desc) {
1104 compareElements(resynthesized, original, desc);
1105 compareTypes(resynthesized.type, original.type, desc);
1106 VariableElementImpl resynthesizedActual =
1107 getActualElement(resynthesized, desc);
1108 VariableElementImpl originalActual = getActualElement(original, desc);
1109 compareFunctionElements(resynthesizedActual.initializer,
1110 originalActual.initializer, '$desc initializer');
1111 if (originalActual is ConstVariableElement) {
1112 Element oEnclosing = original.enclosingElement;
1113 if (oEnclosing is ClassElement && oEnclosing.isEnum) {
1114 compareConstValues(
1115 resynthesized.constantValue, original.constantValue, desc);
1116 } else {
1117 Expression initializer = resynthesizedActual.constantInitializer;
1118 if (variablesWithNotConstInitializers.contains(resynthesized.name)) {
1119 _assertUnresolvedIdentifier(initializer, desc);
1120 } else {
1121 compareConstAsts(initializer, originalActual.constantInitializer,
1122 '$desc initializer');
1123 }
1124 }
1125 }
1126 checkPossibleMember(resynthesized, original, desc);
1127 checkPossibleLocalElements(resynthesized, original);
1128 }
1129
1130 DartSdk createDartSdk() => AbstractContextTest.SHARED_MOCK_SDK;
1131
1132 /**
1133 * Determine the analysis options that should be used for this test.
1134 */
1135 AnalysisOptionsImpl createOptions() =>
1136 new AnalysisOptionsImpl()..enableGenericMethods = true;
1137
1138 /**
1139 * Serialize the given [library] into a summary. Then create a
1140 * [TestSummaryResynthesizer] which can deserialize it, along with any
1141 * references it makes to `dart:core`.
1142 *
1143 * Errors will lead to a test failure unless [allowErrors] is `true`.
1144 */
1145 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library,
1146 {bool allowErrors: false, bool dumpSummaries: false}) {
1147 if (!allowErrors) {
1148 assertNoErrors(library.source);
1149 }
1150 addLibrary('dart:core');
1151 addLibrary('dart:async');
1152 addLibrary('dart:math');
1153 return encodeLibraryElement(library, dumpSummaries: dumpSummaries);
1154 }
1155
1156 /**
1157 * Convert the library element [library] into a summary, and then create a
1158 * [TestSummaryResynthesizer] which can deserialize it.
1159 *
1160 * Caller is responsible for checking the library for errors, and adding any
1161 * dependent libraries using [addLibrary].
1162 */
1163 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library,
1164 {bool dumpSummaries: false}) {
1165 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
1166 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) {
1167 LibrarySerializationResult serialized = serializeLibrary(
1168 lib, context.typeProvider, context.analysisOptions.strongMode);
1169 for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
1170 unlinkedSummaries[serialized.unitUris[i]] =
1171 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
1172 }
1173 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
1174 }
1175
1176 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
1177 library.source.uri.toString(): getLinkedSummaryFor(library)
1178 };
1179 for (Source source in otherLibrarySources) {
1180 LibraryElement original = context.computeLibraryElement(source);
1181 String uri = source.uri.toString();
1182 linkedSummaries[uri] = getLinkedSummaryFor(original);
1183 }
1184 if (dumpSummaries) {
1185 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) {
1186 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}');
1187 });
1188 linkedSummaries.forEach((String path, LinkedLibrary lib) {
1189 print('Linked $path: ${JSON.encode(canonicalize(lib))}');
1190 });
1191 }
1192 return new TestSummaryResynthesizer(
1193 null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles);
1194 }
1195
1196 ElementImpl getActualElement(Element element, String desc) {
1197 if (element == null) {
1198 return null;
1199 } else if (element is ElementImpl) {
1200 return element;
1201 } else if (element is ElementHandle) {
1202 Element actualElement = element.actualElement;
1203 // A handle should never point to a member, because if it did, then
1204 // "is Member" checks on the handle would produce the wrong result.
1205 expect(actualElement, isNot(new isInstanceOf<Member>()), reason: desc);
1206 return getActualElement(actualElement, desc);
1207 } else if (element is Member) {
1208 return getActualElement(element.baseElement, desc);
1209 } else {
1210 fail('Unexpected type for resynthesized ($desc):'
1211 ' ${element.runtimeType}');
1212 return null;
1213 }
1214 }
1215
1216 /**
1217 * Determine if [type] makes use of the given [typeParameter].
1218 */
1219 bool isTypeParameterUsed(TypeParameterType typeParameter, DartType type) {
1220 if (type is FunctionType) {
1221 return isTypeParameterUsed(typeParameter, type.returnType) ||
1222 type.parameters.any((ParameterElement e) =>
1223 isTypeParameterUsed(typeParameter, e.type));
1224 } else if (type is InterfaceType) {
1225 return type.typeArguments
1226 .any((DartType t) => isTypeParameterUsed(typeParameter, t));
1227 } else if (type is TypeParameterType) {
1228 return type == typeParameter;
1229 } else {
1230 expect(type.isDynamic || type.isVoid, isTrue);
1231 return false;
1232 }
1233 }
1234
1235 @override
1236 void setUp() {
1237 super.setUp();
1238 prepareAnalysisContext(createOptions());
1239 }
1240
1241 void _assertUnresolvedIdentifier(Expression initializer, String desc) {
1242 expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc);
1243 SimpleIdentifier identifier = initializer;
1244 expect(identifier.staticElement, isNull, reason: desc);
1245 }
1246
1247 List<PropertyAccessorElement> _getSortedPropertyAccessors(
1248 ClassElement classElement) {
1249 List<PropertyAccessorElement> accessors = classElement.accessors.toList();
1250 accessors.sort((a, b) => a.displayName.compareTo(b.displayName));
1251 return accessors;
1252 }
1253
1254 bool _hasModifier(Element element, Modifier modifier) {
1255 if (modifier == Modifier.ABSTRACT) {
1256 if (element is ClassElement) {
1257 return element.isAbstract;
1258 }
1259 if (element is ExecutableElement) {
1260 return element.isAbstract;
1261 }
1262 return false;
1263 } else if (modifier == Modifier.ASYNCHRONOUS) {
1264 if (element is ExecutableElement) {
1265 return element.isAsynchronous;
1266 }
1267 return false;
1268 } else if (modifier == Modifier.CONST) {
1269 if (element is VariableElement) {
1270 return element.isConst;
1271 }
1272 return false;
1273 } else if (modifier == Modifier.DEFERRED) {
1274 if (element is ImportElement) {
1275 return element.isDeferred;
1276 }
1277 return false;
1278 } else if (modifier == Modifier.ENUM) {
1279 if (element is ClassElement) {
1280 return element.isEnum;
1281 }
1282 return false;
1283 } else if (modifier == Modifier.EXTERNAL) {
1284 if (element is ExecutableElement) {
1285 return element.isExternal;
1286 }
1287 return false;
1288 } else if (modifier == Modifier.FACTORY) {
1289 if (element is ConstructorElement) {
1290 return element.isFactory;
1291 }
1292 return false;
1293 } else if (modifier == Modifier.FINAL) {
1294 if (element is VariableElement) {
1295 return element.isFinal;
1296 }
1297 return false;
1298 } else if (modifier == Modifier.GENERATOR) {
1299 if (element is ExecutableElement) {
1300 return element.isGenerator;
1301 }
1302 return false;
1303 } else if (modifier == Modifier.GETTER) {
1304 if (element is PropertyAccessorElement) {
1305 return element.isGetter;
1306 }
1307 return false;
1308 } else if (modifier == Modifier.HAS_EXT_URI) {
1309 if (element is LibraryElement) {
1310 return element.hasExtUri;
1311 }
1312 return false;
1313 } else if (modifier == Modifier.IMPLICIT_TYPE) {
1314 if (element is ExecutableElement) {
1315 return element.hasImplicitReturnType;
1316 }
1317 return false;
1318 } else if (modifier == Modifier.MIXIN_APPLICATION) {
1319 if (element is ClassElement) {
1320 return element.isMixinApplication;
1321 }
1322 return false;
1323 } else if (modifier == Modifier.REFERENCES_SUPER) {
1324 if (element is ClassElement) {
1325 return element.hasReferenceToSuper;
1326 }
1327 return false;
1328 } else if (modifier == Modifier.SETTER) {
1329 if (element is PropertyAccessorElement) {
1330 return element.isSetter;
1331 }
1332 return false;
1333 } else if (modifier == Modifier.STATIC) {
1334 if (element is ExecutableElement) {
1335 return element.isStatic;
1336 }
1337 return false;
1338 } else if (modifier == Modifier.SYNTHETIC) {
1339 return element.isSynthetic;
1340 }
1341 throw new UnimplementedError(
1342 'Modifier $modifier for ${element?.runtimeType}');
1343 }
1344 }
1345
1346 @reflectiveTest
1347 class ResynthesizeElementTest extends ResynthesizeTest {
1348 @override
1349 LibraryElementImpl checkLibrary(String text,
1350 {bool allowErrors: false, bool dumpSummaries: false}) {
1351 Source source = addTestSource(text);
1352 LibraryElementImpl original = context.computeLibraryElement(source);
1353 LibraryElementImpl resynthesized = resynthesizeLibraryElement(
1354 encodeLibrary(original,
1355 allowErrors: allowErrors, dumpSummaries: dumpSummaries),
1356 source.uri.toString(),
1357 original);
1358 checkLibraryElements(original, resynthesized);
1359 return resynthesized;
1360 }
1361
1362 @override
1363 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource) {
1364 LibraryElement libraryElement =
1365 context.computeLibraryElement(librarySource);
1366 return encodeLibrary(libraryElement);
1367 }
1368
1369 /**
1370 * Serialize the given [library] into a summary. Then create a
1371 * [TestSummaryResynthesizer] which can deserialize it, along with any
1372 * references it makes to `dart:core`.
1373 *
1374 * Errors will lead to a test failure unless [allowErrors] is `true`.
1375 */
1376 TestSummaryResynthesizer encodeLibrary(LibraryElementImpl library,
1377 {bool allowErrors: false, bool dumpSummaries: false}) {
1378 if (!allowErrors) {
1379 assertNoErrors(library.source);
1380 }
1381 addLibrary('dart:core');
1382 addLibrary('dart:async');
1383 addLibrary('dart:math');
1384 return encodeLibraryElement(library, dumpSummaries: dumpSummaries);
1385 }
1386
1387 /**
1388 * Convert the library element [library] into a summary, and then create a
1389 * [TestSummaryResynthesizer] which can deserialize it.
1390 *
1391 * Caller is responsible for checking the library for errors, and adding any
1392 * dependent libraries using [addLibrary].
1393 */
1394 TestSummaryResynthesizer encodeLibraryElement(LibraryElementImpl library,
1395 {bool dumpSummaries: false}) {
1396 Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
1397 LinkedLibrary getLinkedSummaryFor(LibraryElement lib) {
1398 LibrarySerializationResult serialized = serializeLibrary(
1399 lib, context.typeProvider, context.analysisOptions.strongMode);
1400 for (int i = 0; i < serialized.unlinkedUnits.length; i++) {
1401 unlinkedSummaries[serialized.unitUris[i]] =
1402 new UnlinkedUnit.fromBuffer(serialized.unlinkedUnits[i].toBuffer());
1403 }
1404 return new LinkedLibrary.fromBuffer(serialized.linked.toBuffer());
1405 }
1406
1407 Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{
1408 library.source.uri.toString(): getLinkedSummaryFor(library)
1409 };
1410 for (Source source in otherLibrarySources) {
1411 LibraryElement original = context.computeLibraryElement(source);
1412 String uri = source.uri.toString();
1413 linkedSummaries[uri] = getLinkedSummaryFor(original);
1414 }
1415 if (dumpSummaries) {
1416 unlinkedSummaries.forEach((String path, UnlinkedUnit unit) {
1417 print('Unlinked $path: ${JSON.encode(canonicalize(unit))}');
1418 });
1419 linkedSummaries.forEach((String path, LinkedLibrary lib) {
1420 print('Linked $path: ${JSON.encode(canonicalize(lib))}');
1421 });
1422 }
1423 return new TestSummaryResynthesizer(
1424 null, context, unlinkedSummaries, linkedSummaries, allowMissingFiles);
1425 }
1426
1427 /**
1428 * Resynthesize the library element associated with [uri] using
1429 * [resynthesizer], and verify that it only had to consult one summary in
1430 * order to do so. [original] is consulted merely to verify that no
1431 * unnecessary resynthesis work was performed.
1432 */
1433 LibraryElementImpl resynthesizeLibraryElement(
1434 TestSummaryResynthesizer resynthesizer,
1435 String uri,
1436 LibraryElement original) {
1437 LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
1438 checkMinimalResynthesisWork(resynthesizer, original);
1439 return resynthesized;
1440 }
1441
1442 test_core() {
1443 addLibrary('dart:async');
1444 addLibrary('dart:math');
1445 String uri = 'dart:core';
1446 LibraryElementImpl original =
1447 context.computeLibraryElement(context.sourceFactory.forUri(uri));
1448 LibraryElementImpl resynthesized = resynthesizeLibraryElement(
1449 encodeLibraryElement(original), uri, original);
1450 checkLibraryElements(original, resynthesized);
1451 }
1452 }
1453
1454 @reflectiveTest
1455 abstract class ResynthesizeTest extends AbstractResynthesizeTest {
1456 LibraryElementImpl checkLibrary(String text,
1457 {bool allowErrors: false, bool dumpSummaries: false});
1458
1459 /**
1460 * Return a [SummaryResynthesizer] to resynthesize the library with the
1461 * given [librarySource].
1462 */
1463 SummaryResynthesizer encodeDecodeLibrarySource(Source librarySource);
1464
1465 fail_library_hasExtUri() {
1466 checkLibrary('import "dart-ext:doesNotExist.dart";');
1467 }
1468
1469 test_class_abstract() {
1470 checkLibrary('abstract class C {}');
1471 }
1472
1473 test_class_alias() {
1474 checkLibrary('class C = D with E, F; class D {} class E {} class F {}');
1475 }
1476
1477 test_class_alias_abstract() {
1478 checkLibrary('abstract class C = D with E; class D {} class E {}');
1479 }
1480
1481 test_class_alias_documented() {
1482 checkLibrary('''
1483 // Extra comment so doc comment offset != 0
1484 /**
1485 * Docs
1486 */
1487 class C = D with E;
1488
1489 class D {}
1490 class E {}''');
1491 }
1492
1493 test_class_alias_with_forwarding_constructors() {
1494 addLibrarySource(
1495 '/a.dart',
1496 '''
1497 class Base {
1498 Base._priv();
1499 Base();
1500 Base.noArgs();
1501 Base.requiredArg(x);
1502 Base.positionalArg([x]);
1503 Base.namedArg({x});
1504 factory Base.fact() => null;
1505 factory Base.fact2() = Base.noArgs;
1506 }
1507 ''');
1508 checkLibrary('''
1509 import "a.dart";
1510 class M {}
1511 class MixinApp = Base with M;
1512 ''');
1513 }
1514
1515 test_class_alias_with_forwarding_constructors_type_substitution() {
1516 checkLibrary('''
1517 class Base<T> {
1518 Base.ctor(T t, List<T> l);
1519 }
1520 class M {}
1521 class MixinApp = Base with M;
1522 ''');
1523 }
1524
1525 test_class_alias_with_forwarding_constructors_type_substitution_complex() {
1526 checkLibrary('''
1527 class Base<T> {
1528 Base.ctor(T t, List<T> l);
1529 }
1530 class M {}
1531 class MixinApp<U> = Base<List<U>> with M;
1532 ''');
1533 }
1534
1535 test_class_alias_with_mixin_members() {
1536 checkLibrary('''
1537 class C = D with E;
1538 class D {}
1539 class E {
1540 int get a => null;
1541 void set b(int i) {}
1542 void f() {}
1543 int x;
1544 }''');
1545 }
1546
1547 test_class_constructor_const() {
1548 checkLibrary('class C { const C(); }');
1549 }
1550
1551 test_class_constructor_const_external() {
1552 checkLibrary('class C { external const C(); }');
1553 }
1554
1555 test_class_constructor_explicit_named() {
1556 checkLibrary('class C { C.foo(); }');
1557 }
1558
1559 test_class_constructor_explicit_type_params() {
1560 checkLibrary('class C<T, U> { C(); }');
1561 }
1562
1563 test_class_constructor_explicit_unnamed() {
1564 checkLibrary('class C { C(); }');
1565 }
1566
1567 test_class_constructor_external() {
1568 checkLibrary('class C { external C(); }');
1569 }
1570
1571 test_class_constructor_factory() {
1572 checkLibrary('class C { factory C() => null; }');
1573 }
1574
1575 test_class_constructor_field_formal_dynamic_dynamic() {
1576 checkLibrary('class C { dynamic x; C(dynamic this.x); }');
1577 }
1578
1579 test_class_constructor_field_formal_dynamic_typed() {
1580 checkLibrary('class C { dynamic x; C(int this.x); }');
1581 }
1582
1583 test_class_constructor_field_formal_dynamic_untyped() {
1584 checkLibrary('class C { dynamic x; C(this.x); }');
1585 }
1586
1587 test_class_constructor_field_formal_multiple_matching_fields() {
1588 // This is a compile-time error but it should still analyze consistently.
1589 checkLibrary('class C { C(this.x); int x; String x; }', allowErrors: true);
1590 }
1591
1592 test_class_constructor_field_formal_no_matching_field() {
1593 // This is a compile-time error but it should still analyze consistently.
1594 checkLibrary('class C { C(this.x); }', allowErrors: true);
1595 }
1596
1597 test_class_constructor_field_formal_typed_dynamic() {
1598 checkLibrary('class C { num x; C(dynamic this.x); }', allowErrors: true);
1599 }
1600
1601 test_class_constructor_field_formal_typed_typed() {
1602 checkLibrary('class C { num x; C(int this.x); }');
1603 }
1604
1605 test_class_constructor_field_formal_typed_untyped() {
1606 checkLibrary('class C { num x; C(this.x); }');
1607 }
1608
1609 test_class_constructor_field_formal_untyped_dynamic() {
1610 checkLibrary('class C { var x; C(dynamic this.x); }');
1611 }
1612
1613 test_class_constructor_field_formal_untyped_typed() {
1614 checkLibrary('class C { var x; C(int this.x); }');
1615 }
1616
1617 test_class_constructor_field_formal_untyped_untyped() {
1618 checkLibrary('class C { var x; C(this.x); }');
1619 }
1620
1621 test_class_constructor_fieldFormal_named_noDefault() {
1622 checkLibrary('class C { int x; C({this.x}); }');
1623 }
1624
1625 test_class_constructor_fieldFormal_named_withDefault() {
1626 checkLibrary('class C { int x; C({this.x: 42}); }');
1627 }
1628
1629 test_class_constructor_fieldFormal_optional_noDefault() {
1630 checkLibrary('class C { int x; C([this.x]); }');
1631 }
1632
1633 test_class_constructor_fieldFormal_optional_withDefault() {
1634 checkLibrary('class C { int x; C([this.x = 42]); }');
1635 }
1636
1637 test_class_constructor_implicit() {
1638 checkLibrary('class C {}');
1639 }
1640
1641 test_class_constructor_implicit_type_params() {
1642 checkLibrary('class C<T, U> {}');
1643 }
1644
1645 test_class_constructor_params() {
1646 checkLibrary('class C { C(x, y); }');
1647 }
1648
1649 test_class_constructors() {
1650 checkLibrary('class C { C.foo(); C.bar(); }');
1651 }
1652
1653 test_class_documented() {
1654 checkLibrary('''
1655 // Extra comment so doc comment offset != 0
1656 /**
1657 * Docs
1658 */
1659 class C {}''');
1660 }
1661
1662 test_class_documented_with_references() {
1663 checkLibrary('''
1664 /**
1665 * Docs referring to [D] and [E]
1666 */
1667 class C {}
1668
1669 class D {}
1670 class E {}''');
1671 }
1672
1673 test_class_documented_with_windows_line_endings() {
1674 checkLibrary('/**\r\n * Docs\r\n */\r\nclass C {}');
1675 }
1676
1677 test_class_field_const() {
1678 checkLibrary('class C { static const int i = 0; }');
1679 }
1680
1681 test_class_field_implicit_type() {
1682 checkLibrary('class C { var x; }');
1683 }
1684
1685 test_class_field_static() {
1686 checkLibrary('class C { static int i; }');
1687 }
1688
1689 test_class_fields() {
1690 checkLibrary('class C { int i; int j; }');
1691 }
1692
1693 test_class_getter_abstract() {
1694 checkLibrary('abstract class C { int get x; }');
1695 }
1696
1697 test_class_getter_external() {
1698 checkLibrary('class C { external int get x; }');
1699 }
1700
1701 test_class_getter_implicit_return_type() {
1702 checkLibrary('class C { get x => null; }');
1703 }
1704
1705 test_class_getter_static() {
1706 checkLibrary('class C { static int get x => null; }');
1707 }
1708
1709 test_class_getters() {
1710 checkLibrary('class C { int get x => null; get y => null; }');
1711 }
1712
1713 test_class_implicitField_getterFirst() {
1714 checkLibrary('class C { int get x => 0; void set x(int value) {} }');
1715 }
1716
1717 test_class_implicitField_setterFirst() {
1718 checkLibrary('class C { void set x(int value) {} int get x => 0; }');
1719 }
1720
1721 test_class_interfaces() {
1722 checkLibrary('class C implements D, E {} class D {} class E {}');
1723 }
1724
1725 test_class_interfaces_unresolved() {
1726 checkLibrary('class C implements X, Y, Z {} class X {} class Z {}',
1727 allowErrors: true);
1728 }
1729
1730 test_class_method_abstract() {
1731 checkLibrary('abstract class C { f(); }');
1732 }
1733
1734 test_class_method_external() {
1735 checkLibrary('class C { external f(); }');
1736 }
1737
1738 test_class_method_params() {
1739 checkLibrary('class C { f(x, y) {} }');
1740 }
1741
1742 test_class_method_static() {
1743 checkLibrary('class C { static f() {} }');
1744 }
1745
1746 test_class_methods() {
1747 checkLibrary('class C { f() {} g() {} }');
1748 }
1749
1750 test_class_mixins() {
1751 checkLibrary('class C extends Object with D, E {} class D {} class E {}');
1752 }
1753
1754 test_class_mixins_unresolved() {
1755 checkLibrary('class C extends Object with X, Y, Z; class X {} class Z {}',
1756 allowErrors: true);
1757 }
1758
1759 test_class_setter_abstract() {
1760 checkLibrary('abstract class C { void set x(int value); }');
1761 }
1762
1763 test_class_setter_external() {
1764 checkLibrary('class C { external void set x(int value); }');
1765 }
1766
1767 test_class_setter_implicit_param_type() {
1768 checkLibrary('class C { void set x(value) {} }');
1769 }
1770
1771 test_class_setter_implicit_return_type() {
1772 checkLibrary('class C { set x(int value) {} }');
1773 }
1774
1775 test_class_setter_static() {
1776 checkLibrary('class C { static void set x(int value) {} }');
1777 }
1778
1779 test_class_setters() {
1780 checkLibrary('class C { void set x(int value) {} set y(value) {} }');
1781 }
1782
1783 test_class_supertype() {
1784 checkLibrary('class C extends D {} class D {}');
1785 }
1786
1787 test_class_supertype_unresolved() {
1788 checkLibrary('class C extends D {}', allowErrors: true);
1789 }
1790
1791 test_class_type_parameters() {
1792 checkLibrary('class C<T, U> {}');
1793 }
1794
1795 test_class_type_parameters_bound() {
1796 checkLibrary('class C<T extends Object, U extends D> {} class D {}');
1797 }
1798
1799 test_class_type_parameters_f_bound_complex() {
1800 checkLibrary('class C<T extends List<U>, U> {}');
1801 }
1802
1803 test_class_type_parameters_f_bound_simple() {
1804 checkLibrary('class C<T extends U, U> {}');
1805 }
1806
1807 test_classes() {
1808 checkLibrary('class C {} class D {}');
1809 }
1810
1811 test_closure_executable_with_return_type_from_closure() {
1812 checkLibrary('''
1813 f() {
1814 print(() {});
1815 print(() => () => 0);
1816 }
1817 ''');
1818 }
1819
1820 test_const_invalid_field_const() {
1821 variablesWithNotConstInitializers.add('f');
1822 checkLibrary(
1823 r'''
1824 class C {
1825 static const f = 1 + foo();
1826 }
1827 int foo() => 42;
1828 ''',
1829 allowErrors: true);
1830 }
1831
1832 test_const_invalid_field_final() {
1833 variablesWithNotConstInitializers.add('f');
1834 checkLibrary(
1835 r'''
1836 class C {
1837 final f = 1 + foo();
1838 }
1839 int foo() => 42;
1840 ''',
1841 allowErrors: true);
1842 }
1843
1844 test_const_invalid_topLevel() {
1845 variablesWithNotConstInitializers.add('v');
1846 checkLibrary(
1847 r'''
1848 const v = 1 + foo();
1849 int foo() => 42;
1850 ''',
1851 allowErrors: true);
1852 }
1853
1854 test_const_invokeConstructor_generic_named() {
1855 checkLibrary(r'''
1856 class C<K, V> {
1857 const C.named(K k, V v);
1858 }
1859 const V = const C<int, String>.named(1, '222');
1860 ''');
1861 }
1862
1863 test_const_invokeConstructor_generic_named_imported() {
1864 addLibrarySource(
1865 '/a.dart',
1866 r'''
1867 class C<K, V> {
1868 const C.named(K k, V v);
1869 }
1870 ''');
1871 checkLibrary(r'''
1872 import 'a.dart';
1873 const V = const C<int, String>.named(1, '222');
1874 ''');
1875 }
1876
1877 test_const_invokeConstructor_generic_named_imported_withPrefix() {
1878 addLibrarySource(
1879 '/a.dart',
1880 r'''
1881 class C<K, V> {
1882 const C.named(K k, V v);
1883 }
1884 ''');
1885 checkLibrary(r'''
1886 import 'a.dart' as p;
1887 const V = const p.C<int, String>.named(1, '222');
1888 ''');
1889 }
1890
1891 test_const_invokeConstructor_generic_noTypeArguments() {
1892 checkLibrary(r'''
1893 class C<K, V> {
1894 const C();
1895 }
1896 const V = const C();
1897 ''');
1898 }
1899
1900 test_const_invokeConstructor_generic_unnamed() {
1901 checkLibrary(r'''
1902 class C<K, V> {
1903 const C();
1904 }
1905 const V = const C<int, String>();
1906 ''');
1907 }
1908
1909 test_const_invokeConstructor_generic_unnamed_imported() {
1910 addLibrarySource(
1911 '/a.dart',
1912 r'''
1913 class C<K, V> {
1914 const C();
1915 }
1916 ''');
1917 checkLibrary(r'''
1918 import 'a.dart';
1919 const V = const C<int, String>();
1920 ''');
1921 }
1922
1923 test_const_invokeConstructor_generic_unnamed_imported_withPrefix() {
1924 addLibrarySource(
1925 '/a.dart',
1926 r'''
1927 class C<K, V> {
1928 const C();
1929 }
1930 ''');
1931 checkLibrary(r'''
1932 import 'a.dart' as p;
1933 const V = const p.C<int, String>();
1934 ''');
1935 }
1936
1937 test_const_invokeConstructor_named() {
1938 checkLibrary(r'''
1939 class C {
1940 const C.named(bool a, int b, int c, {String d, double e});
1941 }
1942 const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
1943 ''');
1944 }
1945
1946 test_const_invokeConstructor_named_imported() {
1947 addLibrarySource(
1948 '/a.dart',
1949 r'''
1950 class C {
1951 const C.named();
1952 }
1953 ''');
1954 checkLibrary(r'''
1955 import 'a.dart';
1956 const V = const C.named();
1957 ''');
1958 }
1959
1960 test_const_invokeConstructor_named_imported_withPrefix() {
1961 addLibrarySource(
1962 '/a.dart',
1963 r'''
1964 class C {
1965 const C.named();
1966 }
1967 ''');
1968 checkLibrary(r'''
1969 import 'a.dart' as p;
1970 const V = const p.C.named();
1971 ''');
1972 }
1973
1974 test_const_invokeConstructor_named_unresolved() {
1975 checkLibrary(
1976 r'''
1977 class C {}
1978 const V = const C.named();
1979 ''',
1980 allowErrors: true);
1981 }
1982
1983 test_const_invokeConstructor_named_unresolved2() {
1984 checkLibrary(
1985 r'''
1986 const V = const C.named();
1987 ''',
1988 allowErrors: true);
1989 }
1990
1991 test_const_invokeConstructor_named_unresolved3() {
1992 addLibrarySource(
1993 '/a.dart',
1994 r'''
1995 class C {
1996 }
1997 ''');
1998 checkLibrary(
1999 r'''
2000 import 'a.dart' as p;
2001 const V = const p.C.named();
2002 ''',
2003 allowErrors: true);
2004 }
2005
2006 test_const_invokeConstructor_named_unresolved4() {
2007 addLibrarySource('/a.dart', '');
2008 checkLibrary(
2009 r'''
2010 import 'a.dart' as p;
2011 const V = const p.C.named();
2012 ''',
2013 allowErrors: true);
2014 }
2015
2016 test_const_invokeConstructor_named_unresolved5() {
2017 checkLibrary(
2018 r'''
2019 const V = const p.C.named();
2020 ''',
2021 allowErrors: true);
2022 }
2023
2024 test_const_invokeConstructor_unnamed() {
2025 checkLibrary(r'''
2026 class C {
2027 const C();
2028 }
2029 const V = const C();
2030 ''');
2031 }
2032
2033 test_const_invokeConstructor_unnamed_imported() {
2034 addLibrarySource(
2035 '/a.dart',
2036 r'''
2037 class C {
2038 const C();
2039 }
2040 ''');
2041 checkLibrary(r'''
2042 import 'a.dart';
2043 const V = const C();
2044 ''');
2045 }
2046
2047 test_const_invokeConstructor_unnamed_imported_withPrefix() {
2048 addLibrarySource(
2049 '/a.dart',
2050 r'''
2051 class C {
2052 const C();
2053 }
2054 ''');
2055 checkLibrary(r'''
2056 import 'a.dart' as p;
2057 const V = const p.C();
2058 ''');
2059 }
2060
2061 test_const_invokeConstructor_unnamed_unresolved() {
2062 checkLibrary(
2063 r'''
2064 const V = const C();
2065 ''',
2066 allowErrors: true);
2067 }
2068
2069 test_const_invokeConstructor_unnamed_unresolved2() {
2070 addLibrarySource('/a.dart', '');
2071 checkLibrary(
2072 r'''
2073 import 'a.dart' as p;
2074 const V = const p.C();
2075 ''',
2076 allowErrors: true);
2077 }
2078
2079 test_const_invokeConstructor_unnamed_unresolved3() {
2080 checkLibrary(
2081 r'''
2082 const V = const p.C();
2083 ''',
2084 allowErrors: true);
2085 }
2086
2087 test_const_length_ofClassConstField() {
2088 checkLibrary(r'''
2089 class C {
2090 static const String F = '';
2091 }
2092 const int v = C.F.length;
2093 ''');
2094 }
2095
2096 test_const_length_ofClassConstField_imported() {
2097 addLibrarySource(
2098 '/a.dart',
2099 r'''
2100 class C {
2101 static const String F = '';
2102 }
2103 ''');
2104 checkLibrary(r'''
2105 import 'a.dart';
2106 const int v = C.F.length;
2107 ''');
2108 }
2109
2110 test_const_length_ofClassConstField_imported_withPrefix() {
2111 addLibrarySource(
2112 '/a.dart',
2113 r'''
2114 class C {
2115 static const String F = '';
2116 }
2117 ''');
2118 checkLibrary(r'''
2119 import 'a.dart' as p;
2120 const int v = p.C.F.length;
2121 ''');
2122 }
2123
2124 test_const_length_ofStringLiteral() {
2125 checkLibrary(r'''
2126 const v = 'abc'.length;
2127 ''');
2128 }
2129
2130 test_const_length_ofTopLevelVariable() {
2131 checkLibrary(r'''
2132 const String S = 'abc';
2133 const v = S.length;
2134 ''');
2135 }
2136
2137 test_const_length_ofTopLevelVariable_imported() {
2138 addLibrarySource(
2139 '/a.dart',
2140 r'''
2141 const String S = 'abc';
2142 ''');
2143 checkLibrary(r'''
2144 import 'a.dart';
2145 const v = S.length;
2146 ''');
2147 }
2148
2149 test_const_length_ofTopLevelVariable_imported_withPrefix() {
2150 addLibrarySource(
2151 '/a.dart',
2152 r'''
2153 const String S = 'abc';
2154 ''');
2155 checkLibrary(r'''
2156 import 'a.dart' as p;
2157 const v = p.S.length;
2158 ''');
2159 }
2160
2161 test_const_length_staticMethod() {
2162 checkLibrary(r'''
2163 class C {
2164 static int length() => 42;
2165 }
2166 const v = C.length;
2167 ''');
2168 }
2169
2170 test_const_parameterDefaultValue_initializingFormal_functionTyped() {
2171 checkLibrary(r'''
2172 class C {
2173 final x;
2174 const C({this.x: foo});
2175 }
2176 int foo() => 42;
2177 ''');
2178 }
2179
2180 test_const_parameterDefaultValue_initializingFormal_named() {
2181 checkLibrary(r'''
2182 class C {
2183 final x;
2184 const C({this.x: 1 + 2});
2185 }
2186 ''');
2187 }
2188
2189 test_const_parameterDefaultValue_initializingFormal_positional() {
2190 checkLibrary(r'''
2191 class C {
2192 final x;
2193 const C([this.x = 1 + 2]);
2194 }
2195 ''');
2196 }
2197
2198 test_const_parameterDefaultValue_normal() {
2199 checkLibrary(r'''
2200 class C {
2201 const C.positional([p = 1 + 2]);
2202 const C.named({p: 1 + 2});
2203 void methodPositional([p = 1 + 2]) {}
2204 void methodPositionalWithoutDefault([p]) {}
2205 void methodNamed({p: 1 + 2}) {}
2206 void methodNamedWithoutDefault({p}) {}
2207 }
2208 ''');
2209 }
2210
2211 test_const_reference_staticField() {
2212 checkLibrary(r'''
2213 class C {
2214 static const int F = 42;
2215 }
2216 const V = C.F;
2217 ''');
2218 }
2219
2220 test_const_reference_staticField_imported() {
2221 addLibrarySource(
2222 '/a.dart',
2223 r'''
2224 class C {
2225 static const int F = 42;
2226 }
2227 ''');
2228 checkLibrary(r'''
2229 import 'a.dart';
2230 const V = C.F;
2231 ''');
2232 }
2233
2234 test_const_reference_staticField_imported_withPrefix() {
2235 addLibrarySource(
2236 '/a.dart',
2237 r'''
2238 class C {
2239 static const int F = 42;
2240 }
2241 ''');
2242 checkLibrary(r'''
2243 import 'a.dart' as p;
2244 const V = p.C.F;
2245 ''');
2246 }
2247
2248 test_const_reference_staticMethod() {
2249 checkLibrary(r'''
2250 class C {
2251 static int m(int a, String b) => 42;
2252 }
2253 const V = C.m;
2254 ''');
2255 }
2256
2257 test_const_reference_staticMethod_imported() {
2258 addLibrarySource(
2259 '/a.dart',
2260 r'''
2261 class C {
2262 static int m(int a, String b) => 42;
2263 }
2264 ''');
2265 checkLibrary(r'''
2266 import 'a.dart';
2267 const V = C.m;
2268 ''');
2269 }
2270
2271 test_const_reference_staticMethod_imported_withPrefix() {
2272 addLibrarySource(
2273 '/a.dart',
2274 r'''
2275 class C {
2276 static int m(int a, String b) => 42;
2277 }
2278 ''');
2279 checkLibrary(r'''
2280 import 'a.dart' as p;
2281 const V = p.C.m;
2282 ''');
2283 }
2284
2285 test_const_reference_topLevelFunction() {
2286 checkLibrary(r'''
2287 foo() {}
2288 const V = foo;
2289 ''');
2290 }
2291
2292 test_const_reference_topLevelFunction_imported() {
2293 addLibrarySource(
2294 '/a.dart',
2295 r'''
2296 foo() {}
2297 ''');
2298 checkLibrary(r'''
2299 import 'a.dart';
2300 const V = foo;
2301 ''');
2302 }
2303
2304 test_const_reference_topLevelFunction_imported_withPrefix() {
2305 addLibrarySource(
2306 '/a.dart',
2307 r'''
2308 foo() {}
2309 ''');
2310 checkLibrary(r'''
2311 import 'a.dart' as p;
2312 const V = p.foo;
2313 ''');
2314 }
2315
2316 test_const_reference_topLevelVariable() {
2317 checkLibrary(r'''
2318 const A = 1;
2319 const B = A + 2;
2320 ''');
2321 }
2322
2323 test_const_reference_topLevelVariable_imported() {
2324 addLibrarySource(
2325 '/a.dart',
2326 r'''
2327 const A = 1;
2328 ''');
2329 checkLibrary(r'''
2330 import 'a.dart';
2331 const B = A + 2;
2332 ''');
2333 }
2334
2335 test_const_reference_topLevelVariable_imported_withPrefix() {
2336 addLibrarySource(
2337 '/a.dart',
2338 r'''
2339 const A = 1;
2340 ''');
2341 checkLibrary(r'''
2342 import 'a.dart' as p;
2343 const B = p.A + 2;
2344 ''');
2345 }
2346
2347 test_const_reference_type() {
2348 checkLibrary(r'''
2349 class C {}
2350 class D<T> {}
2351 enum E {a, b, c}
2352 typedef F(int a, String b);
2353 const vDynamic = dynamic;
2354 const vNull = Null;
2355 const vObject = Object;
2356 const vClass = C;
2357 const vGenericClass = D;
2358 const vEnum = E;
2359 const vFunctionTypeAlias = F;
2360 ''');
2361 }
2362
2363 test_const_reference_type_functionType() {
2364 checkLibrary(r'''
2365 typedef F();
2366 class C {
2367 final f = <F>[];
2368 }
2369 ''');
2370 }
2371
2372 test_const_reference_type_imported() {
2373 addLibrarySource(
2374 '/a.dart',
2375 r'''
2376 class C {}
2377 enum E {a, b, c}
2378 typedef F(int a, String b);
2379 ''');
2380 checkLibrary(r'''
2381 import 'a.dart';
2382 const vClass = C;
2383 const vEnum = E;
2384 const vFunctionTypeAlias = F;
2385 ''');
2386 }
2387
2388 test_const_reference_type_imported_withPrefix() {
2389 addLibrarySource(
2390 '/a.dart',
2391 r'''
2392 class C {}
2393 enum E {a, b, c}
2394 typedef F(int a, String b);
2395 ''');
2396 checkLibrary(r'''
2397 import 'a.dart' as p;
2398 const vClass = p.C;
2399 const vEnum = p.E;
2400 const vFunctionTypeAlias = p.F;
2401 ''');
2402 }
2403
2404 test_const_reference_type_typeParameter() {
2405 checkLibrary(r'''
2406 class C<T> {
2407 final f = <T>[];
2408 }
2409 ''');
2410 }
2411
2412 test_const_reference_unresolved_prefix0() {
2413 checkLibrary(
2414 r'''
2415 const V = foo;
2416 ''',
2417 allowErrors: true);
2418 }
2419
2420 test_const_reference_unresolved_prefix1() {
2421 checkLibrary(
2422 r'''
2423 class C {}
2424 const v = C.foo;
2425 ''',
2426 allowErrors: true);
2427 }
2428
2429 test_const_reference_unresolved_prefix2() {
2430 addLibrarySource(
2431 '/foo.dart',
2432 '''
2433 class C {}
2434 ''');
2435 checkLibrary(
2436 r'''
2437 import 'foo.dart' as p;
2438 const v = p.C.foo;
2439 ''',
2440 allowErrors: true);
2441 }
2442
2443 test_const_topLevel_binary() {
2444 checkLibrary(r'''
2445 const vEqual = 1 == 2;
2446 const vAnd = true && false;
2447 const vOr = false || true;
2448 const vBitXor = 1 ^ 2;
2449 const vBitAnd = 1 & 2;
2450 const vBitOr = 1 | 2;
2451 const vBitShiftLeft = 1 << 2;
2452 const vBitShiftRight = 1 >> 2;
2453 const vAdd = 1 + 2;
2454 const vSubtract = 1 - 2;
2455 const vMiltiply = 1 * 2;
2456 const vDivide = 1 / 2;
2457 const vFloorDivide = 1 ~/ 2;
2458 const vModulo = 1 % 2;
2459 const vGreater = 1 > 2;
2460 const vGreaterEqual = 1 >= 2;
2461 const vLess = 1 < 2;
2462 const vLessEqual = 1 <= 2;
2463 ''');
2464 }
2465
2466 test_const_topLevel_conditional() {
2467 checkLibrary(r'''
2468 const vConditional = (1 == 2) ? 11 : 22;
2469 ''');
2470 }
2471
2472 test_const_topLevel_identical() {
2473 checkLibrary(r'''
2474 const vIdentical = (1 == 2) ? 11 : 22;
2475 ''');
2476 }
2477
2478 test_const_topLevel_literal() {
2479 checkLibrary(r'''
2480 const vNull = null;
2481 const vBoolFalse = false;
2482 const vBoolTrue = true;
2483 const vInt = 1;
2484 const vIntLong = 0x9876543210987654321;
2485 const vDouble = 2.3;
2486 const vString = 'abc';
2487 const vStringConcat = 'aaa' 'bbb';
2488 const vStringInterpolation = 'aaa ${true} ${42} bbb';
2489 const vSymbol = #aaa.bbb.ccc;
2490 ''');
2491 }
2492
2493 test_const_topLevel_prefix() {
2494 checkLibrary(r'''
2495 const vNotEqual = 1 != 2;
2496 const vNot = !true;
2497 const vNegate = -1;
2498 const vComplement = ~1;
2499 ''');
2500 }
2501
2502 test_const_topLevel_typedList() {
2503 checkLibrary(r'''
2504 const vNull = const <Null>[];
2505 const vDynamic = const <dynamic>[1, 2, 3];
2506 const vInterfaceNoTypeParameters = const <int>[1, 2, 3];
2507 const vInterfaceNoTypeArguments = const <List>[];
2508 const vInterfaceWithTypeArguments = const <List<String>>[];
2509 const vInterfaceWithTypeArguments2 = const <Map<int, List<String>>>[];
2510 ''');
2511 }
2512
2513 test_const_topLevel_typedList_imported() {
2514 addLibrarySource('/a.dart', 'class C {}');
2515 checkLibrary(r'''
2516 import 'a.dart';
2517 const v = const <C>[];
2518 ''');
2519 }
2520
2521 test_const_topLevel_typedList_importedWithPrefix() {
2522 addLibrarySource('/a.dart', 'class C {}');
2523 checkLibrary(r'''
2524 import 'a.dart' as p;
2525 const v = const <p.C>[];
2526 ''');
2527 }
2528
2529 test_const_topLevel_typedMap() {
2530 checkLibrary(r'''
2531 const vDynamic1 = const <dynamic, int>{};
2532 const vDynamic2 = const <int, dynamic>{};
2533 const vInterface = const <int, String>{};
2534 const vInterfaceWithTypeArguments = const <int, List<String>>{};
2535 ''');
2536 }
2537
2538 test_const_topLevel_untypedList() {
2539 checkLibrary(r'''
2540 const v = const [1, 2, 3];
2541 ''');
2542 }
2543
2544 test_const_topLevel_untypedMap() {
2545 checkLibrary(r'''
2546 const v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
2547 ''');
2548 }
2549
2550 test_constExpr_pushReference_field_simpleIdentifier() {
2551 checkLibrary('''
2552 class C {
2553 static const a = b;
2554 static const b = null;
2555 }
2556 ''');
2557 }
2558
2559 test_constExpr_pushReference_staticMethod_simpleIdentifier() {
2560 checkLibrary('''
2561 class C {
2562 static const a = m;
2563 static m() {}
2564 }
2565 ''');
2566 }
2567
2568 test_constructor_documented() {
2569 checkLibrary('''
2570 class C {
2571 /**
2572 * Docs
2573 */
2574 C();
2575 }''');
2576 }
2577
2578 test_constructor_initializers_field() {
2579 checkLibrary('''
2580 class C {
2581 final x;
2582 const C() : x = 42;
2583 }
2584 ''');
2585 }
2586
2587 test_constructor_initializers_field_notConst() {
2588 variablesWithNotConstInitializers.add('x');
2589 checkLibrary(
2590 '''
2591 class C {
2592 final x;
2593 const A() : x = foo();
2594 }
2595 int foo() => 42;
2596 ''',
2597 allowErrors: true);
2598 }
2599
2600 test_constructor_initializers_field_withParameter() {
2601 checkLibrary('''
2602 class C {
2603 final x;
2604 const C(int p) : x = 1 + p;
2605 }
2606 ''');
2607 }
2608
2609 test_constructor_initializers_superInvocation_named() {
2610 checkLibrary('''
2611 class A {
2612 const A.aaa(int p);
2613 }
2614 class C extends A {
2615 const C() : super.aaa(42);
2616 }
2617 ''');
2618 }
2619
2620 test_constructor_initializers_superInvocation_namedExpression() {
2621 checkLibrary('''
2622 class A {
2623 const A.aaa(a, {int b});
2624 }
2625 class C extends A {
2626 const C() : super.aaa(1, b: 2);
2627 }
2628 ''');
2629 }
2630
2631 test_constructor_initializers_superInvocation_unnamed() {
2632 checkLibrary('''
2633 class A {
2634 const A(int p);
2635 }
2636 class C extends A {
2637 const C.ccc() : super(42);
2638 }
2639 ''');
2640 }
2641
2642 test_constructor_initializers_thisInvocation_named() {
2643 checkLibrary('''
2644 class C {
2645 const C() : this.named(1, 'bbb');
2646 const C.named(int a, String b);
2647 }
2648 ''');
2649 }
2650
2651 test_constructor_initializers_thisInvocation_namedExpression() {
2652 checkLibrary('''
2653 class C {
2654 const C() : this.named(1, b: 2);
2655 const C.named(a, {int b});
2656 }
2657 ''');
2658 }
2659
2660 test_constructor_initializers_thisInvocation_unnamed() {
2661 checkLibrary('''
2662 class C {
2663 const C.named() : this(1, 'bbb');
2664 const C(int a, String b);
2665 }
2666 ''');
2667 }
2668
2669 test_constructor_redirected_factory_named() {
2670 checkLibrary('''
2671 class C {
2672 factory C() = D.named;
2673 C._();
2674 }
2675 class D extends C {
2676 D.named() : super._();
2677 }
2678 ''');
2679 }
2680
2681 test_constructor_redirected_factory_named_generic() {
2682 checkLibrary('''
2683 class C<T, U> {
2684 factory C() = D<U, T>.named;
2685 C._();
2686 }
2687 class D<T, U> extends C<U, T> {
2688 D.named() : super._();
2689 }
2690 ''');
2691 }
2692
2693 test_constructor_redirected_factory_named_imported() {
2694 addLibrarySource(
2695 '/foo.dart',
2696 '''
2697 import 'test.dart';
2698 class D extends C {
2699 D.named() : super._();
2700 }
2701 ''');
2702 checkLibrary('''
2703 import 'foo.dart';
2704 class C {
2705 factory C() = D.named;
2706 C._();
2707 }
2708 ''');
2709 }
2710
2711 test_constructor_redirected_factory_named_imported_generic() {
2712 addLibrarySource(
2713 '/foo.dart',
2714 '''
2715 import 'test.dart';
2716 class D<T, U> extends C<U, T> {
2717 D.named() : super._();
2718 }
2719 ''');
2720 checkLibrary('''
2721 import 'foo.dart';
2722 class C<T, U> {
2723 factory C() = D<U, T>.named;
2724 C._();
2725 }
2726 ''');
2727 }
2728
2729 test_constructor_redirected_factory_named_prefixed() {
2730 addLibrarySource(
2731 '/foo.dart',
2732 '''
2733 import 'test.dart';
2734 class D extends C {
2735 D.named() : super._();
2736 }
2737 ''');
2738 checkLibrary('''
2739 import 'foo.dart' as foo;
2740 class C {
2741 factory C() = foo.D.named;
2742 C._();
2743 }
2744 ''');
2745 }
2746
2747 test_constructor_redirected_factory_named_prefixed_generic() {
2748 addLibrarySource(
2749 '/foo.dart',
2750 '''
2751 import 'test.dart';
2752 class D<T, U> extends C<U, T> {
2753 D.named() : super._();
2754 }
2755 ''');
2756 checkLibrary('''
2757 import 'foo.dart' as foo;
2758 class C<T, U> {
2759 factory C() = foo.D<U, T>.named;
2760 C._();
2761 }
2762 ''');
2763 }
2764
2765 test_constructor_redirected_factory_unnamed() {
2766 checkLibrary('''
2767 class C {
2768 factory C() = D;
2769 C._();
2770 }
2771 class D extends C {
2772 D() : super._();
2773 }
2774 ''');
2775 }
2776
2777 test_constructor_redirected_factory_unnamed_generic() {
2778 checkLibrary('''
2779 class C<T, U> {
2780 factory C() = D<U, T>;
2781 C._();
2782 }
2783 class D<T, U> extends C<U, T> {
2784 D() : super._();
2785 }
2786 ''');
2787 }
2788
2789 test_constructor_redirected_factory_unnamed_imported() {
2790 addLibrarySource(
2791 '/foo.dart',
2792 '''
2793 import 'test.dart';
2794 class D extends C {
2795 D() : super._();
2796 }
2797 ''');
2798 checkLibrary('''
2799 import 'foo.dart';
2800 class C {
2801 factory C() = D;
2802 C._();
2803 }
2804 ''');
2805 }
2806
2807 test_constructor_redirected_factory_unnamed_imported_generic() {
2808 addLibrarySource(
2809 '/foo.dart',
2810 '''
2811 import 'test.dart';
2812 class D<T, U> extends C<U, T> {
2813 D() : super._();
2814 }
2815 ''');
2816 checkLibrary('''
2817 import 'foo.dart';
2818 class C<T, U> {
2819 factory C() = D<U, T>;
2820 C._();
2821 }
2822 ''');
2823 }
2824
2825 test_constructor_redirected_factory_unnamed_prefixed() {
2826 addLibrarySource(
2827 '/foo.dart',
2828 '''
2829 import 'test.dart';
2830 class D extends C {
2831 D() : super._();
2832 }
2833 ''');
2834 checkLibrary('''
2835 import 'foo.dart' as foo;
2836 class C {
2837 factory C() = foo.D;
2838 C._();
2839 }
2840 ''');
2841 }
2842
2843 test_constructor_redirected_factory_unnamed_prefixed_generic() {
2844 addLibrarySource(
2845 '/foo.dart',
2846 '''
2847 import 'test.dart';
2848 class D<T, U> extends C<U, T> {
2849 D() : super._();
2850 }
2851 ''');
2852 checkLibrary('''
2853 import 'foo.dart' as foo;
2854 class C<T, U> {
2855 factory C() = foo.D<U, T>;
2856 C._();
2857 }
2858 ''');
2859 }
2860
2861 test_constructor_redirected_thisInvocation_named() {
2862 checkLibrary('''
2863 class C {
2864 C.named();
2865 C() : this.named();
2866 }
2867 ''');
2868 }
2869
2870 test_constructor_redirected_thisInvocation_named_generic() {
2871 checkLibrary('''
2872 class C<T> {
2873 C.named();
2874 C() : this.named();
2875 }
2876 ''');
2877 }
2878
2879 test_constructor_redirected_thisInvocation_unnamed() {
2880 checkLibrary('''
2881 class C {
2882 C();
2883 C.named() : this();
2884 }
2885 ''');
2886 }
2887
2888 test_constructor_redirected_thisInvocation_unnamed_generic() {
2889 checkLibrary('''
2890 class C<T> {
2891 C();
2892 C.named() : this();
2893 }
2894 ''');
2895 }
2896
2897 test_constructor_withCycles_const() {
2898 checkLibrary('''
2899 class C {
2900 final x;
2901 const C() : x = const D();
2902 }
2903 class D {
2904 final x;
2905 const D() : x = const C();
2906 }
2907 ''');
2908 }
2909
2910 test_constructor_withCycles_nonConst() {
2911 checkLibrary('''
2912 class C {
2913 final x;
2914 C() : x = new D();
2915 }
2916 class D {
2917 final x;
2918 D() : x = new C();
2919 }
2920 ''');
2921 }
2922
2923 test_defaultValue_refersToGenericClass_constructor() {
2924 checkLibrary('''
2925 class B<T> {
2926 const B();
2927 }
2928 class C<T> {
2929 const C([B<T> b = const B()]);
2930 }
2931 ''');
2932 }
2933
2934 test_defaultValue_refersToGenericClass_constructor2() {
2935 checkLibrary('''
2936 abstract class A<T> {}
2937 class B<T> implements A<T> {
2938 const B();
2939 }
2940 class C<T> implements A<Iterable<T>> {
2941 const C([A<T> a = const B()]);
2942 }
2943 ''');
2944 }
2945
2946 test_defaultValue_refersToGenericClass_functionG() {
2947 checkLibrary('''
2948 class B<T> {
2949 const B();
2950 }
2951 void foo<T>([B<T> b = const B()]) {}
2952 ''');
2953 }
2954
2955 test_defaultValue_refersToGenericClass_methodG() {
2956 checkLibrary('''
2957 class B<T> {
2958 const B();
2959 }
2960 class C {
2961 void foo<T>([B<T> b = const B()]) {}
2962 }
2963 ''');
2964 }
2965
2966 test_defaultValue_refersToGenericClass_methodG_classG() {
2967 checkLibrary('''
2968 class B<T1, T2> {
2969 const B();
2970 }
2971 class C<E1> {
2972 void foo<E2>([B<E1, E2> b = const B()]) {}
2973 }
2974 ''');
2975 }
2976
2977 test_defaultValue_refersToGenericClass_methodNG() {
2978 checkLibrary('''
2979 class B<T> {
2980 const B();
2981 }
2982 class C<T> {
2983 void foo([B<T> b = const B()]) {}
2984 }
2985 ''');
2986 }
2987
2988 test_enum_documented() {
2989 checkLibrary('''
2990 // Extra comment so doc comment offset != 0
2991 /**
2992 * Docs
2993 */
2994 enum E { v }''');
2995 }
2996
2997 test_enum_value_documented() {
2998 checkLibrary('''
2999 enum E {
3000 /**
3001 * Docs
3002 */
3003 v
3004 }''');
3005 }
3006
3007 test_enum_values() {
3008 checkLibrary('enum E { v1, v2 }');
3009 }
3010
3011 test_enums() {
3012 checkLibrary('enum E1 { v1 } enum E2 { v2 }');
3013 }
3014
3015 test_executable_parameter_type_typedef() {
3016 checkLibrary(r'''
3017 typedef F(int p);
3018 main(F f) {}
3019 ''');
3020 }
3021
3022 test_export_class() {
3023 addLibrarySource('/a.dart', 'class C {}');
3024 checkLibrary('export "a.dart";');
3025 }
3026
3027 test_export_class_type_alias() {
3028 addLibrarySource(
3029 '/a.dart', 'class C {} exends _D with _E; class _D {} class _E {}');
3030 checkLibrary('export "a.dart";');
3031 }
3032
3033 test_export_configurations_useDefault() {
3034 context.declaredVariables.define('dart.library.io', 'false');
3035 addLibrarySource('/foo.dart', 'class A {}');
3036 addLibrarySource('/foo_io.dart', 'class A {}');
3037 addLibrarySource('/foo_html.dart', 'class A {}');
3038 LibraryElementImpl library = checkLibrary(r'''
3039 export 'foo.dart'
3040 if (dart.library.io) 'foo_io.dart'
3041 if (dart.library.html) 'foo_html.dart';
3042 ''');
3043 expect(library.exports[0].uri, 'foo.dart');
3044 expect(library.exports[0].exportedLibrary.source.shortName, 'foo.dart');
3045 }
3046
3047 test_export_configurations_useFirst() {
3048 context.declaredVariables.define('dart.library.io', 'true');
3049 context.declaredVariables.define('dart.library.html', 'true');
3050 addLibrarySource('/foo.dart', 'class A {}');
3051 addLibrarySource('/foo_io.dart', 'class A {}');
3052 addLibrarySource('/foo_html.dart', 'class A {}');
3053 LibraryElementImpl library = checkLibrary(r'''
3054 export 'foo.dart'
3055 if (dart.library.io) 'foo_io.dart'
3056 if (dart.library.html) 'foo_html.dart';
3057 ''');
3058 expect(library.exports[0].uri, 'foo_io.dart');
3059 expect(library.exports[0].exportedLibrary.source.shortName, 'foo_io.dart');
3060 }
3061
3062 test_export_configurations_useSecond() {
3063 context.declaredVariables.define('dart.library.io', 'false');
3064 context.declaredVariables.define('dart.library.html', 'true');
3065 addLibrarySource('/foo.dart', 'class A {}');
3066 addLibrarySource('/foo_io.dart', 'class A {}');
3067 addLibrarySource('/foo_html.dart', 'class A {}');
3068 LibraryElementImpl library = checkLibrary(r'''
3069 export 'foo.dart'
3070 if (dart.library.io) 'foo_io.dart'
3071 if (dart.library.html) 'foo_html.dart';
3072 ''');
3073 ExportElement export = library.exports[0];
3074 expect(export.uri, 'foo_html.dart');
3075 expect(export.exportedLibrary.source.shortName, 'foo_html.dart');
3076 }
3077
3078 test_export_function() {
3079 addLibrarySource('/a.dart', 'f() {}');
3080 checkLibrary('export "a.dart";');
3081 }
3082
3083 test_export_getter() {
3084 addLibrarySource('/a.dart', 'get f() => null;');
3085 checkLibrary('export "a.dart";');
3086 }
3087
3088 test_export_hide() {
3089 addLibrary('dart:async');
3090 checkLibrary('export "dart:async" hide Stream, Future;');
3091 }
3092
3093 test_export_multiple_combinators() {
3094 addLibrary('dart:async');
3095 checkLibrary('export "dart:async" hide Stream show Future;');
3096 }
3097
3098 test_export_setter() {
3099 addLibrarySource('/a.dart', 'void set f(value) {}');
3100 checkLibrary('export "a.dart";');
3101 }
3102
3103 test_export_show() {
3104 addLibrary('dart:async');
3105 checkLibrary('export "dart:async" show Future, Stream;');
3106 }
3107
3108 test_export_typedef() {
3109 addLibrarySource('/a.dart', 'typedef F();');
3110 checkLibrary('export "a.dart";');
3111 }
3112
3113 test_export_variable() {
3114 addLibrarySource('/a.dart', 'var x;');
3115 checkLibrary('export "a.dart";');
3116 }
3117
3118 test_export_variable_const() {
3119 addLibrarySource('/a.dart', 'const x = 0;');
3120 checkLibrary('export "a.dart";');
3121 }
3122
3123 test_export_variable_final() {
3124 addLibrarySource('/a.dart', 'final x = 0;');
3125 checkLibrary('export "a.dart";');
3126 }
3127
3128 test_exportImport_configurations_useDefault() {
3129 context.declaredVariables.define('dart.library.io', 'false');
3130 addLibrarySource('/foo.dart', 'class A {}');
3131 addLibrarySource('/foo_io.dart', 'class A {}');
3132 addLibrarySource('/foo_html.dart', 'class A {}');
3133 addLibrarySource(
3134 '/bar.dart',
3135 r'''
3136 export 'foo.dart'
3137 if (dart.library.io) 'foo_io.dart'
3138 if (dart.library.html) 'foo_html.dart';
3139 ''');
3140 LibraryElementImpl library = checkLibrary(r'''
3141 import 'bar.dart';
3142 class B extends A {}
3143 ''');
3144 var typeA = library.definingCompilationUnit.getType('B').supertype;
3145 expect(typeA.element.source.shortName, 'foo.dart');
3146 }
3147
3148 test_exportImport_configurations_useFirst() {
3149 context.declaredVariables.define('dart.library.io', 'true');
3150 context.declaredVariables.define('dart.library.html', 'true');
3151 addLibrarySource('/foo.dart', 'class A {}');
3152 addLibrarySource('/foo_io.dart', 'class A {}');
3153 addLibrarySource('/foo_html.dart', 'class A {}');
3154 addLibrarySource(
3155 '/bar.dart',
3156 r'''
3157 export 'foo.dart'
3158 if (dart.library.io) 'foo_io.dart'
3159 if (dart.library.html) 'foo_html.dart';
3160 ''');
3161 var library = checkLibrary(r'''
3162 import 'bar.dart';
3163 class B extends A {}
3164 ''');
3165 var typeA = library.definingCompilationUnit.getType('B').supertype;
3166 expect(typeA.element.source.shortName, 'foo_io.dart');
3167 }
3168
3169 test_exports() {
3170 addLibrarySource('/a.dart', 'library a;');
3171 addLibrarySource('/b.dart', 'library b;');
3172 checkLibrary('export "a.dart"; export "b.dart";');
3173 }
3174
3175 test_field_documented() {
3176 checkLibrary('''
3177 class C {
3178 /**
3179 * Docs
3180 */
3181 var x;
3182 }''');
3183 }
3184
3185 test_field_formal_param_inferred_type_implicit() {
3186 checkLibrary('class C extends D { var v; C(this.v); }'
3187 ' abstract class D { int get v; }');
3188 }
3189
3190 test_field_inferred_type_nonStatic_explicit_initialized() {
3191 checkLibrary('class C { num v = 0; }');
3192 }
3193
3194 test_field_inferred_type_nonStatic_implicit_initialized() {
3195 checkLibrary('class C { var v = 0; }');
3196 }
3197
3198 test_field_inferred_type_nonStatic_implicit_uninitialized() {
3199 checkLibrary(
3200 'class C extends D { var v; } abstract class D { int get v; }');
3201 }
3202
3203 test_field_inferred_type_static_implicit_initialized() {
3204 checkLibrary('class C { static var v = 0; }');
3205 }
3206
3207 test_field_propagatedType_const_noDep() {
3208 checkLibrary('''
3209 class C {
3210 static const x = 0;
3211 }''');
3212 }
3213
3214 test_field_propagatedType_final_dep_inLib() {
3215 addLibrarySource('/a.dart', 'final a = 1;');
3216 checkLibrary('''
3217 import "a.dart";
3218 class C {
3219 final b = a / 2;
3220 }''');
3221 }
3222
3223 test_field_propagatedType_final_dep_inPart() {
3224 addSource('/a.dart', 'part of lib; final a = 1;');
3225 checkLibrary('''
3226 library lib;
3227 part "a.dart";
3228 class C {
3229 final b = a / 2;
3230 }''');
3231 }
3232
3233 test_field_propagatedType_final_noDep_instance() {
3234 checkLibrary('''
3235 class C {
3236 final x = 0;
3237 }''');
3238 }
3239
3240 test_field_propagatedType_final_noDep_static() {
3241 checkLibrary('''
3242 class C {
3243 static final x = 0;
3244 }''');
3245 }
3246
3247 test_field_static_final_untyped() {
3248 checkLibrary('class C { static final x = 0; }');
3249 }
3250
3251 test_field_untyped() {
3252 checkLibrary('class C { var x = 0; }');
3253 }
3254
3255 test_function_async() {
3256 checkLibrary(r'''
3257 import 'dart:async';
3258 Future f() async {}
3259 ''');
3260 }
3261
3262 test_function_asyncStar() {
3263 checkLibrary(r'''
3264 import 'dart:async';
3265 Stream f() async* {}
3266 ''');
3267 }
3268
3269 test_function_documented() {
3270 checkLibrary('''
3271 // Extra comment so doc comment offset != 0
3272 /**
3273 * Docs
3274 */
3275 f() {}''');
3276 }
3277
3278 test_function_entry_point() {
3279 checkLibrary('main() {}');
3280 }
3281
3282 test_function_entry_point_in_export() {
3283 addLibrarySource('/a.dart', 'library a; main() {}');
3284 checkLibrary('export "a.dart";');
3285 }
3286
3287 test_function_entry_point_in_export_hidden() {
3288 addLibrarySource('/a.dart', 'library a; main() {}');
3289 checkLibrary('export "a.dart" hide main;');
3290 }
3291
3292 test_function_entry_point_in_part() {
3293 addSource('/a.dart', 'part of my.lib; main() {}');
3294 checkLibrary('library my.lib; part "a.dart";');
3295 }
3296
3297 test_function_external() {
3298 checkLibrary('external f();');
3299 }
3300
3301 test_function_parameter_kind_named() {
3302 checkLibrary('f({x}) {}');
3303 }
3304
3305 test_function_parameter_kind_positional() {
3306 checkLibrary('f([x]) {}');
3307 }
3308
3309 test_function_parameter_kind_required() {
3310 checkLibrary('f(x) {}');
3311 }
3312
3313 test_function_parameter_parameters() {
3314 checkLibrary('f(g(x, y)) {}');
3315 }
3316
3317 test_function_parameter_return_type() {
3318 checkLibrary('f(int g()) {}');
3319 }
3320
3321 test_function_parameter_return_type_void() {
3322 checkLibrary('f(void g()) {}');
3323 }
3324
3325 test_function_parameter_type() {
3326 checkLibrary('f(int i) {}');
3327 }
3328
3329 test_function_parameters() {
3330 checkLibrary('f(x, y) {}');
3331 }
3332
3333 test_function_return_type() {
3334 checkLibrary('int f() => null;');
3335 }
3336
3337 test_function_return_type_implicit() {
3338 checkLibrary('f() => null;');
3339 }
3340
3341 test_function_return_type_void() {
3342 checkLibrary('void f() {}');
3343 }
3344
3345 test_function_type_parameter() {
3346 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
3347 checkLibrary('T f<T, U>(U u) => null;');
3348 }
3349
3350 test_function_type_parameter_with_function_typed_parameter() {
3351 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
3352 checkLibrary('void f<T, U>(T x(U u)) {}');
3353 }
3354
3355 test_functions() {
3356 checkLibrary('f() {} g() {}');
3357 }
3358
3359 test_generic_gClass_gMethodStatic() {
3360 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
3361 checkLibrary('''
3362 class C<T, U> {
3363 static void m<V, W>(V v, W w) {
3364 void f<X, Y>(V v, W w, X x, Y y) {
3365 }
3366 }
3367 }
3368 ''');
3369 }
3370
3371 test_getElement_constructor_named() {
3372 String text = 'class C { C.named(); }';
3373 Source source = addLibrarySource('/test.dart', text);
3374 ConstructorElement original = context
3375 .computeLibraryElement(source)
3376 .getType('C')
3377 .getNamedConstructor('named');
3378 expect(original, isNotNull);
3379 ConstructorElement resynthesized = validateGetElement(text, original);
3380 compareConstructorElements(resynthesized, original, 'C.constructor named');
3381 }
3382
3383 test_getElement_constructor_unnamed() {
3384 String text = 'class C { C(); }';
3385 Source source = addLibrarySource('/test.dart', text);
3386 ConstructorElement original =
3387 context.computeLibraryElement(source).getType('C').unnamedConstructor;
3388 expect(original, isNotNull);
3389 ConstructorElement resynthesized = validateGetElement(text, original);
3390 compareConstructorElements(resynthesized, original, 'C.constructor');
3391 }
3392
3393 test_getElement_field() {
3394 String text = 'class C { var f; }';
3395 Source source = addLibrarySource('/test.dart', text);
3396 FieldElement original =
3397 context.computeLibraryElement(source).getType('C').getField('f');
3398 expect(original, isNotNull);
3399 FieldElement resynthesized = validateGetElement(text, original);
3400 compareFieldElements(resynthesized, original, 'C.field f');
3401 }
3402
3403 test_getElement_getter() {
3404 String text = 'class C { get f => null; }';
3405 Source source = addLibrarySource('/test.dart', text);
3406 PropertyAccessorElement original =
3407 context.computeLibraryElement(source).getType('C').getGetter('f');
3408 expect(original, isNotNull);
3409 PropertyAccessorElement resynthesized = validateGetElement(text, original);
3410 comparePropertyAccessorElements(resynthesized, original, 'C.getter f');
3411 }
3412
3413 test_getElement_method() {
3414 String text = 'class C { f() {} }';
3415 Source source = addLibrarySource('/test.dart', text);
3416 MethodElement original =
3417 context.computeLibraryElement(source).getType('C').getMethod('f');
3418 expect(original, isNotNull);
3419 MethodElement resynthesized = validateGetElement(text, original);
3420 compareMethodElements(resynthesized, original, 'C.method f');
3421 }
3422
3423 test_getElement_operator() {
3424 String text = 'class C { operator+(x) => null; }';
3425 Source source = addLibrarySource('/test.dart', text);
3426 MethodElement original =
3427 context.computeLibraryElement(source).getType('C').getMethod('+');
3428 expect(original, isNotNull);
3429 MethodElement resynthesized = validateGetElement(text, original);
3430 compareMethodElements(resynthesized, original, 'C.operator+');
3431 }
3432
3433 test_getElement_setter() {
3434 String text = 'class C { void set f(value) {} }';
3435 Source source = addLibrarySource('/test.dart', text);
3436 PropertyAccessorElement original =
3437 context.computeLibraryElement(source).getType('C').getSetter('f');
3438 expect(original, isNotNull);
3439 PropertyAccessorElement resynthesized = validateGetElement(text, original);
3440 comparePropertyAccessorElements(resynthesized, original, 'C.setter f');
3441 }
3442
3443 test_getElement_unit() {
3444 String text = 'class C { f() {} }';
3445 Source source = addLibrarySource('/test.dart', text);
3446 CompilationUnitElement original =
3447 context.computeLibraryElement(source).definingCompilationUnit;
3448 expect(original, isNotNull);
3449 CompilationUnitElement resynthesized = validateGetElement(text, original);
3450 compareCompilationUnitElements(resynthesized, original);
3451 }
3452
3453 test_getter_documented() {
3454 checkLibrary('''
3455 // Extra comment so doc comment offset != 0
3456 /**
3457 * Docs
3458 */
3459 get x => null;''');
3460 }
3461
3462 test_getter_external() {
3463 checkLibrary('external int get x;');
3464 }
3465
3466 test_getter_inferred_type_nonStatic_implicit_return() {
3467 checkLibrary(
3468 'class C extends D { get f => null; } abstract class D { int get f; }');
3469 }
3470
3471 test_getters() {
3472 checkLibrary('int get x => null; get y => null;');
3473 }
3474
3475 test_implicitTopLevelVariable_getterFirst() {
3476 checkLibrary('int get x => 0; void set x(int value) {}');
3477 }
3478
3479 test_implicitTopLevelVariable_setterFirst() {
3480 checkLibrary('void set x(int value) {} int get x => 0;');
3481 }
3482
3483 test_import_configurations_useDefault() {
3484 context.declaredVariables.define('dart.library.io', 'false');
3485 addLibrarySource('/foo.dart', 'class A {}');
3486 addLibrarySource('/foo_io.dart', 'class A {}');
3487 addLibrarySource('/foo_html.dart', 'class A {}');
3488 var library = checkLibrary(r'''
3489 import 'foo.dart'
3490 if (dart.library.io) 'foo_io.dart'
3491 if (dart.library.html) 'foo_html.dart';
3492
3493 class B extends A {}
3494 ''');
3495 var typeA = library.definingCompilationUnit.getType('B').supertype;
3496 expect(typeA.element.source.shortName, 'foo.dart');
3497 }
3498
3499 test_import_configurations_useFirst() {
3500 context.declaredVariables.define('dart.library.io', 'true');
3501 context.declaredVariables.define('dart.library.html', 'true');
3502 addLibrarySource('/foo.dart', 'class A {}');
3503 addLibrarySource('/foo_io.dart', 'class A {}');
3504 addLibrarySource('/foo_html.dart', 'class A {}');
3505 var library = checkLibrary(r'''
3506 import 'foo.dart'
3507 if (dart.library.io) 'foo_io.dart'
3508 if (dart.library.html) 'foo_html.dart';
3509
3510 class B extends A {}
3511 ''');
3512 var typeA = library.definingCompilationUnit.getType('B').supertype;
3513 expect(typeA.element.source.shortName, 'foo_io.dart');
3514 }
3515
3516 test_import_deferred() {
3517 addLibrarySource('/a.dart', 'f() {}');
3518 checkLibrary('import "a.dart" deferred as p; main() { p.f(); }');
3519 }
3520
3521 test_import_hide() {
3522 addLibrary('dart:async');
3523 checkLibrary('import "dart:async" hide Stream, Completer; Future f;');
3524 }
3525
3526 test_import_multiple_combinators() {
3527 addLibrary('dart:async');
3528 checkLibrary('import "dart:async" hide Stream show Future; Future f;');
3529 }
3530
3531 test_import_prefixed() {
3532 addLibrarySource('/a.dart', 'library a; class C {}');
3533 checkLibrary('import "a.dart" as a; a.C c;');
3534 }
3535
3536 test_import_self() {
3537 LibraryElementImpl resynthesized = checkLibrary('''
3538 import 'test.dart' as p;
3539 class C {}
3540 class D extends p.C {} // Prevent "unused import" warning
3541 ''');
3542 expect(resynthesized.imports, hasLength(2));
3543 expect(resynthesized.imports[0].importedLibrary.location,
3544 resynthesized.location);
3545 expect(resynthesized.imports[1].importedLibrary.isDartCore, true);
3546 }
3547
3548 test_import_show() {
3549 addLibrary('dart:async');
3550 checkLibrary('''
3551 import "dart:async" show Future, Stream;
3552 Future f;
3553 Stream s;
3554 ''');
3555 }
3556
3557 test_imports() {
3558 addLibrarySource('/a.dart', 'library a; class C {}');
3559 addLibrarySource('/b.dart', 'library b; class D {}');
3560 checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
3561 }
3562
3563 test_inferred_function_type_for_variable_in_generic_function() {
3564 // In the code below, `x` has an inferred type of `() => int`, with 2
3565 // (unused) type parameters from the enclosing top level function.
3566 checkLibrary('''
3567 f<U, V>() {
3568 var x = () => 0;
3569 }
3570 ''');
3571 }
3572
3573 test_inferred_function_type_in_generic_class_constructor() {
3574 // In the code below, `() => () => 0` has an inferred return type of
3575 // `() => int`, with 2 (unused) type parameters from the enclosing class.
3576 checkLibrary('''
3577 class C<U, V> {
3578 final x;
3579 C() : x = (() => () => 0);
3580 }
3581 ''');
3582 }
3583
3584 test_inferred_function_type_in_generic_class_getter() {
3585 // In the code below, `() => () => 0` has an inferred return type of
3586 // `() => int`, with 2 (unused) type parameters from the enclosing class.
3587 checkLibrary('''
3588 class C<U, V> {
3589 get x => () => () => 0;
3590 }
3591 ''');
3592 }
3593
3594 test_inferred_function_type_in_generic_class_in_generic_method() {
3595 // In the code below, `() => () => 0` has an inferred return type of
3596 // `() => int`, with 3 (unused) type parameters from the enclosing class
3597 // and method.
3598 checkLibrary('''
3599 class C<T> {
3600 f<U, V>() {
3601 print(() => () => 0);
3602 }
3603 }
3604 ''');
3605 }
3606
3607 test_inferred_function_type_in_generic_class_setter() {
3608 // In the code below, `() => () => 0` has an inferred return type of
3609 // `() => int`, with 2 (unused) type parameters from the enclosing class.
3610 checkLibrary('''
3611 class C<U, V> {
3612 void set x(value) {
3613 print(() => () => 0);
3614 }
3615 }
3616 ''');
3617 }
3618
3619 test_inferred_function_type_in_generic_closure() {
3620 if (!createOptions().strongMode) {
3621 // The test below uses generic comment syntax because proper generic
3622 // method syntax doesn't support generic closures. So it can only run in
3623 // strong mode.
3624 // TODO(paulberry): once proper generic method syntax supports generic
3625 // closures, rewrite the test below without using generic comment syntax,
3626 // and remove this hack. See dartbug.com/25819
3627 return;
3628 }
3629 // In the code below, `<U, V>() => () => 0` has an inferred return type of
3630 // `() => int`, with 3 (unused) type parameters.
3631 checkLibrary('''
3632 f<T>() {
3633 print(/*<U, V>*/() => () => 0);
3634 }
3635 ''');
3636 }
3637
3638 test_inferred_generic_function_type_in_generic_closure() {
3639 if (!createOptions().strongMode) {
3640 // The test below uses generic comment syntax because proper generic
3641 // method syntax doesn't support generic closures. So it can only run in
3642 // strong mode.
3643 // TODO(paulberry): once proper generic method syntax supports generic
3644 // closures, rewrite the test below without using generic comment syntax,
3645 // and remove this hack. See dartbug.com/25819
3646 return;
3647 }
3648 // In the code below, `<U, V>() => <W, X, Y, Z>() => 0` has an inferred
3649 // return type of `() => int`, with 7 (unused) type parameters.
3650 checkLibrary('''
3651 f<T>() {
3652 print(/*<U, V>*/() => /*<W, X, Y, Z>*/() => 0);
3653 }
3654 ''');
3655 }
3656
3657 test_inferred_type_is_typedef() {
3658 checkLibrary('typedef int F(String s);'
3659 ' class C extends D { var v; }'
3660 ' abstract class D { F get v; }');
3661 }
3662
3663 test_inferred_type_refers_to_bound_type_param() {
3664 checkLibrary('class C<T> extends D<int, T> { var v; }'
3665 ' abstract class D<U, V> { Map<V, U> get v; }');
3666 }
3667
3668 void test_inferred_type_refers_to_function_typed_param_of_typedef() {
3669 checkLibrary('''
3670 typedef void F(int g(String s));
3671 h(F f) => null;
3672 var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
3673 ''');
3674 }
3675
3676 test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
3677 checkLibrary('class C<T, U> extends D<U, int> { void f(int x, g) {} }'
3678 ' abstract class D<V, W> { void f(int x, W g(V s)); }');
3679 }
3680
3681 test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
3682 addLibrarySource(
3683 '/a.dart', 'import "b.dart"; abstract class D extends E {}');
3684 addLibrarySource(
3685 '/b.dart', 'abstract class E { void f(int x, int g(String s)); }');
3686 checkLibrary('import "a.dart"; class C extends D { void f(int x, g) {} }');
3687 }
3688
3689 test_inferred_type_refers_to_method_function_typed_parameter_type() {
3690 checkLibrary('class C extends D { void f(int x, g) {} }'
3691 ' abstract class D { void f(int x, int g(String s)); }');
3692 }
3693
3694 test_inferred_type_refers_to_nested_function_typed_param() {
3695 checkLibrary('''
3696 f(void g(int x, void h())) => null;
3697 var v = f((x, y) {});
3698 ''');
3699 }
3700
3701 test_inferred_type_refers_to_nested_function_typed_param_named() {
3702 checkLibrary('''
3703 f({void g(int x, void h())}) => null;
3704 var v = f(g: (x, y) {});
3705 ''');
3706 }
3707
3708 test_inferred_type_refers_to_setter_function_typed_parameter_type() {
3709 checkLibrary('class C extends D { void set f(g) {} }'
3710 ' abstract class D { void set f(int g(String s)); }');
3711 }
3712
3713 void test_inferredType_usesSyntheticFunctionType_functionTypedParam() {
3714 checkLibrary('''
3715 int f(int x(String y)) => null;
3716 String g(int x(String y)) => null;
3717 var v = [f, g];
3718 ''');
3719 }
3720
3721 test_initializer_executable_with_return_type_from_closure() {
3722 checkLibrary('var v = () => 0;');
3723 }
3724
3725 test_initializer_executable_with_return_type_from_closure_field() {
3726 checkLibrary('''
3727 class C {
3728 var v = () => 0;
3729 }
3730 ''');
3731 }
3732
3733 test_initializer_executable_with_return_type_from_closure_local() {
3734 checkLibrary('''
3735 void f() {
3736 int u = 0;
3737 var v = () => 0;
3738 }
3739 ''');
3740 }
3741
3742 test_instantiateToBounds_boundRefersToEarlierTypeArgument() {
3743 checkLibrary('''
3744 class C<S extends num, T extends C<S, T>> {}
3745 C c;
3746 ''');
3747 }
3748
3749 test_instantiateToBounds_boundRefersToItself() {
3750 checkLibrary('''
3751 class C<T extends C<T>> {}
3752 C c;
3753 ''');
3754 }
3755
3756 test_instantiateToBounds_boundRefersToLaterTypeArgument() {
3757 checkLibrary('''
3758 class C<T extends C<T, U>, U extends num> {}
3759 C c;
3760 ''');
3761 }
3762
3763 test_instantiateToBounds_simple() {
3764 checkLibrary('''
3765 class C<T extends num> {}
3766 C c;
3767 ''');
3768 }
3769
3770 test_library() {
3771 checkLibrary('');
3772 }
3773
3774 test_library_documented() {
3775 checkLibrary('''
3776 // Extra comment so doc comment offset != 0
3777 /**
3778 * Docs
3779 */
3780 library foo;''');
3781 }
3782
3783 test_library_name_with_spaces() {
3784 checkLibrary('library foo . bar ;');
3785 }
3786
3787 test_library_named() {
3788 checkLibrary('library foo.bar;');
3789 }
3790
3791 test_localFunctions() {
3792 checkLibrary(r'''
3793 f() {
3794 f1() {}
3795 {
3796 f2() {}
3797 }
3798 }
3799 ''');
3800 }
3801
3802 test_localFunctions_inConstructor() {
3803 checkLibrary(r'''
3804 class C {
3805 C() {
3806 f() {}
3807 }
3808 }
3809 ''');
3810 }
3811
3812 test_localFunctions_inMethod() {
3813 checkLibrary(r'''
3814 class C {
3815 m() {
3816 f() {}
3817 }
3818 }
3819 ''');
3820 }
3821
3822 test_localFunctions_inTopLevelGetter() {
3823 checkLibrary(r'''
3824 get g {
3825 f() {}
3826 }
3827 ''');
3828 }
3829
3830 test_localLabels_inConstructor() {
3831 checkLibrary(
3832 r'''
3833 class C {
3834 C() {
3835 aaa: while (true) {}
3836 bbb: switch (42) {
3837 ccc: case 0:
3838 break;
3839 }
3840 }
3841 }
3842 ''',
3843 allowErrors: true);
3844 }
3845
3846 test_localLabels_inMethod() {
3847 checkLibrary(
3848 r'''
3849 class C {
3850 m() {
3851 aaa: while (true) {}
3852 bbb: switch (42) {
3853 ccc: case 0:
3854 break;
3855 }
3856 }
3857 }
3858 ''',
3859 allowErrors: true);
3860 }
3861
3862 test_localLabels_inTopLevelFunction() {
3863 checkLibrary(
3864 r'''
3865 main() {
3866 aaa: while (true) {}
3867 bbb: switch (42) {
3868 ccc: case 0:
3869 break;
3870 }
3871 }
3872 ''',
3873 allowErrors: true);
3874 }
3875
3876 test_localVariables_inConstructor() {
3877 checkLibrary(r'''
3878 class C {
3879 C() {
3880 int v;
3881 f() {}
3882 }
3883 }
3884 ''');
3885 }
3886
3887 test_localVariables_inLocalFunction() {
3888 checkLibrary(r'''
3889 f() {
3890 f1() {
3891 int v1 = 1;
3892 } // 2
3893 f2() {
3894 int v1 = 1;
3895 f3() {
3896 int v2 = 1;
3897 }
3898 }
3899 }
3900 ''');
3901 }
3902
3903 test_localVariables_inMethod() {
3904 checkLibrary(r'''
3905 class C {
3906 m() {
3907 int v;
3908 }
3909 }
3910 ''');
3911 }
3912
3913 test_localVariables_inTopLevelFunction() {
3914 checkLibrary(r'''
3915 main() {
3916 int v1 = 1;
3917 {
3918 const String v2 = 'bbb';
3919 }
3920 Map<int, List<double>> v3;
3921 }
3922 ''');
3923 }
3924
3925 test_localVariables_inTopLevelGetter() {
3926 checkLibrary(r'''
3927 get g {
3928 int v;
3929 }
3930 ''');
3931 }
3932
3933 test_main_class() {
3934 checkLibrary('class main {}');
3935 }
3936
3937 test_main_class_alias() {
3938 checkLibrary('class main = C with D; class C {} class D {}');
3939 }
3940
3941 test_main_class_alias_via_export() {
3942 addLibrarySource('/a.dart', 'class main = C with D; class C {} class D {}');
3943 checkLibrary('export "a.dart";');
3944 }
3945
3946 test_main_class_via_export() {
3947 addLibrarySource('/a.dart', 'class main {}');
3948 checkLibrary('export "a.dart";');
3949 }
3950
3951 test_main_getter() {
3952 checkLibrary('get main => null;');
3953 }
3954
3955 test_main_getter_via_export() {
3956 addLibrarySource('/a.dart', 'get main => null;');
3957 checkLibrary('export "a.dart";');
3958 }
3959
3960 test_main_typedef() {
3961 checkLibrary('typedef main();');
3962 }
3963
3964 test_main_typedef_via_export() {
3965 addLibrarySource('/a.dart', 'typedef main();');
3966 checkLibrary('export "a.dart";');
3967 }
3968
3969 test_main_variable() {
3970 checkLibrary('var main;');
3971 }
3972
3973 test_main_variable_via_export() {
3974 addLibrarySource('/a.dart', 'var main;');
3975 checkLibrary('export "a.dart";');
3976 }
3977
3978 test_member_function_async() {
3979 checkLibrary(r'''
3980 import 'dart:async';
3981 class C {
3982 Future f() async {}
3983 }
3984 ''');
3985 }
3986
3987 test_member_function_asyncStar() {
3988 checkLibrary(r'''
3989 import 'dart:async';
3990 class C {
3991 Stream f() async* {}
3992 }
3993 ''');
3994 }
3995
3996 test_metadata_classDeclaration() {
3997 checkLibrary('const a = null; @a class C {}');
3998 }
3999
4000 test_metadata_classTypeAlias() {
4001 checkLibrary(
4002 'const a = null; @a class C = D with E; class D {} class E {}');
4003 }
4004
4005 test_metadata_constructor_call_named() {
4006 checkLibrary('class A { const A.named(); } @A.named() class C {}');
4007 }
4008
4009 test_metadata_constructor_call_named_prefixed() {
4010 addLibrarySource('/foo.dart', 'class A { const A.named(); }');
4011 checkLibrary('import "foo.dart" as foo; @foo.A.named() class C {}');
4012 }
4013
4014 test_metadata_constructor_call_unnamed() {
4015 checkLibrary('class A { const A(); } @A() class C {}');
4016 }
4017
4018 test_metadata_constructor_call_unnamed_prefixed() {
4019 addLibrarySource('/foo.dart', 'class A { const A(); }');
4020 checkLibrary('import "foo.dart" as foo; @foo.A() class C {}');
4021 }
4022
4023 test_metadata_constructor_call_with_args() {
4024 checkLibrary('class A { const A(x); } @A(null) class C {}');
4025 }
4026
4027 test_metadata_constructorDeclaration_named() {
4028 checkLibrary('const a = null; class C { @a C.named(); }');
4029 }
4030
4031 test_metadata_constructorDeclaration_unnamed() {
4032 checkLibrary('const a = null; class C { @a C(); }');
4033 }
4034
4035 test_metadata_enumDeclaration() {
4036 checkLibrary('const a = null; @a enum E { v }');
4037 }
4038
4039 test_metadata_exportDirective() {
4040 addLibrarySource('/foo.dart', '');
4041 checkLibrary('@a export "foo.dart"; const a = null;');
4042 }
4043
4044 test_metadata_fieldDeclaration() {
4045 checkLibrary('const a = null; class C { @a int x; }');
4046 }
4047
4048 test_metadata_fieldFormalParameter() {
4049 checkLibrary('const a = null; class C { var x; C(@a this.x); }');
4050 }
4051
4052 test_metadata_fieldFormalParameter_withDefault() {
4053 checkLibrary('const a = null; class C { var x; C([@a this.x = null]); }');
4054 }
4055
4056 test_metadata_functionDeclaration_function() {
4057 checkLibrary('const a = null; @a f() {}');
4058 }
4059
4060 test_metadata_functionDeclaration_getter() {
4061 checkLibrary('const a = null; @a get f => null;');
4062 }
4063
4064 test_metadata_functionDeclaration_setter() {
4065 checkLibrary('const a = null; @a set f(value) {}');
4066 }
4067
4068 test_metadata_functionTypeAlias() {
4069 checkLibrary('const a = null; @a typedef F();');
4070 }
4071
4072 test_metadata_functionTypedFormalParameter() {
4073 checkLibrary('const a = null; f(@a g()) {}');
4074 }
4075
4076 test_metadata_functionTypedFormalParameter_withDefault() {
4077 checkLibrary('const a = null; f([@a g() = null]) {}');
4078 }
4079
4080 test_metadata_importDirective() {
4081 addLibrarySource('/foo.dart', 'const b = null;');
4082 checkLibrary('@a import "foo.dart"; const a = b;');
4083 }
4084
4085 test_metadata_libraryDirective() {
4086 checkLibrary('@a library L; const a = null;');
4087 }
4088
4089 test_metadata_methodDeclaration_getter() {
4090 checkLibrary('const a = null; class C { @a get m => null; }');
4091 }
4092
4093 test_metadata_methodDeclaration_method() {
4094 checkLibrary('const a = null; class C { @a m() {} }');
4095 }
4096
4097 test_metadata_methodDeclaration_setter() {
4098 checkLibrary('const a = null; class C { @a set m(value) {} }');
4099 }
4100
4101 test_metadata_partDirective() {
4102 addSource('/foo.dart', 'part of L;');
4103 checkLibrary('library L; @a part "foo.dart"; const a = null;');
4104 }
4105
4106 test_metadata_prefixed_variable() {
4107 addLibrarySource('/a.dart', 'const b = null;');
4108 checkLibrary('import "a.dart" as a; @a.b class C {}');
4109 }
4110
4111 test_metadata_simpleFormalParameter() {
4112 checkLibrary('const a = null; f(@a x) {}');
4113 }
4114
4115 test_metadata_simpleFormalParameter_withDefault() {
4116 checkLibrary('const a = null; f([@a x = null]) {}');
4117 }
4118
4119 test_metadata_topLevelVariableDeclaration() {
4120 checkLibrary('const a = null; @a int v;');
4121 }
4122
4123 test_metadata_typeParameter_ofClass() {
4124 checkLibrary('const a = null; class C<@a T> {}');
4125 }
4126
4127 test_metadata_typeParameter_ofClassTypeAlias() {
4128 checkLibrary(
4129 'const a = null; class C<@a T> = D with E; class D {} class E {}');
4130 }
4131
4132 test_metadata_typeParameter_ofFunction() {
4133 checkLibrary('const a = null; f<@a T>() {}');
4134 }
4135
4136 test_metadata_typeParameter_ofTypedef() {
4137 checkLibrary('const a = null; typedef F<@a T>();');
4138 }
4139
4140 test_method_documented() {
4141 checkLibrary('''
4142 class C {
4143 /**
4144 * Docs
4145 */
4146 f() {}
4147 }''');
4148 }
4149
4150 test_method_inferred_type_nonStatic_implicit_param() {
4151 checkLibrary('class C extends D { void f(value) {} }'
4152 ' abstract class D { void f(int value); }');
4153 }
4154
4155 test_method_inferred_type_nonStatic_implicit_return() {
4156 checkLibrary(
4157 'class C extends D { f() => null; } abstract class D { int f(); }');
4158 }
4159
4160 test_method_parameter_parameters() {
4161 checkLibrary('class C { f(g(x, y)) {} }');
4162 }
4163
4164 test_method_parameter_parameters_in_generic_class() {
4165 checkLibrary('class C<A, B> { f(A g(B x)) {} }');
4166 }
4167
4168 test_method_parameter_return_type() {
4169 checkLibrary('class C { f(int g()) {} }');
4170 }
4171
4172 test_method_parameter_return_type_void() {
4173 checkLibrary('class C { f(void g()) {} }');
4174 }
4175
4176 test_method_type_parameter() {
4177 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
4178 checkLibrary('class C { T f<T, U>(U u) => null; }');
4179 }
4180
4181 test_method_type_parameter_in_generic_class() {
4182 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
4183 checkLibrary('class C<T, U> { V f<V, W>(T t, U u, W w) => null; }');
4184 }
4185
4186 test_method_type_parameter_with_function_typed_parameter() {
4187 prepareAnalysisContext(createOptions()..enableGenericMethods = true);
4188 checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
4189 }
4190
4191 test_nested_generic_functions_in_generic_class_with_function_typed_params() {
4192 checkLibrary('''
4193 class C<T, U> {
4194 void g<V, W>() {
4195 void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
4196 }
4197 }
4198 }
4199 ''');
4200 }
4201
4202 test_nested_generic_functions_in_generic_class_with_local_variables() {
4203 checkLibrary('''
4204 class C<T, U> {
4205 void g<V, W>() {
4206 void h<X, Y>() {
4207 T t;
4208 U u;
4209 V v;
4210 W w;
4211 X x;
4212 Y y;
4213 }
4214 }
4215 }
4216 ''');
4217 }
4218
4219 test_nested_generic_functions_with_function_typed_param() {
4220 checkLibrary('''
4221 void f<T, U>() {
4222 void g<V, W>() {
4223 void h<X, Y>(void p(T t, U u, V v, W w, X x, Y y)) {
4224 }
4225 }
4226 }
4227 ''');
4228 }
4229
4230 test_nested_generic_functions_with_local_variables() {
4231 checkLibrary('''
4232 void f<T, U>() {
4233 void g<V, W>() {
4234 void h<X, Y>() {
4235 T t;
4236 U u;
4237 V v;
4238 W w;
4239 X x;
4240 Y y;
4241 }
4242 }
4243 }
4244 ''');
4245 }
4246
4247 test_operator() {
4248 checkLibrary('class C { C operator+(C other) => null; }');
4249 }
4250
4251 test_operator_equal() {
4252 checkLibrary('class C { bool operator==(Object other) => false; }');
4253 }
4254
4255 test_operator_external() {
4256 checkLibrary('class C { external C operator+(C other); }');
4257 }
4258
4259 test_operator_greater_equal() {
4260 checkLibrary('class C { bool operator>=(C other) => false; }');
4261 }
4262
4263 test_operator_index() {
4264 checkLibrary('class C { bool operator[](int i) => null; }');
4265 }
4266
4267 test_operator_index_set() {
4268 checkLibrary('class C { void operator[]=(int i, bool v) {} }');
4269 }
4270
4271 test_operator_less_equal() {
4272 checkLibrary('class C { bool operator<=(C other) => false; }');
4273 }
4274
4275 test_parameterTypeNotInferred_constructor() {
4276 // Strong mode doesn't do type inference on constructor parameters, so it's
4277 // ok that we don't store inferred type info for them in summaries.
4278 checkLibrary('''
4279 class C {
4280 C.positional([x = 1]);
4281 C.named({x: 1});
4282 }
4283 ''');
4284 }
4285
4286 test_parameterTypeNotInferred_initializingFormal() {
4287 // Strong mode doesn't do type inference on initializing formals, so it's
4288 // ok that we don't store inferred type info for them in summaries.
4289 checkLibrary('''
4290 class C {
4291 var x;
4292 C.positional([this.x = 1]);
4293 C.named({this.x: 1});
4294 }
4295 ''');
4296 }
4297
4298 test_parameterTypeNotInferred_staticMethod() {
4299 // Strong mode doesn't do type inference on parameters of static methods,
4300 // so it's ok that we don't store inferred type info for them in summaries.
4301 checkLibrary('''
4302 class C {
4303 static void positional([x = 1]) {}
4304 static void named({x: 1}) {}
4305 }
4306 ''');
4307 }
4308
4309 test_parameterTypeNotInferred_topLevelFunction() {
4310 // Strong mode doesn't do type inference on parameters of top level
4311 // functions, so it's ok that we don't store inferred type info for them in
4312 // summaries.
4313 checkLibrary('''
4314 void positional([x = 1]) {}
4315 void named({x: 1}) {}
4316 ''');
4317 }
4318
4319 test_parts() {
4320 addSource('/a.dart', 'part of my.lib;');
4321 addSource('/b.dart', 'part of my.lib;');
4322 checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
4323 }
4324
4325 test_propagated_type_refers_to_closure() {
4326 checkLibrary('''
4327 void f() {
4328 var x = () => 0;
4329 var y = x;
4330 }
4331 ''');
4332 }
4333
4334 test_setter_documented() {
4335 checkLibrary('''
4336 // Extra comment so doc comment offset != 0
4337 /**
4338 * Docs
4339 */
4340 void set x(value) {}''');
4341 }
4342
4343 test_setter_external() {
4344 checkLibrary('external void set x(int value);');
4345 }
4346
4347 test_setter_inferred_type_nonStatic_implicit_param() {
4348 checkLibrary('class C extends D { void set f(value) {} }'
4349 ' abstract class D { void set f(int value); }');
4350 }
4351
4352 test_setter_inferred_type_static_implicit_return() {
4353 checkLibrary('class C { static set f(int value) {} }');
4354 }
4355
4356 test_setter_inferred_type_top_level_implicit_return() {
4357 checkLibrary('set f(int value) {}');
4358 }
4359
4360 test_setters() {
4361 checkLibrary('void set x(int value) {} set y(value) {}');
4362 }
4363
4364 test_syntheticFunctionType_genericClosure() {
4365 if (!createOptions().strongMode) {
4366 // The test below uses generic comment syntax because proper generic
4367 // method syntax doesn't support generic closures. So it can only run in
4368 // strong mode.
4369 // TODO(paulberry): once proper generic method syntax supports generic
4370 // closures, rewrite the test below without using generic comment syntax,
4371 // and remove this hack. See dartbug.com/25819
4372 return;
4373 }
4374 checkLibrary('''
4375 final v = f() ? /*<T>*/(T t) => 0 : /*<T>*/(T t) => 1;
4376 bool f() => true;
4377 ''');
4378 }
4379
4380 test_syntheticFunctionType_genericClosure_inGenericFunction() {
4381 if (!createOptions().strongMode) {
4382 // The test below uses generic comment syntax because proper generic
4383 // method syntax doesn't support generic closures. So it can only run in
4384 // strong mode.
4385 // TODO(paulberry): once proper generic method syntax supports generic
4386 // closures, rewrite the test below without using generic comment syntax,
4387 // and remove this hack. See dartbug.com/25819
4388 return;
4389 }
4390 checkLibrary('''
4391 void f<T, U>(bool b) {
4392 final v = b ? /*<V>*/(T t, U u, V v) => 0 : /*<V>*/(T t, U u, V v) => 1;
4393 }
4394 ''');
4395 }
4396
4397 test_syntheticFunctionType_inGenericClass() {
4398 checkLibrary('''
4399 class C<T, U> {
4400 var v = f() ? (T t, U u) => 0 : (T t, U u) => 1;
4401 }
4402 bool f() => false;
4403 ''');
4404 }
4405
4406 test_syntheticFunctionType_inGenericFunction() {
4407 checkLibrary('''
4408 void f<T, U>(bool b) {
4409 var v = b ? (T t, U u) => 0 : (T t, U u) => 1;
4410 }
4411 ''');
4412 }
4413
4414 test_syntheticFunctionType_noArguments() {
4415 checkLibrary('''
4416 final v = f() ? () => 0 : () => 1;
4417 bool f() => true;
4418 ''');
4419 }
4420
4421 test_syntheticFunctionType_withArguments() {
4422 checkLibrary('''
4423 final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
4424 bool f() => true;
4425 ''');
4426 }
4427
4428 test_type_arguments_explicit_dynamic_dynamic() {
4429 checkLibrary('Map<dynamic, dynamic> m;');
4430 }
4431
4432 test_type_arguments_explicit_dynamic_int() {
4433 checkLibrary('Map<dynamic, int> m;');
4434 }
4435
4436 test_type_arguments_explicit_String_dynamic() {
4437 checkLibrary('Map<String, dynamic> m;');
4438 }
4439
4440 test_type_arguments_explicit_String_int() {
4441 checkLibrary('Map<String, int> m;');
4442 }
4443
4444 test_type_arguments_implicit() {
4445 checkLibrary('Map m;');
4446 }
4447
4448 test_type_dynamic() {
4449 checkLibrary('dynamic d;');
4450 }
4451
4452 test_type_reference_lib_to_lib() {
4453 checkLibrary('class C {} enum E { v } typedef F(); C c; E e; F f;');
4454 }
4455
4456 test_type_reference_lib_to_part() {
4457 addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
4458 checkLibrary('library l; part "a.dart"; C c; E e; F f;');
4459 }
4460
4461 test_type_reference_part_to_lib() {
4462 addSource('/a.dart', 'part of l; C c; E e; F f;');
4463 checkLibrary(
4464 'library l; part "a.dart"; class C {} enum E { v } typedef F();');
4465 }
4466
4467 test_type_reference_part_to_other_part() {
4468 addSource('/a.dart', 'part of l; class C {} enum E { v } typedef F();');
4469 addSource('/b.dart', 'part of l; C c; E e; F f;');
4470 checkLibrary('library l; part "a.dart"; part "b.dart";');
4471 }
4472
4473 test_type_reference_part_to_part() {
4474 addSource('/a.dart',
4475 'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;');
4476 checkLibrary('library l; part "a.dart";');
4477 }
4478
4479 test_type_reference_to_class() {
4480 checkLibrary('class C {} C c;');
4481 }
4482
4483 test_type_reference_to_class_with_type_arguments() {
4484 checkLibrary('class C<T, U> {} C<int, String> c;');
4485 }
4486
4487 test_type_reference_to_class_with_type_arguments_implicit() {
4488 checkLibrary('class C<T, U> {} C c;');
4489 }
4490
4491 test_type_reference_to_enum() {
4492 checkLibrary('enum E { v } E e;');
4493 }
4494
4495 test_type_reference_to_import() {
4496 addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();');
4497 checkLibrary('import "a.dart"; C c; E e; F f;');
4498 }
4499
4500 test_type_reference_to_import_export() {
4501 addLibrarySource('/a.dart', 'export "b.dart";');
4502 addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();');
4503 checkLibrary('import "a.dart"; C c; E e; F f;');
4504 }
4505
4506 test_type_reference_to_import_export_export() {
4507 addLibrarySource('/a.dart', 'export "b.dart";');
4508 addLibrarySource('/b.dart', 'export "c.dart";');
4509 addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();');
4510 checkLibrary('import "a.dart"; C c; E e; F f;');
4511 }
4512
4513 test_type_reference_to_import_export_export_in_subdirs() {
4514 addLibrarySource('/a/a.dart', 'export "b/b.dart";');
4515 addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";');
4516 addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();');
4517 checkLibrary('import "a/a.dart"; C c; E e; F f;');
4518 }
4519
4520 test_type_reference_to_import_export_in_subdirs() {
4521 addLibrarySource('/a/a.dart', 'export "b/b.dart";');
4522 addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();');
4523 checkLibrary('import "a/a.dart"; C c; E e; F f;');
4524 }
4525
4526 test_type_reference_to_import_part() {
4527 addLibrarySource('/a.dart', 'library l; part "b.dart";');
4528 addSource('/b.dart', 'part of l; class C {} enum E { v } typedef F();');
4529 checkLibrary('import "a.dart"; C c; E e; F f;');
4530 }
4531
4532 test_type_reference_to_import_part2() {
4533 addLibrarySource('/a.dart', 'library l; part "p1.dart"; part "p2.dart";');
4534 addSource('/p1.dart', 'part of l; class C1 {}');
4535 addSource('/p2.dart', 'part of l; class C2 {}');
4536 checkLibrary('import "a.dart"; C1 c1; C2 c2;');
4537 }
4538
4539 test_type_reference_to_import_part_in_subdir() {
4540 addLibrarySource('/a/b.dart', 'library l; part "c.dart";');
4541 addSource('/a/c.dart', 'part of l; class C {} enum E { v } typedef F();');
4542 checkLibrary('import "a/b.dart"; C c; E e; F f;');
4543 }
4544
4545 test_type_reference_to_import_relative() {
4546 addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();');
4547 checkLibrary('import "a.dart"; C c; E e; F f;');
4548 }
4549
4550 test_type_reference_to_typedef() {
4551 checkLibrary('typedef F(); F f;');
4552 }
4553
4554 test_type_reference_to_typedef_with_type_arguments() {
4555 checkLibrary('typedef U F<T, U>(T t); F<int, String> f;');
4556 }
4557
4558 test_type_reference_to_typedef_with_type_arguments_implicit() {
4559 checkLibrary('typedef U F<T, U>(T t); F f;');
4560 }
4561
4562 test_type_unresolved() {
4563 checkLibrary('C c;', allowErrors: true);
4564 }
4565
4566 test_type_unresolved_prefixed() {
4567 checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true);
4568 }
4569
4570 test_typedef_documented() {
4571 checkLibrary('''
4572 // Extra comment so doc comment offset != 0
4573 /**
4574 * Docs
4575 */
4576 typedef F();''');
4577 }
4578
4579 test_typedef_parameter_parameters() {
4580 checkLibrary('typedef F(g(x, y));');
4581 }
4582
4583 test_typedef_parameter_parameters_in_generic_class() {
4584 checkLibrary('typedef F<A, B>(A g(B x));');
4585 }
4586
4587 test_typedef_parameter_return_type() {
4588 checkLibrary('typedef F(int g());');
4589 }
4590
4591 test_typedef_parameter_type() {
4592 checkLibrary('typedef F(int i);');
4593 }
4594
4595 test_typedef_parameter_type_generic() {
4596 checkLibrary('typedef F<T>(T t);');
4597 }
4598
4599 test_typedef_parameters() {
4600 checkLibrary('typedef F(x, y);');
4601 }
4602
4603 test_typedef_return_type() {
4604 checkLibrary('typedef int F();');
4605 }
4606
4607 test_typedef_return_type_generic() {
4608 checkLibrary('typedef T F<T>();');
4609 }
4610
4611 test_typedef_return_type_implicit() {
4612 checkLibrary('typedef F();');
4613 }
4614
4615 test_typedef_return_type_void() {
4616 checkLibrary('typedef void F();');
4617 }
4618
4619 test_typedef_type_parameters() {
4620 checkLibrary('typedef U F<T, U>(T t);');
4621 }
4622
4623 test_typedef_type_parameters_bound() {
4624 checkLibrary('typedef U F<T extends Object, U extends D>(T t); class D {}');
4625 }
4626
4627 test_typedef_type_parameters_f_bound_complex() {
4628 checkLibrary('typedef U F<T extends List<U>, U>(T t);');
4629 }
4630
4631 test_typedef_type_parameters_f_bound_simple() {
4632 checkLibrary('typedef U F<T extends U, U>(T t);');
4633 }
4634
4635 test_typedefs() {
4636 checkLibrary('f() {} g() {}');
4637 }
4638
4639 test_unresolved_export() {
4640 allowMissingFiles = true;
4641 checkLibrary("export 'foo.dart';", allowErrors: true);
4642 }
4643
4644 test_unresolved_import() {
4645 allowMissingFiles = true;
4646 checkLibrary("import 'foo.dart';", allowErrors: true);
4647 }
4648
4649 test_unresolved_part() {
4650 allowMissingFiles = true;
4651 checkLibrary("part 'foo.dart';", allowErrors: true);
4652 }
4653
4654 test_unused_type_parameter() {
4655 checkLibrary('''
4656 class C<T> {
4657 void f() {}
4658 }
4659 C<int> c;
4660 var v = c.f;
4661 ''');
4662 }
4663
4664 test_variable_const() {
4665 checkLibrary('const int i = 0;');
4666 }
4667
4668 test_variable_documented() {
4669 checkLibrary('''
4670 // Extra comment so doc comment offset != 0
4671 /**
4672 * Docs
4673 */
4674 var x;''');
4675 }
4676
4677 test_variable_final() {
4678 checkLibrary('final int x = 0;');
4679 }
4680
4681 test_variable_final_top_level_untyped() {
4682 checkLibrary('final v = 0;');
4683 }
4684
4685 test_variable_getterInLib_setterInPart() {
4686 addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
4687 checkLibrary('library my.lib; part "a.dart"; int get x => 42;');
4688 }
4689
4690 test_variable_getterInPart_setterInLib() {
4691 addSource('/a.dart', 'part of my.lib; int get x => 42;');
4692 checkLibrary('library my.lib; part "a.dart"; void set x(int _) {}');
4693 }
4694
4695 test_variable_getterInPart_setterInPart() {
4696 addSource('/a.dart', 'part of my.lib; int get x => 42;');
4697 addSource('/b.dart', 'part of my.lib; void set x(int _) {}');
4698 checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
4699 }
4700
4701 test_variable_implicit_type() {
4702 checkLibrary('var x;');
4703 }
4704
4705 test_variable_inferred_type_implicit_initialized() {
4706 checkLibrary('var v = 0;');
4707 }
4708
4709 test_variable_propagatedType_const_noDep() {
4710 checkLibrary('const i = 0;');
4711 }
4712
4713 test_variable_propagatedType_final_dep_inLib() {
4714 addLibrarySource('/a.dart', 'final a = 1;');
4715 checkLibrary('import "a.dart"; final b = a / 2;');
4716 }
4717
4718 test_variable_propagatedType_final_dep_inPart() {
4719 addSource('/a.dart', 'part of lib; final a = 1;');
4720 checkLibrary('library lib; part "a.dart"; final b = a / 2;');
4721 }
4722
4723 test_variable_propagatedType_final_noDep() {
4724 checkLibrary('final i = 0;');
4725 }
4726
4727 test_variable_propagatedType_implicit_dep() {
4728 // The propagated type is defined in a library that is not imported.
4729 addLibrarySource('/a.dart', 'class C {}');
4730 addLibrarySource('/b.dart', 'import "a.dart"; C f() => null;');
4731 checkLibrary('import "b.dart"; final x = f();');
4732 }
4733
4734 test_variable_setterInPart_getterInPart() {
4735 addSource('/a.dart', 'part of my.lib; void set x(int _) {}');
4736 addSource('/b.dart', 'part of my.lib; int get x => 42;');
4737 checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
4738 }
4739
4740 test_variables() {
4741 checkLibrary('int i; int j;');
4742 }
4743
4744 /**
4745 * Encode the library containing [original] into a summary and then use
4746 * [TestSummaryResynthesizer.getElement] to retrieve just the original
4747 * element from the resynthesized summary.
4748 */
4749 Element validateGetElement(String text, Element original) {
4750 SummaryResynthesizer resynthesizer =
4751 encodeDecodeLibrarySource(original.library.source);
4752 ElementLocationImpl location = original.location;
4753 Element result = resynthesizer.getElement(location);
4754 checkMinimalResynthesisWork(resynthesizer, original.library);
4755 // Check that no other summaries needed to be resynthesized to resynthesize
4756 // the library element.
4757 expect(resynthesizer.resynthesisCount, 1);
4758 expect(result.location, location);
4759 return result;
4760 }
4761 }
4762
4763 class TestSummaryResynthesizer extends SummaryResynthesizer {
4764 final Map<String, UnlinkedUnit> unlinkedSummaries;
4765 final Map<String, LinkedLibrary> linkedSummaries;
4766 final bool allowMissingFiles;
4767
4768 /**
4769 * The set of uris for which unlinked summaries have been requested using
4770 * [getUnlinkedSummary].
4771 */
4772 final Set<String> unlinkedSummariesRequested = new Set<String>();
4773
4774 /**
4775 * The set of uris for which linked summaries have been requested using
4776 * [getLinkedSummary].
4777 */
4778 final Set<String> linkedSummariesRequested = new Set<String>();
4779
4780 TestSummaryResynthesizer(SummaryResynthesizer parent, AnalysisContext context,
4781 this.unlinkedSummaries, this.linkedSummaries, this.allowMissingFiles)
4782 : super(parent, context, context.typeProvider, context.sourceFactory,
4783 context.analysisOptions.strongMode);
4784
4785 @override
4786 LinkedLibrary getLinkedSummary(String uri) {
4787 linkedSummariesRequested.add(uri);
4788 LinkedLibrary serializedLibrary = linkedSummaries[uri];
4789 if (serializedLibrary == null && !allowMissingFiles) {
4790 fail('Unexpectedly tried to get linked summary for $uri');
4791 }
4792 return serializedLibrary;
4793 }
4794
4795 @override
4796 UnlinkedUnit getUnlinkedSummary(String uri) {
4797 unlinkedSummariesRequested.add(uri);
4798 UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
4799 if (serializedUnit == null && !allowMissingFiles) {
4800 fail('Unexpectedly tried to get unlinked summary for $uri');
4801 }
4802 return serializedUnit;
4803 }
4804
4805 @override
4806 bool hasLibrarySummary(String uri) {
4807 return true;
4808 }
4809 }
OLDNEW
« no previous file with comments | « pkg/analyzer/test/src/summary/resynthesize_strong_test.dart ('k') | pkg/analyzer/test/src/summary/summarize_ast_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698