OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2013, the Dart project authors. | 2 * Copyright (c) 2013, the Dart project authors. |
3 * | 3 * |
4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except | 4 * Licensed under the Eclipse Public License v1.0 (the "License"); you may not u
se this file except |
5 * in compliance with the License. You may obtain a copy of the License at | 5 * in compliance with the License. You may obtain a copy of the License at |
6 * | 6 * |
7 * http://www.eclipse.org/legal/epl-v10.html | 7 * http://www.eclipse.org/legal/epl-v10.html |
8 * | 8 * |
9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License | 9 * Unless required by applicable law or agreed to in writing, software distribut
ed under the License |
10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express | 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY K
IND, either express |
11 * or implied. See the License for the specific language governing permissions a
nd limitations under | 11 * or implied. See the License for the specific language governing permissions a
nd limitations under |
12 * the License. | 12 * the License. |
13 */ | 13 */ |
14 package com.google.dart.engine.context; | 14 package com.google.dart.engine.context; |
15 | 15 |
16 import com.google.dart.engine.element.ClassElement; | 16 import com.google.dart.engine.element.ClassElement; |
17 import com.google.dart.engine.element.ConstructorElement; | 17 import com.google.dart.engine.element.ConstructorElement; |
18 import com.google.dart.engine.element.FunctionElement; | 18 import com.google.dart.engine.element.FunctionElement; |
19 import com.google.dart.engine.element.LibraryElement; | 19 import com.google.dart.engine.element.LibraryElement; |
20 import com.google.dart.engine.element.MethodElement; | 20 import com.google.dart.engine.element.MethodElement; |
21 import com.google.dart.engine.element.ParameterElement; | 21 import com.google.dart.engine.element.ParameterElement; |
22 import com.google.dart.engine.element.PropertyAccessorElement; | 22 import com.google.dart.engine.element.PropertyAccessorElement; |
23 import com.google.dart.engine.element.TopLevelVariableElement; | 23 import com.google.dart.engine.element.TopLevelVariableElement; |
24 import com.google.dart.engine.internal.context.AnalysisContextImpl; | 24 import com.google.dart.engine.internal.context.AnalysisContextImpl; |
| 25 import com.google.dart.engine.internal.context.TimestampedData; |
25 import com.google.dart.engine.internal.element.ClassElementImpl; | 26 import com.google.dart.engine.internal.element.ClassElementImpl; |
26 import com.google.dart.engine.internal.element.CompilationUnitElementImpl; | 27 import com.google.dart.engine.internal.element.CompilationUnitElementImpl; |
27 import com.google.dart.engine.internal.element.ConstructorElementImpl; | 28 import com.google.dart.engine.internal.element.ConstructorElementImpl; |
28 import com.google.dart.engine.internal.element.FunctionTypeAliasElementImpl; | 29 import com.google.dart.engine.internal.element.FunctionTypeAliasElementImpl; |
29 import com.google.dart.engine.internal.element.LibraryElementImpl; | 30 import com.google.dart.engine.internal.element.LibraryElementImpl; |
| 31 import com.google.dart.engine.internal.element.ParameterElementImpl; |
30 import com.google.dart.engine.internal.element.TopLevelVariableElementImpl; | 32 import com.google.dart.engine.internal.element.TopLevelVariableElementImpl; |
31 import com.google.dart.engine.internal.resolver.TestTypeProvider; | 33 import com.google.dart.engine.internal.resolver.TestTypeProvider; |
| 34 import com.google.dart.engine.internal.sdk.LibraryMap; |
| 35 import com.google.dart.engine.internal.sdk.SdkLibraryImpl; |
32 import com.google.dart.engine.internal.type.FunctionTypeImpl; | 36 import com.google.dart.engine.internal.type.FunctionTypeImpl; |
33 import com.google.dart.engine.sdk.DartSdk; | 37 import com.google.dart.engine.sdk.DartSdk; |
34 import com.google.dart.engine.sdk.DirectoryBasedDartSdk; | 38 import com.google.dart.engine.sdk.DirectoryBasedDartSdk; |
35 import com.google.dart.engine.source.DartUriResolver; | 39 import com.google.dart.engine.source.DartUriResolver; |
36 import com.google.dart.engine.source.FileUriResolver; | 40 import com.google.dart.engine.source.FileUriResolver; |
37 import com.google.dart.engine.source.Source; | 41 import com.google.dart.engine.source.Source; |
38 import com.google.dart.engine.source.SourceFactory; | 42 import com.google.dart.engine.source.SourceFactory; |
39 import com.google.dart.engine.type.InterfaceType; | 43 import com.google.dart.engine.type.InterfaceType; |
40 import com.google.dart.engine.type.Type; | 44 import com.google.dart.engine.type.Type; |
| 45 import com.google.dart.engine.utilities.dart.ParameterKind; |
41 | 46 |
42 import static com.google.dart.engine.ast.AstFactory.libraryIdentifier; | 47 import static com.google.dart.engine.ast.AstFactory.libraryIdentifier; |
43 import static com.google.dart.engine.element.ElementFactory.classElement; | 48 import static com.google.dart.engine.element.ElementFactory.classElement; |
44 import static com.google.dart.engine.element.ElementFactory.constructorElement; | 49 import static com.google.dart.engine.element.ElementFactory.constructorElement; |
45 import static com.google.dart.engine.element.ElementFactory.functionElement; | 50 import static com.google.dart.engine.element.ElementFactory.functionElement; |
46 import static com.google.dart.engine.element.ElementFactory.getterElement; | 51 import static com.google.dart.engine.element.ElementFactory.getterElement; |
47 import static com.google.dart.engine.element.ElementFactory.methodElement; | 52 import static com.google.dart.engine.element.ElementFactory.methodElement; |
48 import static com.google.dart.engine.element.ElementFactory.methodElementWithPar
ameters; | 53 import static com.google.dart.engine.element.ElementFactory.methodElementWithPar
ameters; |
49 import static com.google.dart.engine.element.ElementFactory.namedParameter; | 54 import static com.google.dart.engine.element.ElementFactory.namedParameter; |
50 import static com.google.dart.engine.element.ElementFactory.positionalParameter; | 55 import static com.google.dart.engine.element.ElementFactory.positionalParameter; |
51 import static com.google.dart.engine.element.ElementFactory.requiredParameter; | 56 import static com.google.dart.engine.element.ElementFactory.requiredParameter; |
52 import static com.google.dart.engine.element.ElementFactory.topLevelVariableElem
ent; | 57 import static com.google.dart.engine.element.ElementFactory.topLevelVariableElem
ent; |
53 | 58 |
54 import junit.framework.Assert; | 59 import junit.framework.Assert; |
55 | 60 |
| 61 import java.io.File; |
56 import java.util.HashMap; | 62 import java.util.HashMap; |
57 | 63 |
58 /** | 64 /** |
59 * The class {@code AnalysisContextFactory} defines utility methods used to crea
te analysis contexts | 65 * The class {@code AnalysisContextFactory} defines utility methods used to crea
te analysis contexts |
60 * for testing purposes. | 66 * for testing purposes. |
61 */ | 67 */ |
62 public final class AnalysisContextFactory { | 68 public final class AnalysisContextFactory { |
63 /** | 69 /** |
| 70 * Instances of the class {@code AnalysisContextForTests} implement an analysi
s context that has a |
| 71 * fake SDK that is much smaller and faster for testing purposes. |
| 72 */ |
| 73 public static class AnalysisContextForTests extends AnalysisContextImpl { |
| 74 @Override |
| 75 public boolean exists(Source source) { |
| 76 return super.exists(source) || getSourceFactory().getDartSdk().getContext(
).exists(source); |
| 77 } |
| 78 |
| 79 @Override |
| 80 public TimestampedData<CharSequence> getContents(Source source) throws Excep
tion { |
| 81 if (source.isInSystemLibrary()) { |
| 82 return getSourceFactory().getDartSdk().getContext().getContents(source); |
| 83 } |
| 84 return super.getContents(source); |
| 85 } |
| 86 |
| 87 @Override |
| 88 public long getModificationStamp(Source source) { |
| 89 if (source.isInSystemLibrary()) { |
| 90 return getSourceFactory().getDartSdk().getContext().getModificationStamp
(source); |
| 91 } |
| 92 return super.getModificationStamp(source); |
| 93 } |
| 94 |
| 95 @Override |
| 96 public void setAnalysisOptions(AnalysisOptions options) { |
| 97 AnalysisOptions currentOptions = getAnalysisOptions(); |
| 98 boolean needsRecompute = currentOptions.getAnalyzeFunctionBodies() != opti
ons.getAnalyzeFunctionBodies() |
| 99 || currentOptions.getGenerateSdkErrors() != options.getGenerateSdkErro
rs() |
| 100 || currentOptions.getEnableAsync() != options.getEnableAsync() |
| 101 || currentOptions.getEnableDeferredLoading() != options.getEnableDefer
redLoading() |
| 102 || currentOptions.getEnableEnum() != options.getEnableEnum() |
| 103 || currentOptions.getDart2jsHint() != options.getDart2jsHint() |
| 104 || (currentOptions.getHint() && !options.getHint()) |
| 105 || currentOptions.getPreserveComments() != options.getPreserveComments
(); |
| 106 if (needsRecompute) { |
| 107 Assert.fail("Cannot set options that cause the sources to be reanalyzed
in a test context"); |
| 108 } |
| 109 super.setAnalysisOptions(options); |
| 110 } |
| 111 |
| 112 /** |
| 113 * Set the analysis options, even if they would force re-analysis. This meth
od should only be |
| 114 * invoked before the fake SDK is initialized. |
| 115 * |
| 116 * @param options the analysis options to be set |
| 117 */ |
| 118 private void internalSetAnalysisOptions(AnalysisOptions options) { |
| 119 super.setAnalysisOptions(options); |
| 120 } |
| 121 } |
| 122 |
| 123 private static final String DART_MATH = "dart:math"; |
| 124 private static final String DART_INTERCEPTORS = "dart:_interceptors"; |
| 125 private static final String DART_JS_HELPER = "dart:_js_helper"; |
| 126 |
| 127 /** |
| 128 * The fake SDK used by all of the contexts created by this factory. |
| 129 */ |
| 130 private static DirectoryBasedDartSdk FAKE_SDK; |
| 131 |
| 132 /** |
64 * Create an analysis context that has a fake core library already resolved. | 133 * Create an analysis context that has a fake core library already resolved. |
65 * | 134 * |
66 * @return the analysis context that was created | 135 * @return the analysis context that was created |
67 */ | 136 */ |
68 public static AnalysisContextImpl contextWithCore() { | 137 public static AnalysisContextImpl contextWithCore() { |
69 AnalysisContextImpl context = new AnalysisContextImpl() { | 138 AnalysisContextForTests context = new AnalysisContextForTests(); |
70 @Override | |
71 public void setAnalysisOptions(AnalysisOptions options) { | |
72 AnalysisOptions currentOptions = getAnalysisOptions(); | |
73 boolean needsRecompute = currentOptions.getAnalyzeFunctionBodies() != op
tions.getAnalyzeFunctionBodies() | |
74 || currentOptions.getGenerateSdkErrors() != options.getGenerateSdkEr
rors() | |
75 || currentOptions.getEnableAsync() != options.getEnableAsync() | |
76 || currentOptions.getEnableDeferredLoading() != options.getEnableDef
erredLoading() | |
77 || currentOptions.getEnableEnum() != options.getEnableEnum() | |
78 || currentOptions.getDart2jsHint() != options.getDart2jsHint() | |
79 || (currentOptions.getHint() && !options.getHint()) | |
80 || currentOptions.getPreserveComments() != options.getPreserveCommen
ts(); | |
81 if (needsRecompute) { | |
82 Assert.fail("Cannot set options that cause the sources to be reanalyze
d in a test context"); | |
83 } | |
84 super.setAnalysisOptions(options); | |
85 } | |
86 }; | |
87 return initContextWithCore(context); | 139 return initContextWithCore(context); |
88 } | 140 } |
89 | 141 |
90 /** | 142 /** |
91 * Create an analysis context that uses the given options and has a fake core
library already | 143 * Create an analysis context that uses the given options and has a fake core
library already |
92 * resolved. | 144 * resolved. |
93 * | 145 * |
94 * @param options the options to be applied to the context | 146 * @param options the options to be applied to the context |
95 * @return the analysis context that was created | 147 * @return the analysis context that was created |
96 */ | 148 */ |
97 public static AnalysisContextImpl contextWithCoreAndOptions(AnalysisOptions op
tions) { | 149 public static AnalysisContextImpl contextWithCoreAndOptions(AnalysisOptions op
tions) { |
98 AnalysisContextImpl context = new AnalysisContextImpl(); | 150 AnalysisContextForTests context = new AnalysisContextForTests(); |
99 context.setAnalysisOptions(options); | 151 context.internalSetAnalysisOptions(options); |
100 return initContextWithCore(context); | 152 return initContextWithCore(context); |
101 } | 153 } |
102 | 154 |
103 /** | 155 /** |
104 * Initialize the given analysis context with a fake core library already reso
lved. | 156 * Initialize the given analysis context with a fake core library already reso
lved. |
105 * | 157 * |
106 * @param context the context to be initialized (not {@code null}) | 158 * @param context the context to be initialized (not {@code null}) |
107 * @return the analysis context that was created | 159 * @return the analysis context that was created |
108 */ | 160 */ |
109 public static AnalysisContextImpl initContextWithCore(AnalysisContextImpl cont
ext) { | 161 public static AnalysisContextImpl initContextWithCore(AnalysisContextImpl cont
ext) { |
110 DirectoryBasedDartSdk sdk = DirectoryBasedDartSdk.getDefaultSdk(); | 162 DirectoryBasedDartSdk sdk = new DirectoryBasedDartSdk(new File("/fake/sdk"))
{ |
| 163 @Override |
| 164 protected LibraryMap initialLibraryMap(boolean useDart2jsPaths) { |
| 165 LibraryMap map = new LibraryMap(); |
| 166 addLibrary(map, DART_ASYNC, false, "async.dart"); |
| 167 addLibrary(map, DART_CORE, false, "core.dart"); |
| 168 addLibrary(map, DART_HTML, false, "html_dartium.dart"); |
| 169 addLibrary(map, DART_MATH, false, "math.dart"); |
| 170 addLibrary(map, DART_INTERCEPTORS, true, "_interceptors.dart"); |
| 171 addLibrary(map, DART_JS_HELPER, true, "_js_helper.dart"); |
| 172 return map; |
| 173 } |
| 174 |
| 175 private void addLibrary(LibraryMap map, String uri, boolean isInternal, St
ring path) { |
| 176 SdkLibraryImpl library = new SdkLibraryImpl(uri); |
| 177 if (isInternal) { |
| 178 library.setCategory("Internal"); |
| 179 } |
| 180 library.setPath(path); |
| 181 map.setLibrary(uri, library); |
| 182 } |
| 183 }; |
111 SourceFactory sourceFactory = new SourceFactory(new DartUriResolver(sdk), ne
w FileUriResolver()); | 184 SourceFactory sourceFactory = new SourceFactory(new DartUriResolver(sdk), ne
w FileUriResolver()); |
112 context.setSourceFactory(sourceFactory); | 185 context.setSourceFactory(sourceFactory); |
113 AnalysisContext coreContext = sdk.getContext(); | 186 AnalysisContext coreContext = sdk.getContext(); |
114 // | 187 // |
115 // dart:core | 188 // dart:core |
116 // | 189 // |
117 TestTypeProvider provider = new TestTypeProvider(); | 190 TestTypeProvider provider = new TestTypeProvider(); |
118 CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl("core.d
art"); | 191 CompilationUnitElementImpl coreUnit = new CompilationUnitElementImpl("core.d
art"); |
119 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE); | 192 Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE); |
120 coreContext.setContents(coreSource, ""); | 193 coreContext.setContents(coreSource, ""); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 false, | 319 false, |
247 true, | 320 true, |
248 htmlDocumentElement.getType()); | 321 htmlDocumentElement.getType()); |
249 htmlUnit.setTopLevelVariables(new TopLevelVariableElement[] {document}); | 322 htmlUnit.setTopLevelVariables(new TopLevelVariableElement[] {document}); |
250 htmlUnit.setAccessors(new PropertyAccessorElement[] {document.getGetter()}); | 323 htmlUnit.setAccessors(new PropertyAccessorElement[] {document.getGetter()}); |
251 LibraryElementImpl htmlLibrary = new LibraryElementImpl(coreContext, library
Identifier( | 324 LibraryElementImpl htmlLibrary = new LibraryElementImpl(coreContext, library
Identifier( |
252 "dart", | 325 "dart", |
253 "dom", | 326 "dom", |
254 "html")); | 327 "html")); |
255 htmlLibrary.setDefiningCompilationUnit(htmlUnit); | 328 htmlLibrary.setDefiningCompilationUnit(htmlUnit); |
| 329 // |
| 330 // dart:math |
| 331 // |
| 332 CompilationUnitElementImpl mathUnit = new CompilationUnitElementImpl("math.d
art"); |
| 333 Source mathSource = sourceFactory.forUri(DART_MATH); |
| 334 coreContext.setContents(mathSource, ""); |
| 335 mathUnit.setSource(mathSource); |
256 | 336 |
| 337 FunctionElement cosElement = functionElement( |
| 338 "cos", |
| 339 provider.getDoubleType().getElement(), |
| 340 new ClassElement[] {provider.getNumType().getElement()}, |
| 341 new ClassElement[] {}); |
| 342 TopLevelVariableElement ln10Element = topLevelVariableElement( |
| 343 "LN10", |
| 344 true, |
| 345 false, |
| 346 provider.getDoubleType()); |
| 347 TopLevelVariableElement piElement = topLevelVariableElement( |
| 348 "PI", |
| 349 true, |
| 350 false, |
| 351 provider.getDoubleType()); |
| 352 ClassElementImpl randomElement = classElement("Random"); |
| 353 randomElement.setAbstract(true); |
| 354 ConstructorElementImpl randomConstructor = constructorElement(randomElement,
null); |
| 355 randomConstructor.setFactory(true); |
| 356 ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0); |
| 357 seedParam.setParameterKind(ParameterKind.POSITIONAL); |
| 358 seedParam.setType(provider.getIntType()); |
| 359 randomConstructor.setParameters(new ParameterElement[] {seedParam}); |
| 360 randomElement.setConstructors(new ConstructorElement[] {randomConstructor}); |
| 361 FunctionElement sinElement = functionElement( |
| 362 "sin", |
| 363 provider.getDoubleType().getElement(), |
| 364 new ClassElement[] {provider.getNumType().getElement()}, |
| 365 new ClassElement[] {}); |
| 366 FunctionElement sqrtElement = functionElement( |
| 367 "sqrt", |
| 368 provider.getDoubleType().getElement(), |
| 369 new ClassElement[] {provider.getNumType().getElement()}, |
| 370 new ClassElement[] {}); |
| 371 |
| 372 mathUnit.setAccessors(new PropertyAccessorElement[] { |
| 373 ln10Element.getGetter(), piElement.getGetter()}); |
| 374 mathUnit.setFunctions(new FunctionElement[] {cosElement, sinElement, sqrtEle
ment}); |
| 375 mathUnit.setTopLevelVariables(new TopLevelVariableElement[] {ln10Element, pi
Element}); |
| 376 mathUnit.setTypes(new ClassElement[] {randomElement}); |
| 377 |
| 378 LibraryElementImpl mathLibrary = new LibraryElementImpl(coreContext, library
Identifier( |
| 379 "dart", |
| 380 "math")); |
| 381 mathLibrary.setDefiningCompilationUnit(mathUnit); |
| 382 // |
| 383 // Set empty sources for the rest of the libraries. |
| 384 // |
| 385 Source source = sourceFactory.forUri(DART_INTERCEPTORS); |
| 386 coreContext.setContents(source, ""); |
| 387 source = sourceFactory.forUri(DART_JS_HELPER); |
| 388 coreContext.setContents(source, ""); |
| 389 // |
| 390 // Record the elements. |
| 391 // |
257 HashMap<Source, LibraryElement> elementMap = new HashMap<Source, LibraryElem
ent>(); | 392 HashMap<Source, LibraryElement> elementMap = new HashMap<Source, LibraryElem
ent>(); |
258 elementMap.put(coreSource, coreLibrary); | 393 elementMap.put(coreSource, coreLibrary); |
259 elementMap.put(asyncSource, asyncLibrary); | 394 elementMap.put(asyncSource, asyncLibrary); |
260 elementMap.put(htmlSource, htmlLibrary); | 395 elementMap.put(htmlSource, htmlLibrary); |
| 396 elementMap.put(mathSource, mathLibrary); |
261 context.recordLibraryElements(elementMap); | 397 context.recordLibraryElements(elementMap); |
262 return context; | 398 return context; |
263 } | 399 } |
264 | 400 |
265 /** | 401 /** |
266 * Prevent the creation of instances of this class. | 402 * Prevent the creation of instances of this class. |
267 */ | 403 */ |
268 private AnalysisContextFactory() { | 404 private AnalysisContextFactory() { |
269 } | 405 } |
270 } | 406 } |
OLD | NEW |