Index: editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/context/AnalysisContextFactory.java |
=================================================================== |
--- editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/context/AnalysisContextFactory.java (revision 40542) |
+++ editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/context/AnalysisContextFactory.java (working copy) |
@@ -22,13 +22,17 @@ |
import com.google.dart.engine.element.PropertyAccessorElement; |
import com.google.dart.engine.element.TopLevelVariableElement; |
import com.google.dart.engine.internal.context.AnalysisContextImpl; |
+import com.google.dart.engine.internal.context.TimestampedData; |
import com.google.dart.engine.internal.element.ClassElementImpl; |
import com.google.dart.engine.internal.element.CompilationUnitElementImpl; |
import com.google.dart.engine.internal.element.ConstructorElementImpl; |
import com.google.dart.engine.internal.element.FunctionTypeAliasElementImpl; |
import com.google.dart.engine.internal.element.LibraryElementImpl; |
+import com.google.dart.engine.internal.element.ParameterElementImpl; |
import com.google.dart.engine.internal.element.TopLevelVariableElementImpl; |
import com.google.dart.engine.internal.resolver.TestTypeProvider; |
+import com.google.dart.engine.internal.sdk.LibraryMap; |
+import com.google.dart.engine.internal.sdk.SdkLibraryImpl; |
import com.google.dart.engine.internal.type.FunctionTypeImpl; |
import com.google.dart.engine.sdk.DartSdk; |
import com.google.dart.engine.sdk.DirectoryBasedDartSdk; |
@@ -38,6 +42,7 @@ |
import com.google.dart.engine.source.SourceFactory; |
import com.google.dart.engine.type.InterfaceType; |
import com.google.dart.engine.type.Type; |
+import com.google.dart.engine.utilities.dart.ParameterKind; |
import static com.google.dart.engine.ast.AstFactory.libraryIdentifier; |
import static com.google.dart.engine.element.ElementFactory.classElement; |
@@ -53,6 +58,7 @@ |
import junit.framework.Assert; |
+import java.io.File; |
import java.util.HashMap; |
/** |
@@ -61,29 +67,75 @@ |
*/ |
public final class AnalysisContextFactory { |
/** |
+ * Instances of the class {@code AnalysisContextForTests} implement an analysis context that has a |
+ * fake SDK that is much smaller and faster for testing purposes. |
+ */ |
+ public static class AnalysisContextForTests extends AnalysisContextImpl { |
+ @Override |
+ public boolean exists(Source source) { |
+ return super.exists(source) || getSourceFactory().getDartSdk().getContext().exists(source); |
+ } |
+ |
+ @Override |
+ public TimestampedData<CharSequence> getContents(Source source) throws Exception { |
+ if (source.isInSystemLibrary()) { |
+ return getSourceFactory().getDartSdk().getContext().getContents(source); |
+ } |
+ return super.getContents(source); |
+ } |
+ |
+ @Override |
+ public long getModificationStamp(Source source) { |
+ if (source.isInSystemLibrary()) { |
+ return getSourceFactory().getDartSdk().getContext().getModificationStamp(source); |
+ } |
+ return super.getModificationStamp(source); |
+ } |
+ |
+ @Override |
+ public void setAnalysisOptions(AnalysisOptions options) { |
+ AnalysisOptions currentOptions = getAnalysisOptions(); |
+ boolean needsRecompute = currentOptions.getAnalyzeFunctionBodies() != options.getAnalyzeFunctionBodies() |
+ || currentOptions.getGenerateSdkErrors() != options.getGenerateSdkErrors() |
+ || currentOptions.getEnableAsync() != options.getEnableAsync() |
+ || currentOptions.getEnableDeferredLoading() != options.getEnableDeferredLoading() |
+ || currentOptions.getEnableEnum() != options.getEnableEnum() |
+ || currentOptions.getDart2jsHint() != options.getDart2jsHint() |
+ || (currentOptions.getHint() && !options.getHint()) |
+ || currentOptions.getPreserveComments() != options.getPreserveComments(); |
+ if (needsRecompute) { |
+ Assert.fail("Cannot set options that cause the sources to be reanalyzed in a test context"); |
+ } |
+ super.setAnalysisOptions(options); |
+ } |
+ |
+ /** |
+ * Set the analysis options, even if they would force re-analysis. This method should only be |
+ * invoked before the fake SDK is initialized. |
+ * |
+ * @param options the analysis options to be set |
+ */ |
+ private void internalSetAnalysisOptions(AnalysisOptions options) { |
+ super.setAnalysisOptions(options); |
+ } |
+ } |
+ |
+ private static final String DART_MATH = "dart:math"; |
+ private static final String DART_INTERCEPTORS = "dart:_interceptors"; |
+ private static final String DART_JS_HELPER = "dart:_js_helper"; |
+ |
+ /** |
+ * The fake SDK used by all of the contexts created by this factory. |
+ */ |
+ private static DirectoryBasedDartSdk FAKE_SDK; |
+ |
+ /** |
* Create an analysis context that has a fake core library already resolved. |
* |
* @return the analysis context that was created |
*/ |
public static AnalysisContextImpl contextWithCore() { |
- AnalysisContextImpl context = new AnalysisContextImpl() { |
- @Override |
- public void setAnalysisOptions(AnalysisOptions options) { |
- AnalysisOptions currentOptions = getAnalysisOptions(); |
- boolean needsRecompute = currentOptions.getAnalyzeFunctionBodies() != options.getAnalyzeFunctionBodies() |
- || currentOptions.getGenerateSdkErrors() != options.getGenerateSdkErrors() |
- || currentOptions.getEnableAsync() != options.getEnableAsync() |
- || currentOptions.getEnableDeferredLoading() != options.getEnableDeferredLoading() |
- || currentOptions.getEnableEnum() != options.getEnableEnum() |
- || currentOptions.getDart2jsHint() != options.getDart2jsHint() |
- || (currentOptions.getHint() && !options.getHint()) |
- || currentOptions.getPreserveComments() != options.getPreserveComments(); |
- if (needsRecompute) { |
- Assert.fail("Cannot set options that cause the sources to be reanalyzed in a test context"); |
- } |
- super.setAnalysisOptions(options); |
- } |
- }; |
+ AnalysisContextForTests context = new AnalysisContextForTests(); |
return initContextWithCore(context); |
} |
@@ -95,8 +147,8 @@ |
* @return the analysis context that was created |
*/ |
public static AnalysisContextImpl contextWithCoreAndOptions(AnalysisOptions options) { |
- AnalysisContextImpl context = new AnalysisContextImpl(); |
- context.setAnalysisOptions(options); |
+ AnalysisContextForTests context = new AnalysisContextForTests(); |
+ context.internalSetAnalysisOptions(options); |
return initContextWithCore(context); |
} |
@@ -107,7 +159,28 @@ |
* @return the analysis context that was created |
*/ |
public static AnalysisContextImpl initContextWithCore(AnalysisContextImpl context) { |
- DirectoryBasedDartSdk sdk = DirectoryBasedDartSdk.getDefaultSdk(); |
+ DirectoryBasedDartSdk sdk = new DirectoryBasedDartSdk(new File("/fake/sdk")) { |
+ @Override |
+ protected LibraryMap initialLibraryMap(boolean useDart2jsPaths) { |
+ LibraryMap map = new LibraryMap(); |
+ addLibrary(map, DART_ASYNC, false, "async.dart"); |
+ addLibrary(map, DART_CORE, false, "core.dart"); |
+ addLibrary(map, DART_HTML, false, "html_dartium.dart"); |
+ addLibrary(map, DART_MATH, false, "math.dart"); |
+ addLibrary(map, DART_INTERCEPTORS, true, "_interceptors.dart"); |
+ addLibrary(map, DART_JS_HELPER, true, "_js_helper.dart"); |
+ return map; |
+ } |
+ |
+ private void addLibrary(LibraryMap map, String uri, boolean isInternal, String path) { |
+ SdkLibraryImpl library = new SdkLibraryImpl(uri); |
+ if (isInternal) { |
+ library.setCategory("Internal"); |
+ } |
+ library.setPath(path); |
+ map.setLibrary(uri, library); |
+ } |
+ }; |
SourceFactory sourceFactory = new SourceFactory(new DartUriResolver(sdk), new FileUriResolver()); |
context.setSourceFactory(sourceFactory); |
AnalysisContext coreContext = sdk.getContext(); |
@@ -253,11 +326,74 @@ |
"dom", |
"html")); |
htmlLibrary.setDefiningCompilationUnit(htmlUnit); |
+ // |
+ // dart:math |
+ // |
+ CompilationUnitElementImpl mathUnit = new CompilationUnitElementImpl("math.dart"); |
+ Source mathSource = sourceFactory.forUri(DART_MATH); |
+ coreContext.setContents(mathSource, ""); |
+ mathUnit.setSource(mathSource); |
+ FunctionElement cosElement = functionElement( |
+ "cos", |
+ provider.getDoubleType().getElement(), |
+ new ClassElement[] {provider.getNumType().getElement()}, |
+ new ClassElement[] {}); |
+ TopLevelVariableElement ln10Element = topLevelVariableElement( |
+ "LN10", |
+ true, |
+ false, |
+ provider.getDoubleType()); |
+ TopLevelVariableElement piElement = topLevelVariableElement( |
+ "PI", |
+ true, |
+ false, |
+ provider.getDoubleType()); |
+ ClassElementImpl randomElement = classElement("Random"); |
+ randomElement.setAbstract(true); |
+ ConstructorElementImpl randomConstructor = constructorElement(randomElement, null); |
+ randomConstructor.setFactory(true); |
+ ParameterElementImpl seedParam = new ParameterElementImpl("seed", 0); |
+ seedParam.setParameterKind(ParameterKind.POSITIONAL); |
+ seedParam.setType(provider.getIntType()); |
+ randomConstructor.setParameters(new ParameterElement[] {seedParam}); |
+ randomElement.setConstructors(new ConstructorElement[] {randomConstructor}); |
+ FunctionElement sinElement = functionElement( |
+ "sin", |
+ provider.getDoubleType().getElement(), |
+ new ClassElement[] {provider.getNumType().getElement()}, |
+ new ClassElement[] {}); |
+ FunctionElement sqrtElement = functionElement( |
+ "sqrt", |
+ provider.getDoubleType().getElement(), |
+ new ClassElement[] {provider.getNumType().getElement()}, |
+ new ClassElement[] {}); |
+ |
+ mathUnit.setAccessors(new PropertyAccessorElement[] { |
+ ln10Element.getGetter(), piElement.getGetter()}); |
+ mathUnit.setFunctions(new FunctionElement[] {cosElement, sinElement, sqrtElement}); |
+ mathUnit.setTopLevelVariables(new TopLevelVariableElement[] {ln10Element, piElement}); |
+ mathUnit.setTypes(new ClassElement[] {randomElement}); |
+ |
+ LibraryElementImpl mathLibrary = new LibraryElementImpl(coreContext, libraryIdentifier( |
+ "dart", |
+ "math")); |
+ mathLibrary.setDefiningCompilationUnit(mathUnit); |
+ // |
+ // Set empty sources for the rest of the libraries. |
+ // |
+ Source source = sourceFactory.forUri(DART_INTERCEPTORS); |
+ coreContext.setContents(source, ""); |
+ source = sourceFactory.forUri(DART_JS_HELPER); |
+ coreContext.setContents(source, ""); |
+ // |
+ // Record the elements. |
+ // |
HashMap<Source, LibraryElement> elementMap = new HashMap<Source, LibraryElement>(); |
elementMap.put(coreSource, coreLibrary); |
elementMap.put(asyncSource, asyncLibrary); |
elementMap.put(htmlSource, htmlLibrary); |
+ elementMap.put(mathSource, mathLibrary); |
context.recordLibraryElements(elementMap); |
return context; |
} |