| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 library analyzer.test.generated.analysis_context_factory; |
| 6 |
| 7 import 'dart:collection'; |
| 8 |
| 9 import 'package:analyzer/dart/ast/ast.dart'; |
| 10 import 'package:analyzer/dart/ast/token.dart'; |
| 11 import 'package:analyzer/dart/element/element.dart'; |
| 12 import 'package:analyzer/dart/element/type.dart'; |
| 13 import 'package:analyzer/file_system/file_system.dart'; |
| 14 import 'package:analyzer/file_system/memory_file_system.dart'; |
| 15 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 16 import 'package:analyzer/src/context/context.dart'; |
| 17 import 'package:analyzer/src/dart/element/element.dart'; |
| 18 import 'package:analyzer/src/dart/element/type.dart'; |
| 19 import 'package:analyzer/src/dart/sdk/sdk.dart'; |
| 20 import 'package:analyzer/src/generated/engine.dart'; |
| 21 import 'package:analyzer/src/generated/resolver.dart'; |
| 22 import 'package:analyzer/src/generated/sdk.dart'; |
| 23 import 'package:analyzer/src/generated/source_io.dart'; |
| 24 import 'package:analyzer/src/generated/testing/ast_factory.dart'; |
| 25 import 'package:analyzer/src/generated/testing/element_factory.dart'; |
| 26 import 'package:analyzer/src/generated/testing/test_type_provider.dart'; |
| 27 import 'package:analyzer/src/generated/utilities_dart.dart'; |
| 28 import 'package:analyzer/src/source/source_resource.dart'; |
| 29 import 'package:analyzer/src/string_source.dart'; |
| 30 import 'package:unittest/unittest.dart'; |
| 31 |
| 32 /** |
| 33 * The class `AnalysisContextFactory` defines utility methods used to create ana
lysis contexts |
| 34 * for testing purposes. |
| 35 */ |
| 36 class AnalysisContextFactory { |
| 37 static String _DART_MATH = "dart:math"; |
| 38 |
| 39 static String _DART_INTERCEPTORS = "dart:_interceptors"; |
| 40 |
| 41 static String _DART_JS_HELPER = "dart:_js_helper"; |
| 42 |
| 43 /** |
| 44 * Create and return an analysis context that has a fake core library already |
| 45 * resolved. The given [resourceProvider] will be used when accessing the file |
| 46 * system. |
| 47 */ |
| 48 static InternalAnalysisContext contextWithCore( |
| 49 {ResourceProvider resourceProvider}) { |
| 50 AnalysisContextForTests context = new AnalysisContextForTests(); |
| 51 return initContextWithCore(context, null, resourceProvider); |
| 52 } |
| 53 |
| 54 /** |
| 55 * Create and return an analysis context that uses the given [options] and has |
| 56 * a fake core library already resolved. The given [resourceProvider] will be |
| 57 * used when accessing the file system. |
| 58 */ |
| 59 static InternalAnalysisContext contextWithCoreAndOptions( |
| 60 AnalysisOptions options, |
| 61 {ResourceProvider resourceProvider}) { |
| 62 AnalysisContextForTests context = new AnalysisContextForTests(); |
| 63 context._internalSetAnalysisOptions(options); |
| 64 return initContextWithCore(context, null, resourceProvider); |
| 65 } |
| 66 |
| 67 /** |
| 68 * Create and return an analysis context that has a fake core library already |
| 69 * resolved. If not `null`, the given [packages] map will be used to create a |
| 70 * package URI resolver. The given [resourceProvider] will be used when |
| 71 * accessing the file system. |
| 72 */ |
| 73 static InternalAnalysisContext contextWithCoreAndPackages( |
| 74 Map<String, String> packages, |
| 75 {ResourceProvider resourceProvider}) { |
| 76 AnalysisContextForTests context = new AnalysisContextForTests(); |
| 77 return initContextWithCore( |
| 78 context, new TestPackageUriResolver(packages), resourceProvider); |
| 79 } |
| 80 |
| 81 /** |
| 82 * Initialize the given analysis [context] with a fake core library that has |
| 83 * already been resolved. If not `null`, the given [contributedResolver] will |
| 84 * be added to the context's source factory. The given [resourceProvider] will |
| 85 * be used when accessing the file system. |
| 86 */ |
| 87 static InternalAnalysisContext initContextWithCore( |
| 88 InternalAnalysisContext context, |
| 89 [UriResolver contributedResolver, |
| 90 ResourceProvider resourceProvider]) { |
| 91 resourceProvider ??= PhysicalResourceProvider.INSTANCE; |
| 92 DartSdk sdk = new _AnalysisContextFactory_initContextWithCore( |
| 93 resourceProvider, '/fake/sdk'); |
| 94 List<UriResolver> resolvers = <UriResolver>[ |
| 95 new DartUriResolver(sdk), |
| 96 new ResourceUriResolver(resourceProvider) |
| 97 ]; |
| 98 if (contributedResolver != null) { |
| 99 resolvers.add(contributedResolver); |
| 100 } |
| 101 SourceFactory sourceFactory = new SourceFactory(resolvers); |
| 102 context.sourceFactory = sourceFactory; |
| 103 AnalysisContext coreContext = sdk.context; |
| 104 (coreContext.analysisOptions as AnalysisOptionsImpl).strongMode = |
| 105 context.analysisOptions.strongMode; |
| 106 // |
| 107 // dart:core |
| 108 // |
| 109 TestTypeProvider provider = new TestTypeProvider(); |
| 110 CompilationUnitElementImpl coreUnit = |
| 111 new CompilationUnitElementImpl("core.dart"); |
| 112 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE); |
| 113 coreContext.setContents(coreSource, ""); |
| 114 coreUnit.librarySource = coreUnit.source = coreSource; |
| 115 ClassElementImpl overrideClassElement = |
| 116 ElementFactory.classElement2("_Override"); |
| 117 ClassElementImpl proxyClassElement = ElementFactory.classElement2("_Proxy"); |
| 118 proxyClassElement.constructors = <ConstructorElement>[ |
| 119 ElementFactory.constructorElement(proxyClassElement, '', true) |
| 120 ..isCycleFree = true |
| 121 ..constantInitializers = <ConstructorInitializer>[] |
| 122 ]; |
| 123 ClassElement objectClassElement = provider.objectType.element; |
| 124 coreUnit.types = <ClassElement>[ |
| 125 provider.boolType.element, |
| 126 provider.deprecatedType.element, |
| 127 provider.doubleType.element, |
| 128 provider.functionType.element, |
| 129 provider.intType.element, |
| 130 provider.iterableType.element, |
| 131 provider.iteratorType.element, |
| 132 provider.listType.element, |
| 133 provider.mapType.element, |
| 134 provider.nullType.element, |
| 135 provider.numType.element, |
| 136 objectClassElement, |
| 137 overrideClassElement, |
| 138 proxyClassElement, |
| 139 provider.stackTraceType.element, |
| 140 provider.stringType.element, |
| 141 provider.symbolType.element, |
| 142 provider.typeType.element |
| 143 ]; |
| 144 coreUnit.functions = <FunctionElement>[ |
| 145 ElementFactory.functionElement3("identical", provider.boolType.element, |
| 146 <ClassElement>[objectClassElement, objectClassElement], null), |
| 147 ElementFactory.functionElement3("print", VoidTypeImpl.instance.element, |
| 148 <ClassElement>[objectClassElement], null) |
| 149 ]; |
| 150 TopLevelVariableElement proxyTopLevelVariableElt = ElementFactory |
| 151 .topLevelVariableElement3("proxy", true, false, proxyClassElement.type); |
| 152 ConstTopLevelVariableElementImpl deprecatedTopLevelVariableElt = |
| 153 ElementFactory.topLevelVariableElement3( |
| 154 "deprecated", true, false, provider.deprecatedType); |
| 155 TopLevelVariableElement overrideTopLevelVariableElt = |
| 156 ElementFactory.topLevelVariableElement3( |
| 157 "override", true, false, overrideClassElement.type); |
| 158 { |
| 159 ClassElement deprecatedElement = provider.deprecatedType.element; |
| 160 InstanceCreationExpression initializer = AstFactory |
| 161 .instanceCreationExpression2( |
| 162 Keyword.CONST, |
| 163 AstFactory.typeName(deprecatedElement), |
| 164 [AstFactory.string2('next release')]); |
| 165 ConstructorElement constructor = deprecatedElement.constructors.single; |
| 166 initializer.staticElement = constructor; |
| 167 initializer.constructorName.staticElement = constructor; |
| 168 deprecatedTopLevelVariableElt.constantInitializer = initializer; |
| 169 } |
| 170 coreUnit.accessors = <PropertyAccessorElement>[ |
| 171 deprecatedTopLevelVariableElt.getter, |
| 172 overrideTopLevelVariableElt.getter, |
| 173 proxyTopLevelVariableElt.getter |
| 174 ]; |
| 175 coreUnit.topLevelVariables = <TopLevelVariableElement>[ |
| 176 deprecatedTopLevelVariableElt, |
| 177 overrideTopLevelVariableElt, |
| 178 proxyTopLevelVariableElt |
| 179 ]; |
| 180 LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode( |
| 181 coreContext, AstFactory.libraryIdentifier2(["dart", "core"])); |
| 182 coreLibrary.definingCompilationUnit = coreUnit; |
| 183 // |
| 184 // dart:async |
| 185 // |
| 186 LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode( |
| 187 coreContext, AstFactory.libraryIdentifier2(["dart", "async"])); |
| 188 CompilationUnitElementImpl asyncUnit = |
| 189 new CompilationUnitElementImpl("async.dart"); |
| 190 Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC); |
| 191 coreContext.setContents(asyncSource, ""); |
| 192 asyncUnit.librarySource = asyncUnit.source = asyncSource; |
| 193 asyncLibrary.definingCompilationUnit = asyncUnit; |
| 194 // Future |
| 195 ClassElementImpl futureElement = |
| 196 ElementFactory.classElement2("Future", ["T"]); |
| 197 futureElement.enclosingElement = asyncUnit; |
| 198 // factory Future.value([value]) |
| 199 ConstructorElementImpl futureConstructor = |
| 200 ElementFactory.constructorElement2(futureElement, "value"); |
| 201 futureConstructor.parameters = <ParameterElement>[ |
| 202 ElementFactory.positionalParameter2("value", provider.dynamicType) |
| 203 ]; |
| 204 futureConstructor.factory = true; |
| 205 futureElement.constructors = <ConstructorElement>[futureConstructor]; |
| 206 // Future then(onValue(T value), { Function onError }); |
| 207 TypeDefiningElement futureThenR = DynamicElementImpl.instance; |
| 208 if (context.analysisOptions.strongMode) { |
| 209 futureThenR = ElementFactory.typeParameterWithType('R'); |
| 210 } |
| 211 FunctionElementImpl thenOnValue = ElementFactory.functionElement3('onValue', |
| 212 DynamicElementImpl.instance, [futureElement.typeParameters[0]], null); |
| 213 thenOnValue.synthetic = true; |
| 214 |
| 215 DartType futureRType = futureElement.type.instantiate([futureThenR.type]); |
| 216 MethodElementImpl thenMethod = ElementFactory |
| 217 .methodElementWithParameters(futureElement, "then", futureRType, [ |
| 218 ElementFactory.requiredParameter2("onValue", thenOnValue.type), |
| 219 ElementFactory.namedParameter2("onError", provider.functionType) |
| 220 ]); |
| 221 if (!futureThenR.type.isDynamic) { |
| 222 thenMethod.typeParameters = <TypeParameterElement>[futureThenR]; |
| 223 } |
| 224 thenOnValue.enclosingElement = thenMethod; |
| 225 thenOnValue.type = new FunctionTypeImpl(thenOnValue); |
| 226 (thenMethod.parameters[0] as ParameterElementImpl).type = thenOnValue.type; |
| 227 thenMethod.type = new FunctionTypeImpl(thenMethod); |
| 228 |
| 229 futureElement.methods = <MethodElement>[thenMethod]; |
| 230 // Completer |
| 231 ClassElementImpl completerElement = |
| 232 ElementFactory.classElement2("Completer", ["T"]); |
| 233 ConstructorElementImpl completerConstructor = |
| 234 ElementFactory.constructorElement2(completerElement, null); |
| 235 completerElement.constructors = <ConstructorElement>[completerConstructor]; |
| 236 // StreamSubscription |
| 237 ClassElementImpl streamSubscriptionElement = |
| 238 ElementFactory.classElement2("StreamSubscription", ["T"]); |
| 239 // Stream |
| 240 ClassElementImpl streamElement = |
| 241 ElementFactory.classElement2("Stream", ["T"]); |
| 242 streamElement.constructors = <ConstructorElement>[ |
| 243 ElementFactory.constructorElement2(streamElement, null) |
| 244 ]; |
| 245 DartType returnType = streamSubscriptionElement.type |
| 246 .instantiate(streamElement.type.typeArguments); |
| 247 FunctionElementImpl listenOnData = ElementFactory.functionElement3( |
| 248 'onData', |
| 249 VoidTypeImpl.instance.element, |
| 250 <TypeDefiningElement>[streamElement.typeParameters[0]], |
| 251 null); |
| 252 listenOnData.synthetic = true; |
| 253 List<DartType> parameterTypes = <DartType>[ |
| 254 listenOnData.type, |
| 255 ]; |
| 256 // TODO(brianwilkerson) This is missing the optional parameters. |
| 257 MethodElementImpl listenMethod = |
| 258 ElementFactory.methodElement('listen', returnType, parameterTypes); |
| 259 streamElement.methods = <MethodElement>[listenMethod]; |
| 260 listenMethod.type = new FunctionTypeImpl(listenMethod); |
| 261 |
| 262 FunctionElementImpl listenParamFunction = parameterTypes[0].element; |
| 263 listenParamFunction.enclosingElement = listenMethod; |
| 264 listenParamFunction.type = new FunctionTypeImpl(listenParamFunction); |
| 265 ParameterElementImpl listenParam = listenMethod.parameters[0]; |
| 266 listenParam.type = listenParamFunction.type; |
| 267 |
| 268 asyncUnit.types = <ClassElement>[ |
| 269 completerElement, |
| 270 futureElement, |
| 271 streamElement, |
| 272 streamSubscriptionElement |
| 273 ]; |
| 274 // |
| 275 // dart:html |
| 276 // |
| 277 CompilationUnitElementImpl htmlUnit = |
| 278 new CompilationUnitElementImpl("html_dartium.dart"); |
| 279 Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML); |
| 280 coreContext.setContents(htmlSource, ""); |
| 281 htmlUnit.librarySource = htmlUnit.source = htmlSource; |
| 282 ClassElementImpl elementElement = ElementFactory.classElement2("Element"); |
| 283 InterfaceType elementType = elementElement.type; |
| 284 ClassElementImpl canvasElement = |
| 285 ElementFactory.classElement("CanvasElement", elementType); |
| 286 ClassElementImpl contextElement = |
| 287 ElementFactory.classElement2("CanvasRenderingContext"); |
| 288 InterfaceType contextElementType = contextElement.type; |
| 289 ClassElementImpl context2dElement = ElementFactory.classElement( |
| 290 "CanvasRenderingContext2D", contextElementType); |
| 291 canvasElement.methods = <MethodElement>[ |
| 292 ElementFactory.methodElement( |
| 293 "getContext", contextElementType, [provider.stringType]) |
| 294 ]; |
| 295 canvasElement.accessors = <PropertyAccessorElement>[ |
| 296 ElementFactory.getterElement("context2D", false, context2dElement.type) |
| 297 ]; |
| 298 canvasElement.fields = canvasElement.accessors |
| 299 .map((PropertyAccessorElement accessor) => accessor.variable) |
| 300 .toList(); |
| 301 ClassElementImpl documentElement = |
| 302 ElementFactory.classElement("Document", elementType); |
| 303 ClassElementImpl htmlDocumentElement = |
| 304 ElementFactory.classElement("HtmlDocument", documentElement.type); |
| 305 htmlDocumentElement.methods = <MethodElement>[ |
| 306 ElementFactory |
| 307 .methodElement("query", elementType, <DartType>[provider.stringType]) |
| 308 ]; |
| 309 htmlUnit.types = <ClassElement>[ |
| 310 ElementFactory.classElement("AnchorElement", elementType), |
| 311 ElementFactory.classElement("BodyElement", elementType), |
| 312 ElementFactory.classElement("ButtonElement", elementType), |
| 313 canvasElement, |
| 314 contextElement, |
| 315 context2dElement, |
| 316 ElementFactory.classElement("DivElement", elementType), |
| 317 documentElement, |
| 318 elementElement, |
| 319 htmlDocumentElement, |
| 320 ElementFactory.classElement("InputElement", elementType), |
| 321 ElementFactory.classElement("SelectElement", elementType) |
| 322 ]; |
| 323 htmlUnit.functions = <FunctionElement>[ |
| 324 ElementFactory.functionElement3("query", elementElement, |
| 325 <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST) |
| 326 ]; |
| 327 TopLevelVariableElementImpl document = |
| 328 ElementFactory.topLevelVariableElement3( |
| 329 "document", false, true, htmlDocumentElement.type); |
| 330 htmlUnit.topLevelVariables = <TopLevelVariableElement>[document]; |
| 331 htmlUnit.accessors = <PropertyAccessorElement>[document.getter]; |
| 332 LibraryElementImpl htmlLibrary = new LibraryElementImpl.forNode( |
| 333 coreContext, AstFactory.libraryIdentifier2(["dart", "dom", "html"])); |
| 334 htmlLibrary.definingCompilationUnit = htmlUnit; |
| 335 // |
| 336 // dart:math |
| 337 // |
| 338 CompilationUnitElementImpl mathUnit = |
| 339 new CompilationUnitElementImpl("math.dart"); |
| 340 Source mathSource = sourceFactory.forUri(_DART_MATH); |
| 341 coreContext.setContents(mathSource, ""); |
| 342 mathUnit.librarySource = mathUnit.source = mathSource; |
| 343 FunctionElement cosElement = ElementFactory.functionElement3( |
| 344 "cos", |
| 345 provider.doubleType.element, |
| 346 <ClassElement>[provider.numType.element], |
| 347 ClassElement.EMPTY_LIST); |
| 348 TopLevelVariableElement ln10Element = ElementFactory |
| 349 .topLevelVariableElement3("LN10", true, false, provider.doubleType); |
| 350 TypeParameterElement maxT = |
| 351 ElementFactory.typeParameterWithType('T', provider.numType); |
| 352 FunctionElementImpl maxElement = ElementFactory.functionElement3( |
| 353 "max", maxT, [maxT, maxT], ClassElement.EMPTY_LIST); |
| 354 maxElement.typeParameters = [maxT]; |
| 355 maxElement.type = new FunctionTypeImpl(maxElement); |
| 356 TopLevelVariableElement piElement = ElementFactory.topLevelVariableElement3( |
| 357 "PI", true, false, provider.doubleType); |
| 358 ClassElementImpl randomElement = ElementFactory.classElement2("Random"); |
| 359 randomElement.abstract = true; |
| 360 ConstructorElementImpl randomConstructor = |
| 361 ElementFactory.constructorElement2(randomElement, null); |
| 362 randomConstructor.factory = true; |
| 363 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0); |
| 364 seedParam.parameterKind = ParameterKind.POSITIONAL; |
| 365 seedParam.type = provider.intType; |
| 366 randomConstructor.parameters = <ParameterElement>[seedParam]; |
| 367 randomElement.constructors = <ConstructorElement>[randomConstructor]; |
| 368 FunctionElement sinElement = ElementFactory.functionElement3( |
| 369 "sin", |
| 370 provider.doubleType.element, |
| 371 <ClassElement>[provider.numType.element], |
| 372 ClassElement.EMPTY_LIST); |
| 373 FunctionElement sqrtElement = ElementFactory.functionElement3( |
| 374 "sqrt", |
| 375 provider.doubleType.element, |
| 376 <ClassElement>[provider.numType.element], |
| 377 ClassElement.EMPTY_LIST); |
| 378 mathUnit.accessors = <PropertyAccessorElement>[ |
| 379 ln10Element.getter, |
| 380 piElement.getter |
| 381 ]; |
| 382 mathUnit.functions = <FunctionElement>[ |
| 383 cosElement, |
| 384 maxElement, |
| 385 sinElement, |
| 386 sqrtElement |
| 387 ]; |
| 388 mathUnit.topLevelVariables = <TopLevelVariableElement>[ |
| 389 ln10Element, |
| 390 piElement |
| 391 ]; |
| 392 mathUnit.types = <ClassElement>[randomElement]; |
| 393 LibraryElementImpl mathLibrary = new LibraryElementImpl.forNode( |
| 394 coreContext, AstFactory.libraryIdentifier2(["dart", "math"])); |
| 395 mathLibrary.definingCompilationUnit = mathUnit; |
| 396 // |
| 397 // Set empty sources for the rest of the libraries. |
| 398 // |
| 399 Source source = sourceFactory.forUri(_DART_INTERCEPTORS); |
| 400 coreContext.setContents(source, ""); |
| 401 source = sourceFactory.forUri(_DART_JS_HELPER); |
| 402 coreContext.setContents(source, ""); |
| 403 // |
| 404 // Record the elements. |
| 405 // |
| 406 HashMap<Source, LibraryElement> elementMap = |
| 407 new HashMap<Source, LibraryElement>(); |
| 408 elementMap[coreSource] = coreLibrary; |
| 409 if (asyncSource != null) { |
| 410 elementMap[asyncSource] = asyncLibrary; |
| 411 } |
| 412 elementMap[htmlSource] = htmlLibrary; |
| 413 elementMap[mathSource] = mathLibrary; |
| 414 // |
| 415 // Set the public and export namespaces. We don't use exports in the fake |
| 416 // core library so public and export namespaces are the same. |
| 417 // |
| 418 for (LibraryElementImpl library in elementMap.values) { |
| 419 Namespace namespace = |
| 420 new NamespaceBuilder().createPublicNamespaceForLibrary(library); |
| 421 library.exportNamespace = namespace; |
| 422 library.publicNamespace = namespace; |
| 423 } |
| 424 context.recordLibraryElements(elementMap); |
| 425 // Create the synthetic element for `loadLibrary`. |
| 426 for (LibraryElementImpl library in elementMap.values) { |
| 427 library.createLoadLibraryFunction(context.typeProvider); |
| 428 } |
| 429 return context; |
| 430 } |
| 431 } |
| 432 |
| 433 /** |
| 434 * An analysis context that has a fake SDK that is much smaller and faster for |
| 435 * testing purposes. |
| 436 */ |
| 437 class AnalysisContextForTests extends AnalysisContextImpl { |
| 438 @override |
| 439 void set analysisOptions(AnalysisOptions options) { |
| 440 AnalysisOptions currentOptions = analysisOptions; |
| 441 bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate != |
| 442 options.analyzeFunctionBodiesPredicate || |
| 443 currentOptions.generateImplicitErrors != |
| 444 options.generateImplicitErrors || |
| 445 currentOptions.generateSdkErrors != options.generateSdkErrors || |
| 446 currentOptions.dart2jsHint != options.dart2jsHint || |
| 447 (currentOptions.hint && !options.hint) || |
| 448 currentOptions.preserveComments != options.preserveComments || |
| 449 currentOptions.enableStrictCallChecks != options.enableStrictCallChecks; |
| 450 if (needsRecompute) { |
| 451 fail( |
| 452 "Cannot set options that cause the sources to be reanalyzed in a test
context"); |
| 453 } |
| 454 super.analysisOptions = options; |
| 455 } |
| 456 |
| 457 @override |
| 458 bool exists(Source source) => |
| 459 super.exists(source) || sourceFactory.dartSdk.context.exists(source); |
| 460 |
| 461 @override |
| 462 TimestampedData<String> getContents(Source source) { |
| 463 if (source.isInSystemLibrary) { |
| 464 return sourceFactory.dartSdk.context.getContents(source); |
| 465 } |
| 466 return super.getContents(source); |
| 467 } |
| 468 |
| 469 @override |
| 470 int getModificationStamp(Source source) { |
| 471 if (source.isInSystemLibrary) { |
| 472 return sourceFactory.dartSdk.context.getModificationStamp(source); |
| 473 } |
| 474 return super.getModificationStamp(source); |
| 475 } |
| 476 |
| 477 /** |
| 478 * Set the analysis options, even if they would force re-analysis. This method
should only be |
| 479 * invoked before the fake SDK is initialized. |
| 480 * |
| 481 * @param options the analysis options to be set |
| 482 */ |
| 483 void _internalSetAnalysisOptions(AnalysisOptions options) { |
| 484 super.analysisOptions = options; |
| 485 } |
| 486 } |
| 487 |
| 488 /** |
| 489 * Helper for creating and managing single [AnalysisContext]. |
| 490 */ |
| 491 class AnalysisContextHelper { |
| 492 ResourceProvider resourceProvider; |
| 493 AnalysisContext context; |
| 494 |
| 495 /** |
| 496 * Creates new [AnalysisContext] using [AnalysisContextFactory]. |
| 497 */ |
| 498 AnalysisContextHelper( |
| 499 [AnalysisOptionsImpl options, ResourceProvider provider]) { |
| 500 resourceProvider = provider ?? new MemoryResourceProvider(); |
| 501 if (options == null) { |
| 502 options = new AnalysisOptionsImpl(); |
| 503 } |
| 504 options.cacheSize = 256; |
| 505 context = AnalysisContextFactory.contextWithCoreAndOptions(options, |
| 506 resourceProvider: resourceProvider); |
| 507 } |
| 508 |
| 509 Source addSource(String path, String code) { |
| 510 Source source = new FileSource(resourceProvider.getFile(path)); |
| 511 if (path.endsWith(".dart") || path.endsWith(".html")) { |
| 512 ChangeSet changeSet = new ChangeSet(); |
| 513 changeSet.addedSource(source); |
| 514 context.applyChanges(changeSet); |
| 515 } |
| 516 context.setContents(source, code); |
| 517 return source; |
| 518 } |
| 519 |
| 520 CompilationUnitElement getDefiningUnitElement(Source source) => |
| 521 context.getCompilationUnitElement(source, source); |
| 522 |
| 523 CompilationUnit resolveDefiningUnit(Source source) { |
| 524 LibraryElement libraryElement = context.computeLibraryElement(source); |
| 525 return context.resolveCompilationUnit(source, libraryElement); |
| 526 } |
| 527 |
| 528 void runTasks() { |
| 529 AnalysisResult result = context.performAnalysisTask(); |
| 530 while (result.changeNotices != null) { |
| 531 result = context.performAnalysisTask(); |
| 532 } |
| 533 } |
| 534 } |
| 535 |
| 536 class TestPackageUriResolver extends UriResolver { |
| 537 Map<String, Source> sourceMap = new HashMap<String, Source>(); |
| 538 |
| 539 TestPackageUriResolver(Map<String, String> map) { |
| 540 map.forEach((String uri, String contents) { |
| 541 sourceMap[uri] = new StringSource(contents, '/test_pkg_source.dart'); |
| 542 }); |
| 543 } |
| 544 |
| 545 @override |
| 546 Source resolveAbsolute(Uri uri, [Uri actualUri]) { |
| 547 String uriString = uri.toString(); |
| 548 return sourceMap[uriString]; |
| 549 } |
| 550 |
| 551 @override |
| 552 Uri restoreAbsolute(Source source) => throw new UnimplementedError(); |
| 553 } |
| 554 |
| 555 class _AnalysisContextFactory_initContextWithCore extends FolderBasedDartSdk { |
| 556 _AnalysisContextFactory_initContextWithCore( |
| 557 ResourceProvider resourceProvider, String sdkPath) |
| 558 : super(resourceProvider, resourceProvider.getFolder(sdkPath)); |
| 559 |
| 560 @override |
| 561 LibraryMap initialLibraryMap(bool useDart2jsPaths) { |
| 562 LibraryMap map = new LibraryMap(); |
| 563 _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart"); |
| 564 _addLibrary(map, DartSdk.DART_CORE, false, "core.dart"); |
| 565 _addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart"); |
| 566 _addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart"); |
| 567 _addLibrary(map, AnalysisContextFactory._DART_INTERCEPTORS, true, |
| 568 "_interceptors.dart"); |
| 569 _addLibrary( |
| 570 map, AnalysisContextFactory._DART_JS_HELPER, true, "_js_helper.dart"); |
| 571 return map; |
| 572 } |
| 573 |
| 574 void _addLibrary(LibraryMap map, String uri, bool isInternal, String path) { |
| 575 SdkLibraryImpl library = new SdkLibraryImpl(uri); |
| 576 if (isInternal) { |
| 577 library.category = "Internal"; |
| 578 } |
| 579 library.path = path; |
| 580 map.setLibrary(uri, library); |
| 581 } |
| 582 } |
| OLD | NEW |