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

Side by Side Diff: pkg/analyzer/test/generated/analysis_context_factory.dart

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

Powered by Google App Engine
This is Rietveld 408576698