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/src/generated/element.dart'; |
| 8 import 'package:analyzer/src/generated/source.dart'; |
| 9 import 'package:analyzer/src/summary/builder.dart'; |
| 10 import 'package:analyzer/src/summary/format.dart'; |
| 11 import 'package:analyzer/src/summary/resynthesize.dart'; |
| 12 import 'package:analyzer/src/summary/summarize_elements.dart'; |
| 13 import 'package:unittest/unittest.dart'; |
| 14 |
| 15 import '../../generated/resolver_test.dart'; |
| 16 import '../../reflective_tests.dart'; |
| 17 |
| 18 main() { |
| 19 groupSep = ' | '; |
| 20 runReflectiveTests(ResynthTest); |
| 21 } |
| 22 |
| 23 @reflectiveTest |
| 24 class ResynthTest extends ResolverTestCase { |
| 25 Set<Source> otherLibrarySources = new Set<Source>(); |
| 26 |
| 27 void addLibrary(String uri) { |
| 28 otherLibrarySources.add(analysisContext2.sourceFactory.forUri(uri)); |
| 29 } |
| 30 |
| 31 void addLibrarySource(String filePath, String contents) { |
| 32 otherLibrarySources.add(addNamedSource(filePath, contents)); |
| 33 } |
| 34 |
| 35 void checkLibrary(String text, {bool allowErrors: false}) { |
| 36 Source source = addSource(text); |
| 37 LibraryElementImpl original = resolve2(source); |
| 38 LibraryElementImpl resynthesized = |
| 39 resynthesizeLibrary(source, original, allowErrors); |
| 40 checkLibraryElements(original, resynthesized); |
| 41 } |
| 42 |
| 43 void checkLibraryElements( |
| 44 LibraryElementImpl original, LibraryElementImpl resynthesized) { |
| 45 compareElements(resynthesized, original, '(library)'); |
| 46 expect(resynthesized.displayName, original.displayName); |
| 47 expect(original.enclosingElement, isNull); |
| 48 expect(resynthesized.enclosingElement, isNull); |
| 49 compareCompilationUnitElements(resynthesized.definingCompilationUnit, |
| 50 original.definingCompilationUnit); |
| 51 expect(resynthesized.parts.length, original.parts.length); |
| 52 for (int i = 0; i < resynthesized.parts.length; i++) { |
| 53 compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]); |
| 54 } |
| 55 expect(resynthesized.imports.length, original.imports.length); |
| 56 for (int i = 0; i < resynthesized.imports.length; i++) { |
| 57 compareImportElements(resynthesized.imports[i], original.imports[i], |
| 58 'import ${original.imports[i].name}'); |
| 59 } |
| 60 expect(resynthesized.exports.length, original.exports.length); |
| 61 for (int i = 0; i < resynthesized.exports.length; i++) { |
| 62 compareExportElements(resynthesized.exports[i], original.exports[i], |
| 63 'export ${original.exports[i].name}'); |
| 64 } |
| 65 // TODO(paulberry): test entryPoint, exportNamespace, publicNamespace, |
| 66 // and metadata. |
| 67 } |
| 68 |
| 69 void compareClassElements( |
| 70 ClassElementImpl resynthesized, ClassElementImpl original, String desc) { |
| 71 compareElements(resynthesized, original, desc); |
| 72 expect(resynthesized.fields.length, original.fields.length); |
| 73 for (int i = 0; i < resynthesized.fields.length; i++) { |
| 74 String name = original.fields[i].name; |
| 75 compareFieldElements( |
| 76 resynthesized.getField(name), original.fields[i], '$desc.$name'); |
| 77 } |
| 78 compareTypes( |
| 79 resynthesized.supertype, original.supertype, '$desc supertype'); |
| 80 expect(resynthesized.interfaces.length, original.interfaces.length); |
| 81 for (int i = 0; i < resynthesized.interfaces.length; i++) { |
| 82 compareTypes(resynthesized.interfaces[i], original.interfaces[i], |
| 83 '$desc interface ${original.interfaces[i].name}'); |
| 84 } |
| 85 expect(resynthesized.mixins.length, original.mixins.length); |
| 86 for (int i = 0; i < resynthesized.mixins.length; i++) { |
| 87 compareTypes(resynthesized.mixins[i], original.mixins[i], |
| 88 '$desc mixin ${original.mixins[i].name}'); |
| 89 } |
| 90 expect(resynthesized.typeParameters.length, original.typeParameters.length); |
| 91 for (int i = 0; i < resynthesized.typeParameters.length; i++) { |
| 92 compareTypeParameterElements( |
| 93 resynthesized.typeParameters[i], |
| 94 original.typeParameters[i], |
| 95 '$desc type parameter ${original.typeParameters[i].name}'); |
| 96 } |
| 97 expect(resynthesized.constructors.length, original.constructors.length, |
| 98 reason: '$desc constructors.length'); |
| 99 for (int i = 0; i < resynthesized.constructors.length; i++) { |
| 100 compareConstructorElements( |
| 101 resynthesized.constructors[i], |
| 102 original.constructors[i], |
| 103 '$desc constructor ${original.constructors[i].name}'); |
| 104 } |
| 105 expect(resynthesized.accessors.length, original.accessors.length); |
| 106 for (int i = 0; i < resynthesized.accessors.length; i++) { |
| 107 String name = original.accessors[i].name; |
| 108 if (name.endsWith('=')) { |
| 109 comparePropertyAccessorElements(resynthesized.getSetter(name), |
| 110 original.accessors[i], '$desc.${original.accessors[i].name}='); |
| 111 } else { |
| 112 comparePropertyAccessorElements(resynthesized.getGetter(name), |
| 113 original.accessors[i], '$desc.${original.accessors[i].name}'); |
| 114 } |
| 115 } |
| 116 expect(resynthesized.methods.length, original.methods.length); |
| 117 for (int i = 0; i < resynthesized.methods.length; i++) { |
| 118 compareMethodElements(resynthesized.methods[i], original.methods[i], |
| 119 '$desc.${original.methods[i].name}'); |
| 120 } |
| 121 compareTypes(resynthesized.type, original.type, desc); |
| 122 } |
| 123 |
| 124 void compareCompilationUnitElements(CompilationUnitElementImpl resynthesized, |
| 125 CompilationUnitElementImpl original) { |
| 126 compareUriReferencedElements(resynthesized, original, '(compilation unit)'); |
| 127 expect(resynthesized.source, original.source); |
| 128 expect(resynthesized.librarySource, original.librarySource); |
| 129 expect(resynthesized.types.length, original.types.length); |
| 130 for (int i = 0; i < resynthesized.types.length; i++) { |
| 131 compareClassElements( |
| 132 resynthesized.types[i], original.types[i], original.types[i].name); |
| 133 } |
| 134 expect(resynthesized.topLevelVariables.length, |
| 135 original.topLevelVariables.length); |
| 136 for (int i = 0; i < resynthesized.topLevelVariables.length; i++) { |
| 137 compareTopLevelVariableElements(resynthesized.topLevelVariables[i], |
| 138 original.topLevelVariables[i], original.topLevelVariables[i].name); |
| 139 } |
| 140 expect(resynthesized.functions.length, original.functions.length); |
| 141 for (int i = 0; i < resynthesized.functions.length; i++) { |
| 142 compareFunctionElements(resynthesized.functions[i], original.functions[i], |
| 143 original.functions[i].name); |
| 144 } |
| 145 expect(resynthesized.functionTypeAliases.length, |
| 146 original.functionTypeAliases.length); |
| 147 for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) { |
| 148 compareFunctionTypeAliasElements( |
| 149 resynthesized.functionTypeAliases[i], |
| 150 original.functionTypeAliases[i], |
| 151 original.functionTypeAliases[i].name); |
| 152 } |
| 153 expect(resynthesized.enums.length, original.enums.length); |
| 154 for (int i = 0; i < resynthesized.enums.length; i++) { |
| 155 compareClassElements( |
| 156 resynthesized.enums[i], original.enums[i], original.enums[i].name); |
| 157 } |
| 158 expect(resynthesized.accessors.length, original.accessors.length); |
| 159 for (int i = 0; i < resynthesized.accessors.length; i++) { |
| 160 comparePropertyAccessorElements(resynthesized.accessors[i], |
| 161 original.accessors[i], original.accessors[i].name); |
| 162 } |
| 163 // TODO(paulberry): test metadata and offsetToElementMap. |
| 164 } |
| 165 |
| 166 void compareConstructorElements(ConstructorElementImpl resynthesized, |
| 167 ConstructorElementImpl original, String desc) { |
| 168 compareExecutableElements(resynthesized, original, desc); |
| 169 // TODO(paulberry): test redirectedConstructor and constantInitializers |
| 170 } |
| 171 |
| 172 void compareElements( |
| 173 ElementImpl resynthesized, ElementImpl original, String desc) { |
| 174 expect(resynthesized, isNotNull); |
| 175 expect(resynthesized.kind, original.kind); |
| 176 expect(resynthesized.location, original.location); |
| 177 expect(resynthesized.name, original.name); |
| 178 for (Modifier modifier in Modifier.values) { |
| 179 if (modifier == Modifier.MIXIN) { |
| 180 // Skipping for now. TODO(paulberry): fix. |
| 181 continue; |
| 182 } |
| 183 bool got = resynthesized.hasModifier(modifier); |
| 184 bool want = original.hasModifier(modifier); |
| 185 expect(got, want, |
| 186 reason: 'Mismatch in $desc.$modifier: got $got, want $want'); |
| 187 } |
| 188 } |
| 189 |
| 190 void compareExecutableElements(ExecutableElementImpl resynthesized, |
| 191 ExecutableElementImpl original, String desc) { |
| 192 compareElements(resynthesized, original, desc); |
| 193 expect(resynthesized.parameters.length, original.parameters.length); |
| 194 for (int i = 0; i < resynthesized.parameters.length; i++) { |
| 195 compareParameterElements( |
| 196 resynthesized.parameters[i], |
| 197 original.parameters[i], |
| 198 '$desc parameter ${original.parameters[i].name}'); |
| 199 } |
| 200 compareTypes( |
| 201 resynthesized.returnType, original.returnType, '$desc return type'); |
| 202 compareTypes(resynthesized.type, original.type, desc); |
| 203 } |
| 204 |
| 205 void compareExportElements(ExportElementImpl resynthesized, |
| 206 ExportElementImpl original, String desc) { |
| 207 compareUriReferencedElements(resynthesized, original, desc); |
| 208 expect(resynthesized.exportedLibrary.location, |
| 209 original.exportedLibrary.location); |
| 210 expect(resynthesized.combinators.length, original.combinators.length); |
| 211 for (int i = 0; i < resynthesized.combinators.length; i++) { |
| 212 compareNamespaceCombinators( |
| 213 resynthesized.combinators[i], original.combinators[i]); |
| 214 } |
| 215 } |
| 216 |
| 217 void compareFieldElements( |
| 218 FieldElementImpl resynthesized, FieldElementImpl original, String desc) { |
| 219 comparePropertyInducingElements(resynthesized, original, desc); |
| 220 // TODO(paulberry): test evaluationResult |
| 221 } |
| 222 |
| 223 void compareFunctionElements(FunctionElementImpl resynthesized, |
| 224 FunctionElementImpl original, String desc) { |
| 225 compareExecutableElements(resynthesized, original, desc); |
| 226 } |
| 227 |
| 228 void compareFunctionTypeAliasElements( |
| 229 FunctionTypeAliasElementImpl resynthesized, |
| 230 FunctionTypeAliasElementImpl original, |
| 231 String desc) { |
| 232 compareElements(resynthesized, original, desc); |
| 233 expect(resynthesized.parameters.length, original.parameters.length); |
| 234 for (int i = 0; i < resynthesized.parameters.length; i++) { |
| 235 compareParameterElements( |
| 236 resynthesized.parameters[i], |
| 237 original.parameters[i], |
| 238 '$desc parameter ${original.parameters[i].name}'); |
| 239 } |
| 240 compareTypes( |
| 241 resynthesized.returnType, original.returnType, '$desc return type'); |
| 242 compareTypes(resynthesized.type, original.type, desc); |
| 243 expect(resynthesized.typeParameters.length, original.typeParameters.length); |
| 244 for (int i = 0; i < resynthesized.typeParameters.length; i++) { |
| 245 compareTypeParameterElements( |
| 246 resynthesized.typeParameters[i], |
| 247 original.typeParameters[i], |
| 248 '$desc type parameter ${original.typeParameters[i].name}'); |
| 249 } |
| 250 } |
| 251 |
| 252 void compareImportElements(ImportElementImpl resynthesized, |
| 253 ImportElementImpl original, String desc) { |
| 254 compareUriReferencedElements(resynthesized, original, desc); |
| 255 expect(resynthesized.importedLibrary.location, |
| 256 original.importedLibrary.location); |
| 257 if (original.prefix == null) { |
| 258 expect(resynthesized.prefix, isNull); |
| 259 } else { |
| 260 comparePrefixElements( |
| 261 resynthesized.prefix, original.prefix, original.prefix.name); |
| 262 } |
| 263 expect(resynthesized.combinators.length, original.combinators.length); |
| 264 for (int i = 0; i < resynthesized.combinators.length; i++) { |
| 265 compareNamespaceCombinators( |
| 266 resynthesized.combinators[i], original.combinators[i]); |
| 267 } |
| 268 } |
| 269 |
| 270 void compareMethodElements(MethodElementImpl resynthesized, |
| 271 MethodElementImpl original, String desc) { |
| 272 // TODO(paulberry): do we need to deal with |
| 273 // MultiplyInheritedMethodElementImpl? |
| 274 // TODO(paulberry): compare type parameters for generic methods. |
| 275 compareExecutableElements(resynthesized, original, desc); |
| 276 } |
| 277 |
| 278 void compareNamespaceCombinators( |
| 279 NamespaceCombinator resynthesized, NamespaceCombinator original) { |
| 280 if (original is ShowElementCombinatorImpl && |
| 281 resynthesized is ShowElementCombinatorImpl) { |
| 282 expect(resynthesized.shownNames, original.shownNames); |
| 283 } else if (original is HideElementCombinatorImpl && |
| 284 resynthesized is HideElementCombinatorImpl) { |
| 285 expect(resynthesized.hiddenNames, original.hiddenNames); |
| 286 } else if (resynthesized.runtimeType != original.runtimeType) { |
| 287 fail( |
| 288 'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.
runtimeType}'); |
| 289 } else { |
| 290 fail('Unimplemented comparison for ${original.runtimeType}'); |
| 291 } |
| 292 } |
| 293 |
| 294 void compareParameterElements(ParameterElementImpl resynthesized, |
| 295 ParameterElementImpl original, String desc) { |
| 296 compareVariableElements(resynthesized, original, desc); |
| 297 expect(resynthesized.parameters.length, original.parameters.length); |
| 298 for (int i = 0; i < resynthesized.parameters.length; i++) { |
| 299 compareParameterElements( |
| 300 resynthesized.parameters[i], |
| 301 original.parameters[i], |
| 302 '$desc parameter ${original.parameters[i].name}'); |
| 303 } |
| 304 expect(resynthesized.parameterKind, original.parameterKind); |
| 305 } |
| 306 |
| 307 void comparePrefixElements(PrefixElementImpl resynthesized, |
| 308 PrefixElementImpl original, String desc) { |
| 309 compareElements(resynthesized, original, desc); |
| 310 // TODO(paulberry): test _importedLibraries. |
| 311 } |
| 312 |
| 313 void comparePropertyAccessorElements( |
| 314 PropertyAccessorElementImpl resynthesized, |
| 315 PropertyAccessorElementImpl original, |
| 316 String desc) { |
| 317 // TODO(paulberry): do I need to worry about |
| 318 // MultiplyInheritedPropertyAccessorElementImpl? |
| 319 compareExecutableElements(resynthesized, original, desc); |
| 320 expect(resynthesized.variable, isNotNull); |
| 321 expect(resynthesized.variable.location, original.variable.location); |
| 322 } |
| 323 |
| 324 void comparePropertyInducingElements( |
| 325 PropertyInducingElementImpl resynthesized, |
| 326 PropertyInducingElementImpl original, |
| 327 String desc) { |
| 328 compareVariableElements(resynthesized, original, desc); |
| 329 if (original.getter == null) { |
| 330 expect(resynthesized.getter, isNull); |
| 331 } else { |
| 332 expect(resynthesized.getter, isNotNull); |
| 333 expect(resynthesized.getter.location, original.getter.location); |
| 334 } |
| 335 if (original.setter == null) { |
| 336 expect(resynthesized.setter, isNull); |
| 337 } else { |
| 338 expect(resynthesized.setter, isNotNull); |
| 339 expect(resynthesized.setter.location, original.setter.location); |
| 340 } |
| 341 } |
| 342 |
| 343 void compareTopLevelVariableElements( |
| 344 TopLevelVariableElementImpl resynthesized, |
| 345 TopLevelVariableElementImpl original, |
| 346 String desc) { |
| 347 comparePropertyInducingElements(resynthesized, original, desc); |
| 348 // TODO(paulberry): test evaluationResult |
| 349 } |
| 350 |
| 351 void compareTypeImpls(TypeImpl resynthesized, TypeImpl original) { |
| 352 expect(resynthesized.element.location, original.element.location); |
| 353 expect(resynthesized.name, original.name); |
| 354 } |
| 355 |
| 356 void compareTypeParameterElements(TypeParameterElementImpl resynthesized, |
| 357 TypeParameterElementImpl original, String desc) { |
| 358 compareElements(resynthesized, original, desc); |
| 359 compareTypes(resynthesized.type, original.type, desc); |
| 360 compareTypes(resynthesized.bound, original.bound, '$desc bound'); |
| 361 } |
| 362 |
| 363 void compareTypes(DartType resynthesized, DartType original, String desc) { |
| 364 if (original == null) { |
| 365 expect(resynthesized, isNull); |
| 366 } else if (resynthesized is InterfaceTypeImpl && |
| 367 original is InterfaceTypeImpl) { |
| 368 compareTypeImpls(resynthesized, original); |
| 369 expect(resynthesized.typeArguments.length, original.typeArguments.length); |
| 370 for (int i = 0; i < resynthesized.typeArguments.length; i++) { |
| 371 compareTypes(resynthesized.typeArguments[i], original.typeArguments[i], |
| 372 '$desc type argument ${original.typeArguments[i].name}'); |
| 373 } |
| 374 } else if (resynthesized is TypeParameterTypeImpl && |
| 375 original is TypeParameterTypeImpl) { |
| 376 compareTypeImpls(resynthesized, original); |
| 377 } else if (resynthesized is DynamicTypeImpl && |
| 378 original is DynamicTypeImpl) { |
| 379 expect(resynthesized, same(original)); |
| 380 } else if (resynthesized is UndefinedTypeImpl && |
| 381 original is UndefinedTypeImpl) { |
| 382 expect(resynthesized, same(original)); |
| 383 } else if (resynthesized is FunctionTypeImpl && |
| 384 original is FunctionTypeImpl) { |
| 385 compareTypeImpls(resynthesized, original); |
| 386 if (original.element.isSynthetic && |
| 387 original.element is FunctionTypeAliasElementImpl && |
| 388 resynthesized.element is FunctionTypeAliasElementImpl) { |
| 389 compareFunctionTypeAliasElements( |
| 390 resynthesized.element, original.element, desc); |
| 391 } |
| 392 for (int i = 0; i < resynthesized.typeArguments.length; i++) { |
| 393 compareTypes(resynthesized.typeArguments[i], original.typeArguments[i], |
| 394 '$desc type argument ${original.typeArguments[i].name}'); |
| 395 } |
| 396 } else if (resynthesized is VoidTypeImpl && original is VoidTypeImpl) { |
| 397 expect(resynthesized, same(original)); |
| 398 } else if (resynthesized.runtimeType != original.runtimeType) { |
| 399 fail( |
| 400 'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.
runtimeType}'); |
| 401 } else { |
| 402 fail('Unimplemented comparison for ${original.runtimeType}'); |
| 403 } |
| 404 } |
| 405 |
| 406 void compareUriReferencedElements(UriReferencedElementImpl resynthesized, |
| 407 UriReferencedElementImpl original, String desc) { |
| 408 compareElements(resynthesized, original, desc); |
| 409 expect(resynthesized.uri, original.uri); |
| 410 } |
| 411 |
| 412 void compareVariableElements(VariableElementImpl resynthesized, |
| 413 VariableElementImpl original, String desc) { |
| 414 compareElements(resynthesized, original, desc); |
| 415 compareTypes(resynthesized.type, original.type, desc); |
| 416 // TODO(paulberry): test initializer |
| 417 } |
| 418 |
| 419 fail_core() { |
| 420 // TODO(paulberry): figure out why this test is failing. It's possible |
| 421 // some of the elements in the core library fail to resynthesize properly |
| 422 // because of flaws in the mock SDK; it's also possible that there are bugs |
| 423 // in the summary logic which are not caught by other tests. |
| 424 String uri = 'dart:core'; |
| 425 LibraryElementImpl original = |
| 426 resolve2(analysisContext2.sourceFactory.forUri(uri)); |
| 427 LibraryElementImpl resynthesized = |
| 428 resynthesizeLibraryElement(uri, original); |
| 429 checkLibraryElements(original, resynthesized); |
| 430 } |
| 431 |
| 432 PrelinkedLibrary getSummaryFor(LibraryElement lib) { |
| 433 BuilderContext ctx = new BuilderContext(); |
| 434 List<int> summary = serializeLibrary(ctx, lib, typeProvider).toBuffer(); |
| 435 return new PrelinkedLibrary.fromBuffer(summary); |
| 436 } |
| 437 |
| 438 LibraryElementImpl resynthesizeLibrary( |
| 439 Source source, LibraryElementImpl original, bool allowErrors) { |
| 440 if (!allowErrors) { |
| 441 assertNoErrors(source); |
| 442 } |
| 443 String uri = source.uri.toString(); |
| 444 addLibrary('dart:core'); |
| 445 return resynthesizeLibraryElement(uri, original); |
| 446 } |
| 447 |
| 448 LibraryElementImpl resynthesizeLibraryElement( |
| 449 String uri, LibraryElementImpl original) { |
| 450 Map<String, PrelinkedLibrary> summaries = <String, PrelinkedLibrary>{ |
| 451 uri: getSummaryFor(original) |
| 452 }; |
| 453 for (Source source in otherLibrarySources) { |
| 454 LibraryElement original = resolve2(source); |
| 455 String uri = source.uri.toString(); |
| 456 summaries[uri] = getSummaryFor(original); |
| 457 } |
| 458 PrelinkedLibrary getSummary(String uri) { |
| 459 PrelinkedLibrary serializedLibrary = summaries[uri]; |
| 460 if (serializedLibrary == null) { |
| 461 fail('Unexpectedly tried to get serialized library for $uri'); |
| 462 } |
| 463 return serializedLibrary; |
| 464 } |
| 465 SummaryResynthesizer resynthesizer = new SummaryResynthesizer( |
| 466 analysisContext, getSummary, analysisContext.sourceFactory); |
| 467 LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri); |
| 468 // Check that no other summaries needed to be resynthesized to resynthesize |
| 469 // the library element. |
| 470 expect(resynthesizer.resynthesisCount, 1); |
| 471 return resynthesized; |
| 472 } |
| 473 |
| 474 test_class_alias() { |
| 475 checkLibrary('class C = D with E, F; class D {} class E {} class F {}'); |
| 476 } |
| 477 |
| 478 test_class_alias_with_forwarding_constructors() { |
| 479 addLibrarySource( |
| 480 '/a.dart', |
| 481 ''' |
| 482 class Base { |
| 483 Base._priv(); |
| 484 Base(); |
| 485 Base.noArgs(); |
| 486 Base.requiredArg(x); |
| 487 Base.positionalArg([x]); |
| 488 Base.namedArg({x}); |
| 489 factory Base.fact() => null; |
| 490 factory Base.fact2() = Base.noArgs; |
| 491 } |
| 492 '''); |
| 493 checkLibrary(''' |
| 494 import "a.dart"; |
| 495 class M {} |
| 496 class MixinApp = Base with M; |
| 497 '''); |
| 498 } |
| 499 |
| 500 test_class_alias_with_forwarding_constructors_type_substitution() { |
| 501 checkLibrary(''' |
| 502 class Base<T> { |
| 503 Base.ctor(T t, List<T> l); |
| 504 } |
| 505 class M {} |
| 506 class MixinApp = Base with M; |
| 507 '''); |
| 508 } |
| 509 |
| 510 test_class_alias_with_forwarding_constructors_type_substitution_complex() { |
| 511 checkLibrary(''' |
| 512 class Base<T> { |
| 513 Base.ctor(T t, List<T> l); |
| 514 } |
| 515 class M {} |
| 516 class MixinApp<U> = Base<List<U>> with M; |
| 517 '''); |
| 518 } |
| 519 |
| 520 test_class_alias_with_mixin_members() { |
| 521 checkLibrary(''' |
| 522 class C = D with E; |
| 523 class D {} |
| 524 class E { |
| 525 int get a => null; |
| 526 void set b(int i) {} |
| 527 void f() {} |
| 528 int x; |
| 529 }'''); |
| 530 } |
| 531 |
| 532 test_class_constructor_const() { |
| 533 checkLibrary('class C { const C(); }'); |
| 534 } |
| 535 |
| 536 test_class_constructor_explicit_named() { |
| 537 checkLibrary('class C { C.foo(); }'); |
| 538 } |
| 539 |
| 540 test_class_constructor_explicit_type_params() { |
| 541 checkLibrary('class C<T, U> { C(); }'); |
| 542 } |
| 543 |
| 544 test_class_constructor_explicit_unnamed() { |
| 545 checkLibrary('class C { C(); }'); |
| 546 } |
| 547 |
| 548 test_class_constructor_factory() { |
| 549 checkLibrary('class C { factory C() => null; }'); |
| 550 } |
| 551 |
| 552 test_class_constructor_implicit() { |
| 553 checkLibrary('class C {}'); |
| 554 } |
| 555 |
| 556 test_class_constructor_implicit_type_params() { |
| 557 checkLibrary('class C<T, U> {}'); |
| 558 } |
| 559 |
| 560 test_class_constructor_params() { |
| 561 checkLibrary('class C { C(x, y); }'); |
| 562 } |
| 563 |
| 564 test_class_constructors() { |
| 565 checkLibrary('class C { C.foo(); C.bar(); }'); |
| 566 } |
| 567 |
| 568 test_class_field_const() { |
| 569 checkLibrary('class C { static const int i = 0; }'); |
| 570 } |
| 571 |
| 572 test_class_field_static() { |
| 573 checkLibrary('class C { static int i; }'); |
| 574 } |
| 575 |
| 576 test_class_fields() { |
| 577 checkLibrary('class C { int i; int j; }'); |
| 578 } |
| 579 |
| 580 test_class_getter_static() { |
| 581 checkLibrary('class C { static int get x => null; }'); |
| 582 } |
| 583 |
| 584 test_class_getters() { |
| 585 checkLibrary('class C { int get x => null; get y => null; }'); |
| 586 } |
| 587 |
| 588 test_class_interfaces() { |
| 589 checkLibrary('class C implements D, E {} class D {} class E {}'); |
| 590 } |
| 591 |
| 592 test_class_method_params() { |
| 593 checkLibrary('class C { f(x, y) {} }'); |
| 594 } |
| 595 |
| 596 test_class_method_static() { |
| 597 checkLibrary('class C { static f() {} }'); |
| 598 } |
| 599 |
| 600 test_class_methods() { |
| 601 checkLibrary('class C { f() {} g() {} }'); |
| 602 } |
| 603 |
| 604 test_class_mixins() { |
| 605 checkLibrary('class C extends Object with D, E {} class D {} class E {}'); |
| 606 } |
| 607 |
| 608 test_class_setter_static() { |
| 609 checkLibrary('class C { static void set x(int value) {} }'); |
| 610 } |
| 611 |
| 612 test_class_setters() { |
| 613 checkLibrary('class C { void set x(int value) {} set y(value) {} }'); |
| 614 } |
| 615 |
| 616 test_class_supertype() { |
| 617 checkLibrary('class C extends D {} class D {}'); |
| 618 } |
| 619 |
| 620 test_class_type_parameters() { |
| 621 checkLibrary('class C<T, U> {}'); |
| 622 } |
| 623 |
| 624 test_class_type_parameters_bound() { |
| 625 checkLibrary('class C<T extends Object, U extends D> {} class D {}'); |
| 626 } |
| 627 |
| 628 test_class_type_parameters_f_bound_complex() { |
| 629 checkLibrary('class C<T extends List<U>, U> {}'); |
| 630 } |
| 631 |
| 632 test_class_type_parameters_f_bound_simple() { |
| 633 checkLibrary('class C<T extends U, U> {}'); |
| 634 } |
| 635 |
| 636 test_classes() { |
| 637 checkLibrary('class C {} class D {}'); |
| 638 } |
| 639 |
| 640 test_enum_values() { |
| 641 checkLibrary('enum E { v1, v2 }'); |
| 642 } |
| 643 |
| 644 test_enums() { |
| 645 checkLibrary('enum E1 { v1 } enum E2 { v2 }'); |
| 646 } |
| 647 |
| 648 test_export_hide() { |
| 649 addLibrary('dart:async'); |
| 650 checkLibrary('export "dart:async" hide Stream, Future;'); |
| 651 } |
| 652 |
| 653 test_export_multiple_combinators() { |
| 654 addLibrary('dart:async'); |
| 655 checkLibrary('export "dart:async" hide Stream show Future;'); |
| 656 } |
| 657 |
| 658 test_export_show() { |
| 659 addLibrary('dart:async'); |
| 660 checkLibrary('export "dart:async" show Future, Stream;'); |
| 661 } |
| 662 |
| 663 test_exports() { |
| 664 addLibrarySource('/a.dart', 'library a;'); |
| 665 addLibrarySource('/b.dart', 'library b;'); |
| 666 checkLibrary('export "a.dart"; export "b.dart";'); |
| 667 } |
| 668 |
| 669 test_function_parameter_kind_named() { |
| 670 // TODO(paulberry): also test default value. |
| 671 checkLibrary('f({x}) {}'); |
| 672 } |
| 673 |
| 674 test_function_parameter_kind_positional() { |
| 675 // TODO(paulberry): also test default value. |
| 676 checkLibrary('f([x]) {}'); |
| 677 } |
| 678 |
| 679 test_function_parameter_kind_required() { |
| 680 checkLibrary('f(x) {}'); |
| 681 } |
| 682 |
| 683 test_function_parameter_parameters() { |
| 684 checkLibrary('f(g(x, y)) {}'); |
| 685 } |
| 686 |
| 687 test_function_parameter_return_type() { |
| 688 checkLibrary('f(int g()) {}'); |
| 689 } |
| 690 |
| 691 test_function_parameter_return_type_void() { |
| 692 checkLibrary('f(void g()) {}'); |
| 693 } |
| 694 |
| 695 test_function_parameter_type() { |
| 696 checkLibrary('f(int i) {}'); |
| 697 } |
| 698 |
| 699 test_function_parameters() { |
| 700 checkLibrary('f(x, y) {}'); |
| 701 } |
| 702 |
| 703 test_function_return_type() { |
| 704 checkLibrary('int f() => null;'); |
| 705 } |
| 706 |
| 707 test_function_return_type_implicit() { |
| 708 checkLibrary('f() => null;'); |
| 709 } |
| 710 |
| 711 test_function_return_type_void() { |
| 712 checkLibrary('void f() {}'); |
| 713 } |
| 714 |
| 715 test_functions() { |
| 716 checkLibrary('f() {} g() {}'); |
| 717 } |
| 718 |
| 719 test_getters() { |
| 720 checkLibrary('int get x => null; get y => null;'); |
| 721 } |
| 722 |
| 723 test_import_hide() { |
| 724 addLibrary('dart:async'); |
| 725 checkLibrary('import "dart:async" hide Stream, Completer; Future f;'); |
| 726 } |
| 727 |
| 728 test_import_multiple_combinators() { |
| 729 addLibrary('dart:async'); |
| 730 checkLibrary('import "dart:async" hide Stream show Future; Future f;'); |
| 731 } |
| 732 |
| 733 test_import_prefixed() { |
| 734 addLibrarySource('/a.dart', 'library a; class C {}'); |
| 735 checkLibrary('import "a.dart" as a; a.C c;'); |
| 736 } |
| 737 |
| 738 test_import_show() { |
| 739 addLibrary('dart:async'); |
| 740 checkLibrary('import "dart:async" show Future, Stream; Future f;'); |
| 741 } |
| 742 |
| 743 test_imports() { |
| 744 addLibrarySource('/a.dart', 'library a; class C {}'); |
| 745 addLibrarySource('/b.dart', 'library b; class D {}'); |
| 746 checkLibrary('import "a.dart"; import "b.dart"; C c; D d;'); |
| 747 } |
| 748 |
| 749 test_library() { |
| 750 checkLibrary(''); |
| 751 } |
| 752 |
| 753 test_library_named() { |
| 754 checkLibrary('library foo.bar;'); |
| 755 } |
| 756 |
| 757 test_method_parameter_parameters() { |
| 758 checkLibrary('class C { f(g(x, y)) {} }'); |
| 759 } |
| 760 |
| 761 test_method_parameter_return_type() { |
| 762 checkLibrary('class C { f(int g()) {} }'); |
| 763 } |
| 764 |
| 765 test_method_parameter_return_type_void() { |
| 766 checkLibrary('class C { f(void g()) {} }'); |
| 767 } |
| 768 |
| 769 test_parts() { |
| 770 addNamedSource('/a.dart', 'part of my.lib;'); |
| 771 addNamedSource('/b.dart', 'part of my.lib;'); |
| 772 checkLibrary('library my.lib; part "a.dart"; part "b.dart";'); |
| 773 } |
| 774 |
| 775 test_setters() { |
| 776 checkLibrary('void set x(int value) {} set y(value) {}'); |
| 777 } |
| 778 |
| 779 test_type_arguments_explicit() { |
| 780 checkLibrary('Map<String, int> m;'); |
| 781 } |
| 782 |
| 783 test_type_arguments_implicit() { |
| 784 checkLibrary('Map m;'); |
| 785 } |
| 786 |
| 787 test_type_dynamic() { |
| 788 checkLibrary('dynamic d;'); |
| 789 } |
| 790 |
| 791 test_type_reference_lib_to_lib() { |
| 792 checkLibrary('class C {} enum E { v } typedef F(); C c; E e; F f;'); |
| 793 } |
| 794 |
| 795 test_type_reference_lib_to_part() { |
| 796 addNamedSource( |
| 797 '/a.dart', 'part of l; class C {} enum E { v } typedef F();'); |
| 798 checkLibrary('library l; part "a.dart"; C c; E e; F f;'); |
| 799 } |
| 800 |
| 801 test_type_reference_part_to_lib() { |
| 802 addNamedSource('/a.dart', 'part of l; C c; E e; F f;'); |
| 803 checkLibrary( |
| 804 'library l; part "a.dart"; class C {} enum E { v } typedef F();'); |
| 805 } |
| 806 |
| 807 test_type_reference_part_to_other_part() { |
| 808 addNamedSource( |
| 809 '/a.dart', 'part of l; class C {} enum E { v } typedef F();'); |
| 810 addNamedSource('/b.dart', 'part of l; C c; E e; F f;'); |
| 811 checkLibrary('library l; part "a.dart"; part "b.dart";'); |
| 812 } |
| 813 |
| 814 test_type_reference_part_to_part() { |
| 815 addNamedSource('/a.dart', |
| 816 'part of l; class C {} enum E { v } typedef F(); C c; E e; F f;'); |
| 817 checkLibrary('library l; part "a.dart";'); |
| 818 } |
| 819 |
| 820 test_type_reference_to_class() { |
| 821 checkLibrary('class C {} C c;'); |
| 822 } |
| 823 |
| 824 test_type_reference_to_class_with_type_arguments() { |
| 825 checkLibrary('class C<T, U> {} C<int, String> c;'); |
| 826 } |
| 827 |
| 828 test_type_reference_to_class_with_type_arguments_implicit() { |
| 829 checkLibrary('class C<T, U> {} C c;'); |
| 830 } |
| 831 |
| 832 test_type_reference_to_enum() { |
| 833 checkLibrary('enum E { v } E e;'); |
| 834 } |
| 835 |
| 836 test_type_reference_to_import() { |
| 837 addLibrarySource('/a.dart', 'class C {} enum E { v }; typedef F();'); |
| 838 checkLibrary('import "a.dart"; C c; E e; F f;'); |
| 839 } |
| 840 |
| 841 test_type_reference_to_import_export() { |
| 842 addLibrarySource('/a.dart', 'export "b.dart";'); |
| 843 addLibrarySource('/b.dart', 'class C {} enum E { v } typedef F();'); |
| 844 checkLibrary('import "a.dart"; C c; E e; F f;'); |
| 845 } |
| 846 |
| 847 test_type_reference_to_import_export_export() { |
| 848 addLibrarySource('/a.dart', 'export "b.dart";'); |
| 849 addLibrarySource('/b.dart', 'export "c.dart";'); |
| 850 addLibrarySource('/c.dart', 'class C {} enum E { v } typedef F();'); |
| 851 checkLibrary('import "a.dart"; C c; E e; F f;'); |
| 852 } |
| 853 |
| 854 test_type_reference_to_import_export_export_in_subdirs() { |
| 855 addLibrarySource('/a/a.dart', 'export "b/b.dart";'); |
| 856 addLibrarySource('/a/b/b.dart', 'export "../c/c.dart";'); |
| 857 addLibrarySource('/a/c/c.dart', 'class C {} enum E { v } typedef F();'); |
| 858 checkLibrary('import "a/a.dart"; C c; E e; F f;'); |
| 859 } |
| 860 |
| 861 test_type_reference_to_import_export_in_subdirs() { |
| 862 addLibrarySource('/a/a.dart', 'export "b/b.dart";'); |
| 863 addLibrarySource('/a/b/b.dart', 'class C {} enum E { v } typedef F();'); |
| 864 checkLibrary('import "a/a.dart"; C c; E e; F f;'); |
| 865 } |
| 866 |
| 867 test_type_reference_to_import_part() { |
| 868 addLibrarySource('/a.dart', 'library l; part "b.dart";'); |
| 869 addNamedSource( |
| 870 '/b.dart', 'part of l; class C {} enum E { v } typedef F();'); |
| 871 checkLibrary('import "a.dart"; C c; E e; F f;'); |
| 872 } |
| 873 |
| 874 test_type_reference_to_import_part_in_subdir() { |
| 875 addLibrarySource('/a/b.dart', 'library l; part "c.dart";'); |
| 876 addNamedSource( |
| 877 '/a/c.dart', 'part of l; class C {} enum E { v } typedef F();'); |
| 878 checkLibrary('import "a/b.dart"; C c; E e; F f;'); |
| 879 } |
| 880 |
| 881 test_type_reference_to_import_relative() { |
| 882 addLibrarySource('/a.dart', 'class C {} enum E { v } typedef F();'); |
| 883 checkLibrary('import "a.dart"; C c; E e; F f;'); |
| 884 } |
| 885 |
| 886 test_type_reference_to_typedef() { |
| 887 checkLibrary('typedef F(); F f;'); |
| 888 } |
| 889 |
| 890 test_type_reference_to_typedef_with_type_arguments() { |
| 891 checkLibrary('typedef U F<T, U>(T t); F<int, String> f;'); |
| 892 } |
| 893 |
| 894 test_type_reference_to_typedef_with_type_arguments_implicit() { |
| 895 checkLibrary('typedef U F<T, U>(T t); F f;'); |
| 896 } |
| 897 |
| 898 test_type_unresolved() { |
| 899 checkLibrary('C c;', allowErrors: true); |
| 900 } |
| 901 |
| 902 test_type_unresolved_prefixed() { |
| 903 checkLibrary('import "dart:core" as core; core.C c;', allowErrors: true); |
| 904 } |
| 905 |
| 906 test_typedef_parameter_parameters() { |
| 907 checkLibrary('typedef F(g(x, y));'); |
| 908 } |
| 909 |
| 910 test_typedef_parameter_return_type() { |
| 911 checkLibrary('typedef F(int g());'); |
| 912 } |
| 913 |
| 914 test_typedef_parameter_type() { |
| 915 checkLibrary('typedef F(int i);'); |
| 916 } |
| 917 |
| 918 test_typedef_parameter_type_generic() { |
| 919 checkLibrary('typedef F<T>(T t);'); |
| 920 } |
| 921 |
| 922 test_typedef_parameters() { |
| 923 checkLibrary('typedef F(x, y);'); |
| 924 } |
| 925 |
| 926 test_typedef_return_type() { |
| 927 checkLibrary('typedef int F();'); |
| 928 } |
| 929 |
| 930 test_typedef_return_type_generic() { |
| 931 checkLibrary('typedef T F<T>();'); |
| 932 } |
| 933 |
| 934 test_typedef_return_type_implicit() { |
| 935 checkLibrary('typedef F();'); |
| 936 } |
| 937 |
| 938 test_typedef_return_type_void() { |
| 939 checkLibrary('typedef void F();'); |
| 940 } |
| 941 |
| 942 test_typedef_type_parameters() { |
| 943 checkLibrary('typedef U F<T, U>(T t);'); |
| 944 } |
| 945 |
| 946 test_typedef_type_parameters_bound() { |
| 947 checkLibrary('typedef U F<T extends Object, U extends D>(T t); class D {}'); |
| 948 } |
| 949 |
| 950 test_typedef_type_parameters_f_bound_complex() { |
| 951 checkLibrary('typedef U F<T extends List<U>, U>(T t);'); |
| 952 } |
| 953 |
| 954 test_typedef_type_parameters_f_bound_simple() { |
| 955 checkLibrary('typedef U F<T extends U, U>(T t);'); |
| 956 } |
| 957 |
| 958 test_typedefs() { |
| 959 checkLibrary('f() {} g() {}'); |
| 960 } |
| 961 |
| 962 test_variable_const() { |
| 963 checkLibrary('const int i = 0;'); |
| 964 } |
| 965 |
| 966 test_variables() { |
| 967 checkLibrary('int i; int j;'); |
| 968 } |
| 969 } |
OLD | NEW |