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