Refactor common portions of the two SDK implementations into a base class
R=pquitslund@google.com Review URL: https://codereview.chromium.org/2069483002 .
This commit is contained in:
@@ -10,14 +10,13 @@ import 'dart:core' hide Resource;
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/source/package_map_provider.dart'
|
||||
show PackageMapProvider;
|
||||
import 'package:analyzer/src/context/context.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart';
|
||||
import 'package:analyzer/src/generated/java_core.dart';
|
||||
import 'package:analyzer/src/generated/java_engine.dart';
|
||||
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
|
||||
import 'package:analyzer/src/generated/sdk.dart';
|
||||
import 'package:analyzer/src/generated/sdk_io.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
|
||||
import 'package:analyzer/src/summary/idl.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
|
||||
const String _DART_COLON_PREFIX = 'dart:';
|
||||
@@ -27,104 +26,28 @@ const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
|
||||
bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null;
|
||||
|
||||
/// An SDK backed by URI mappings derived from an `_embedder.yaml` file.
|
||||
class EmbedderSdk implements DartSdk {
|
||||
/// The resolver associated with this SDK.
|
||||
EmbedderUriResolver _resolver;
|
||||
|
||||
/// The [AnalysisContext] used for this SDK's sources.
|
||||
InternalAnalysisContext _analysisContext;
|
||||
|
||||
final LibraryMap _librariesMap = new LibraryMap();
|
||||
|
||||
class EmbedderSdk extends AbstractDartSdk {
|
||||
final Map<String, String> _urlMappings = new HashMap<String, String>();
|
||||
|
||||
/// Analysis options for this SDK.
|
||||
AnalysisOptions analysisOptions;
|
||||
|
||||
EmbedderSdk([Map<Folder, YamlMap> embedderYamls]) {
|
||||
embedderYamls?.forEach(_processEmbedderYaml);
|
||||
_resolver = new EmbedderUriResolver._forSdk(this);
|
||||
}
|
||||
|
||||
@override
|
||||
AnalysisContext get context {
|
||||
if (_analysisContext == null) {
|
||||
_analysisContext = new SdkAnalysisContext(analysisOptions);
|
||||
SourceFactory factory = new SourceFactory([_resolver]);
|
||||
_analysisContext.sourceFactory = factory;
|
||||
|
||||
ChangeSet changeSet = new ChangeSet();
|
||||
for (String uri in uris) {
|
||||
changeSet.addedSource(factory.forUri(uri));
|
||||
}
|
||||
_analysisContext.applyChanges(changeSet);
|
||||
}
|
||||
return _analysisContext;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SdkLibrary> get sdkLibraries => _librariesMap.sdkLibraries;
|
||||
|
||||
// TODO(danrubel) Determine SDK version
|
||||
@override
|
||||
String get sdkVersion => '0';
|
||||
|
||||
@override
|
||||
List<String> get uris => _librariesMap.uris;
|
||||
|
||||
/// The url mappings for this SDK.
|
||||
Map<String, String> get urlMappings => _urlMappings;
|
||||
|
||||
@override
|
||||
Source fromFileUri(Uri uri) {
|
||||
JavaFile file = new JavaFile.fromUri(uri);
|
||||
String filePath = file.getAbsolutePath();
|
||||
|
||||
String path;
|
||||
for (SdkLibrary library in _librariesMap.sdkLibraries) {
|
||||
String libraryPath = library.path.replaceAll('/', JavaFile.separator);
|
||||
if (filePath == libraryPath) {
|
||||
path = library.shortName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (path == null) {
|
||||
for (SdkLibrary library in _librariesMap.sdkLibraries) {
|
||||
String libraryPath = library.path.replaceAll('/', JavaFile.separator);
|
||||
int index = libraryPath.lastIndexOf(JavaFile.separator);
|
||||
if (index == -1) {
|
||||
continue;
|
||||
}
|
||||
String prefix = libraryPath.substring(0, index + 1);
|
||||
if (!filePath.startsWith(prefix)) {
|
||||
continue;
|
||||
}
|
||||
var relPath = filePath
|
||||
.substring(prefix.length)
|
||||
.replaceAll(JavaFile.separator, '/');
|
||||
path = '${library.shortName}/$relPath';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (path != null) {
|
||||
try {
|
||||
return new FileBasedSource(file, parseUriWithException(path));
|
||||
} on URISyntaxException catch (exception, stackTrace) {
|
||||
AnalysisEngine.instance.logger.logInformation(
|
||||
"Failed to create URI: $path",
|
||||
new CaughtException(exception, stackTrace));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
String getRelativePathFromFile(JavaFile file) => file.getAbsolutePath();
|
||||
|
||||
@override
|
||||
SdkLibrary getSdkLibrary(String dartUri) => _librariesMap.getLibrary(dartUri);
|
||||
PackageBundle getSummarySdkBundle(bool strongMode) => null;
|
||||
|
||||
@override
|
||||
Source mapDartUri(String dartUri) {
|
||||
FileBasedSource internalMapDartUri(String dartUri) {
|
||||
String libraryName;
|
||||
String relativePath;
|
||||
int index = dartUri.indexOf('/');
|
||||
@@ -173,7 +96,7 @@ class EmbedderSdk implements DartSdk {
|
||||
_urlMappings[name] = libPath;
|
||||
SdkLibraryImpl library = new SdkLibraryImpl(name);
|
||||
library.path = libPath;
|
||||
_librariesMap.setLibrary(name, library);
|
||||
libraryMap.setLibrary(name, library);
|
||||
}
|
||||
|
||||
/// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the
|
||||
@@ -211,8 +134,8 @@ class EmbedderUriResolver implements DartUriResolver {
|
||||
|
||||
/// Construct a [EmbedderUriResolver] from a package map
|
||||
/// (see [PackageMapProvider]).
|
||||
EmbedderUriResolver(Map<Folder, YamlMap> embedderMap) :
|
||||
this._forSdk(new EmbedderSdk(embedderMap));
|
||||
EmbedderUriResolver(Map<Folder, YamlMap> embedderMap)
|
||||
: this._forSdk(new EmbedderSdk(embedderMap));
|
||||
|
||||
/// (Provisional API.)
|
||||
EmbedderUriResolver._forSdk(this._embedderSdk) {
|
||||
|
||||
@@ -24,6 +24,205 @@ import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
|
||||
import 'package:analyzer/src/summary/summary_sdk.dart';
|
||||
import 'package:path/path.dart' as pathos;
|
||||
|
||||
/**
|
||||
* An abstract implementation of a Dart SDK in which the available libraries are
|
||||
* stored in a library map. Subclasses are responsible for populating the
|
||||
* library map.
|
||||
*/
|
||||
abstract class AbstractDartSdk implements DartSdk {
|
||||
/**
|
||||
* A mapping from Dart library URI's to the library represented by that URI.
|
||||
*/
|
||||
LibraryMap libraryMap = new LibraryMap();
|
||||
|
||||
/**
|
||||
* The [AnalysisOptions] to use to create the [context].
|
||||
*/
|
||||
AnalysisOptions _analysisOptions;
|
||||
|
||||
/**
|
||||
* The flag that specifies whether an SDK summary should be used. This is a
|
||||
* temporary flag until summaries are enabled by default.
|
||||
*/
|
||||
bool _useSummary = false;
|
||||
|
||||
/**
|
||||
* The [AnalysisContext] which is used for all of the sources in this SDK.
|
||||
*/
|
||||
InternalAnalysisContext _analysisContext;
|
||||
|
||||
/**
|
||||
* The mapping from Dart URI's to the corresponding sources.
|
||||
*/
|
||||
Map<String, Source> _uriToSourceMap = new HashMap<String, Source>();
|
||||
|
||||
/**
|
||||
* Set the [options] for this SDK analysis context. Throw [StateError] if the
|
||||
* context has been already created.
|
||||
*/
|
||||
void set analysisOptions(AnalysisOptions options) {
|
||||
if (_analysisContext != null) {
|
||||
throw new StateError(
|
||||
'Analysis options cannot be changed after context creation.');
|
||||
}
|
||||
_analysisOptions = options;
|
||||
}
|
||||
|
||||
@override
|
||||
AnalysisContext get context {
|
||||
if (_analysisContext == null) {
|
||||
_analysisContext = new SdkAnalysisContext(_analysisOptions);
|
||||
SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
|
||||
_analysisContext.sourceFactory = factory;
|
||||
if (_useSummary) {
|
||||
bool strongMode = _analysisOptions?.strongMode ?? false;
|
||||
PackageBundle sdkBundle = getSummarySdkBundle(strongMode);
|
||||
if (sdkBundle != null) {
|
||||
_analysisContext.resultProvider = new SdkSummaryResultProvider(
|
||||
_analysisContext, sdkBundle, strongMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _analysisContext;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SdkLibrary> get sdkLibraries => libraryMap.sdkLibraries;
|
||||
|
||||
@override
|
||||
List<String> get uris => libraryMap.uris;
|
||||
|
||||
/**
|
||||
* Return `true` if the SDK summary will be used when available.
|
||||
*/
|
||||
bool get useSummary => _useSummary;
|
||||
|
||||
/**
|
||||
* Specify whether SDK summary should be used.
|
||||
*/
|
||||
void set useSummary(bool use) {
|
||||
if (_analysisContext != null) {
|
||||
throw new StateError(
|
||||
'The "useSummary" flag cannot be changed after context creation.');
|
||||
}
|
||||
_useSummary = use;
|
||||
}
|
||||
|
||||
@override
|
||||
Source fromFileUri(Uri uri) {
|
||||
JavaFile file = new JavaFile.fromUri(uri);
|
||||
|
||||
String path = _getPath(file);
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return new FileBasedSource(file, parseUriWithException(path));
|
||||
} on URISyntaxException catch (exception, stackTrace) {
|
||||
AnalysisEngine.instance.logger.logInformation(
|
||||
"Failed to create URI: $path",
|
||||
new CaughtException(exception, stackTrace));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String getRelativePathFromFile(JavaFile file);
|
||||
|
||||
@override
|
||||
SdkLibrary getSdkLibrary(String dartUri) => libraryMap.getLibrary(dartUri);
|
||||
|
||||
/**
|
||||
* Return the [PackageBundle] for this SDK, if it exists, or `null` otherwise.
|
||||
* This method should not be used outside of `analyzer` and `analyzer_cli`
|
||||
* packages.
|
||||
*/
|
||||
PackageBundle getSummarySdkBundle(bool strongMode);
|
||||
|
||||
FileBasedSource internalMapDartUri(String dartUri) {
|
||||
// TODO(brianwilkerson) Figure out how to unify the implementations in the
|
||||
// two subclasses.
|
||||
String libraryName;
|
||||
String relativePath;
|
||||
int index = dartUri.indexOf('/');
|
||||
if (index >= 0) {
|
||||
libraryName = dartUri.substring(0, index);
|
||||
relativePath = dartUri.substring(index + 1);
|
||||
} else {
|
||||
libraryName = dartUri;
|
||||
relativePath = "";
|
||||
}
|
||||
SdkLibrary library = getSdkLibrary(libraryName);
|
||||
if (library == null) {
|
||||
return null;
|
||||
}
|
||||
String srcPath;
|
||||
if (relativePath.isEmpty) {
|
||||
srcPath = library.path;
|
||||
} else {
|
||||
String libraryPath = library.path;
|
||||
int index = libraryPath.lastIndexOf(JavaFile.separator);
|
||||
if (index == -1) {
|
||||
index = libraryPath.lastIndexOf('/');
|
||||
if (index == -1) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
String prefix = libraryPath.substring(0, index + 1);
|
||||
srcPath = '$prefix$relativePath';
|
||||
}
|
||||
String filePath = srcPath.replaceAll('/', JavaFile.separator);
|
||||
try {
|
||||
JavaFile file = new JavaFile(filePath);
|
||||
return new FileBasedSource(file, parseUriWithException(dartUri));
|
||||
} on URISyntaxException {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Source mapDartUri(String dartUri) {
|
||||
Source source = _uriToSourceMap[dartUri];
|
||||
if (source == null) {
|
||||
source = internalMapDartUri(dartUri);
|
||||
_uriToSourceMap[dartUri] = source;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
String _getPath(JavaFile file) {
|
||||
List<SdkLibrary> libraries = libraryMap.sdkLibraries;
|
||||
int length = libraries.length;
|
||||
List<String> paths = new List(length);
|
||||
String filePath = getRelativePathFromFile(file);
|
||||
if (filePath == null) {
|
||||
return null;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
SdkLibrary library = libraries[i];
|
||||
String libraryPath = library.path.replaceAll('/', JavaFile.separator);
|
||||
if (filePath == libraryPath) {
|
||||
return library.shortName;
|
||||
}
|
||||
paths[i] = libraryPath;
|
||||
}
|
||||
for (int i = 0; i < length; i++) {
|
||||
SdkLibrary library = libraries[i];
|
||||
String libraryPath = paths[i];
|
||||
int index = libraryPath.lastIndexOf(JavaFile.separator);
|
||||
if (index >= 0) {
|
||||
String prefix = libraryPath.substring(0, index + 1);
|
||||
if (filePath.startsWith(prefix)) {
|
||||
String relPath = filePath
|
||||
.substring(prefix.length)
|
||||
.replaceAll(JavaFile.separator, '/');
|
||||
return '${library.shortName}/$relPath';
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Dart SDK installed in a specified directory. Typical Dart SDK layout is
|
||||
* something like...
|
||||
@@ -40,7 +239,7 @@ import 'package:path/path.dart' as pathos;
|
||||
* ... Dart utilities ...
|
||||
* Chromium/ <-- Dartium typically exists in a sibling directory
|
||||
*/
|
||||
class DirectoryBasedDartSdk implements DartSdk {
|
||||
class DirectoryBasedDartSdk extends AbstractDartSdk {
|
||||
/**
|
||||
* The default SDK, or `null` if the default SDK either has not yet been
|
||||
* created or cannot be created for some reason.
|
||||
@@ -192,11 +391,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
return sdkDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* The [AnalysisContext] which is used for all of the sources in this sdk.
|
||||
*/
|
||||
InternalAnalysisContext _analysisContext;
|
||||
|
||||
/**
|
||||
* The directory containing the SDK.
|
||||
*/
|
||||
@@ -207,11 +401,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
*/
|
||||
JavaFile _libraryDirectory;
|
||||
|
||||
/**
|
||||
* The flag that specifies whether SDK summary should be used.
|
||||
*/
|
||||
bool _useSummary = false;
|
||||
|
||||
/**
|
||||
* The revision number of this SDK, or `"0"` if the revision number cannot be
|
||||
* discovered.
|
||||
@@ -238,21 +427,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
*/
|
||||
JavaFile _vmExecutable;
|
||||
|
||||
/**
|
||||
* A mapping from Dart library URI's to the library represented by that URI.
|
||||
*/
|
||||
LibraryMap _libraryMap;
|
||||
|
||||
/**
|
||||
* The mapping from Dart URI's to the corresponding sources.
|
||||
*/
|
||||
Map<String, Source> _uriToSourceMap = new HashMap<String, Source>();
|
||||
|
||||
/**
|
||||
* The [AnalysisOptions] to use to create the [context].
|
||||
*/
|
||||
AnalysisOptions _analysisOptions;
|
||||
|
||||
/**
|
||||
* Initialize a newly created SDK to represent the Dart SDK installed in the
|
||||
* [sdkDirectory]. The flag [useDart2jsPaths] is `true` if the dart2js path
|
||||
@@ -260,37 +434,7 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
*/
|
||||
DirectoryBasedDartSdk(JavaFile sdkDirectory, [bool useDart2jsPaths = false]) {
|
||||
this._sdkDirectory = sdkDirectory.getAbsoluteFile();
|
||||
_libraryMap = initialLibraryMap(useDart2jsPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the [options] for this SDK analysis context. Throw [StateError] if the
|
||||
* context has been already created.
|
||||
*/
|
||||
void set analysisOptions(AnalysisOptions options) {
|
||||
if (_analysisContext != null) {
|
||||
throw new StateError(
|
||||
'Analysis options cannot be changed after context creation.');
|
||||
}
|
||||
_analysisOptions = options;
|
||||
}
|
||||
|
||||
@override
|
||||
AnalysisContext get context {
|
||||
if (_analysisContext == null) {
|
||||
_analysisContext = new SdkAnalysisContext(_analysisOptions);
|
||||
SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
|
||||
_analysisContext.sourceFactory = factory;
|
||||
if (_useSummary) {
|
||||
PackageBundle sdkBundle = getSummarySdkBundle();
|
||||
if (sdkBundle != null) {
|
||||
bool strongMode = _analysisOptions?.strongMode ?? false;
|
||||
_analysisContext.resultProvider = new SdkSummaryResultProvider(
|
||||
_analysisContext, sdkBundle, strongMode);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _analysisContext;
|
||||
libraryMap = initialLibraryMap(useDart2jsPaths);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,9 +530,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
return _pubExecutable;
|
||||
}
|
||||
|
||||
@override
|
||||
List<SdkLibrary> get sdkLibraries => _libraryMap.sdkLibraries;
|
||||
|
||||
/**
|
||||
* Return the revision number of this SDK, or `"0"` if the revision number
|
||||
* cannot be discovered.
|
||||
@@ -411,25 +552,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
return _sdkVersion;
|
||||
}
|
||||
|
||||
@override
|
||||
List<String> get uris => _libraryMap.uris;
|
||||
|
||||
/**
|
||||
* Whether an SDK summary should be used.
|
||||
*/
|
||||
bool get useSummary => _useSummary;
|
||||
|
||||
/**
|
||||
* Specify whether SDK summary should be used.
|
||||
*/
|
||||
void set useSummary(bool use) {
|
||||
if (_analysisContext != null) {
|
||||
throw new StateError(
|
||||
'The "useSummary" flag cannot be changed after context creation.');
|
||||
}
|
||||
_useSummary = use;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the file containing the VM executable.
|
||||
*/
|
||||
@@ -470,45 +592,6 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
_LIBRARIES_FILE);
|
||||
}
|
||||
|
||||
@override
|
||||
Source fromFileUri(Uri uri) {
|
||||
JavaFile file = new JavaFile.fromUri(uri);
|
||||
String filePath = file.getAbsolutePath();
|
||||
String libPath = libraryDirectory.getAbsolutePath();
|
||||
if (!filePath.startsWith("$libPath${JavaFile.separator}")) {
|
||||
return null;
|
||||
}
|
||||
filePath = filePath.substring(libPath.length + 1);
|
||||
for (SdkLibrary library in _libraryMap.sdkLibraries) {
|
||||
String libraryPath = library.path;
|
||||
if (filePath.replaceAll('\\', '/') == libraryPath) {
|
||||
String path = library.shortName;
|
||||
try {
|
||||
return new FileBasedSource(file, parseUriWithException(path));
|
||||
} on URISyntaxException catch (exception, stackTrace) {
|
||||
AnalysisEngine.instance.logger.logInformation(
|
||||
"Failed to create URI: $path",
|
||||
new CaughtException(exception, stackTrace));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
libraryPath = new JavaFile(library.path).getParent();
|
||||
if (filePath.startsWith("$libraryPath${JavaFile.separator}")) {
|
||||
String path =
|
||||
"${library.shortName}/${filePath.substring(libraryPath.length + 1)}";
|
||||
try {
|
||||
return new FileBasedSource(file, parseUriWithException(path));
|
||||
} on URISyntaxException catch (exception, stackTrace) {
|
||||
AnalysisEngine.instance.logger.logInformation(
|
||||
"Failed to create URI: $path",
|
||||
new CaughtException(exception, stackTrace));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the directory where dartium can be found (the directory that will be
|
||||
* the working directory if Dartium is invoked without changing the default),
|
||||
@@ -536,16 +619,22 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
}
|
||||
|
||||
@override
|
||||
SdkLibrary getSdkLibrary(String dartUri) => _libraryMap.getLibrary(dartUri);
|
||||
String getRelativePathFromFile(JavaFile file) {
|
||||
String filePath = file.getAbsolutePath();
|
||||
String libPath = libraryDirectory.getAbsolutePath();
|
||||
if (!filePath.startsWith("$libPath${JavaFile.separator}")) {
|
||||
return null;
|
||||
}
|
||||
return filePath.substring(libPath.length + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the [PackageBundle] for this SDK, if it exists, or `null` otherwise.
|
||||
* This method should not be used outside of `analyzer` and `analyzer_cli`
|
||||
* packages.
|
||||
*/
|
||||
PackageBundle getSummarySdkBundle() {
|
||||
PackageBundle getSummarySdkBundle(bool strongMode) {
|
||||
String rootPath = directory.getAbsolutePath();
|
||||
bool strongMode = _analysisOptions?.strongMode ?? false;
|
||||
String name = strongMode ? 'strong.sum' : 'spec.sum';
|
||||
String path = pathos.join(rootPath, 'lib', '_internal', name);
|
||||
try {
|
||||
@@ -589,16 +678,7 @@ class DirectoryBasedDartSdk implements DartSdk {
|
||||
}
|
||||
|
||||
@override
|
||||
Source mapDartUri(String dartUri) {
|
||||
Source source = _uriToSourceMap[dartUri];
|
||||
if (source == null) {
|
||||
source = _mapDartUri(dartUri);
|
||||
_uriToSourceMap[dartUri] = source;
|
||||
}
|
||||
return source;
|
||||
}
|
||||
|
||||
FileBasedSource _mapDartUri(String dartUri) {
|
||||
FileBasedSource internalMapDartUri(String dartUri) {
|
||||
String libraryName;
|
||||
String relativePath;
|
||||
int index = dartUri.indexOf('/');
|
||||
|
||||
@@ -9,149 +9,59 @@ import 'dart:core' hide Resource;
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/file_system/memory_file_system.dart';
|
||||
import 'package:analyzer/source/embedder.dart';
|
||||
import 'package:analyzer/src/generated/sdk.dart';
|
||||
import 'package:analyzer/src/generated/source.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:unittest/unittest.dart';
|
||||
|
||||
import '../reflective_tests.dart';
|
||||
import '../resource_utils.dart';
|
||||
import '../utils.dart';
|
||||
|
||||
main() {
|
||||
group('EmbedderUriResolverTest', () {
|
||||
setUp(() {
|
||||
initializeTestEnvironment(path.context);
|
||||
buildResourceProvider();
|
||||
});
|
||||
tearDown(() {
|
||||
initializeTestEnvironment();
|
||||
clearResourceProvider();
|
||||
});
|
||||
test('test_NullEmbedderYamls', () {
|
||||
var resolver = new EmbedderUriResolver(null);
|
||||
expect(resolver.length, 0);
|
||||
});
|
||||
test('test_NoEmbedderYamls', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/empty')]
|
||||
});
|
||||
expect(locator.embedderYamls.length, 0);
|
||||
});
|
||||
test('test_EmbedderYaml', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
|
||||
expectResolved(dartUri, posixPath) {
|
||||
Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
|
||||
expect(source, isNotNull, reason: dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
// We have five mappings.
|
||||
expect(resolver.length, 5);
|
||||
// Check that they map to the correct paths.
|
||||
expectResolved('dart:core', '/tmp/core.dart');
|
||||
expectResolved('dart:fox', '/tmp/slippy.dart');
|
||||
expectResolved('dart:bear', '/tmp/grizzly.dart');
|
||||
expectResolved('dart:relative', '/relative.dart');
|
||||
expectResolved('dart:deep', '/tmp/deep/directory/file.dart');
|
||||
});
|
||||
test('test_BadYAML', () {
|
||||
var locator = new EmbedderYamlLocator(null);
|
||||
locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
|
||||
expect(locator.embedderYamls.length, 0);
|
||||
});
|
||||
test('test_restoreAbsolute', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
|
||||
expectRestore(String dartUri, [String expected]) {
|
||||
var parsedUri = Uri.parse(dartUri);
|
||||
var source = resolver.resolveAbsolute(parsedUri);
|
||||
expect(source, isNotNull);
|
||||
// Restore source's uri.
|
||||
var restoreUri = resolver.restoreAbsolute(source);
|
||||
expect(restoreUri, isNotNull, reason: dartUri);
|
||||
// Verify that it is 'dart:fox'.
|
||||
expect(restoreUri.toString(), expected ?? dartUri);
|
||||
List<String> split = (expected ?? dartUri).split(':');
|
||||
expect(restoreUri.scheme, split[0]);
|
||||
expect(restoreUri.path, split[1]);
|
||||
}
|
||||
|
||||
expectRestore('dart:deep');
|
||||
expectRestore('dart:deep/file.dart', 'dart:deep');
|
||||
expectRestore('dart:deep/part.dart');
|
||||
expectRestore('dart:deep/deep/file.dart');
|
||||
});
|
||||
|
||||
test('test_EmbedderSdk_fromFileUri', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
var sdk = resolver.dartSdk;
|
||||
|
||||
expectSource(String posixPath, String dartUri) {
|
||||
var uri = Uri.parse(posixToOSFileUri(posixPath));
|
||||
var source = sdk.fromFileUri(uri);
|
||||
expect(source, isNotNull, reason: posixPath);
|
||||
expect(source.uri.toString(), dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
expectSource('/tmp/slippy.dart', 'dart:fox');
|
||||
expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
|
||||
expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
|
||||
});
|
||||
test('test_EmbedderSdk_getSdkLibrary', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
var sdk = resolver.dartSdk;
|
||||
var lib = sdk.getSdkLibrary('dart:fox');
|
||||
expect(lib, isNotNull);
|
||||
expect(lib.path, posixToOSPath('/tmp/slippy.dart'));
|
||||
expect(lib.shortName, 'dart:fox');
|
||||
});
|
||||
test('test_EmbedderSdk_mapDartUri', () {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
var sdk = resolver.dartSdk;
|
||||
|
||||
expectSource(String dartUri, String posixPath) {
|
||||
var source = sdk.mapDartUri(dartUri);
|
||||
expect(source, isNotNull, reason: posixPath);
|
||||
expect(source.uri.toString(), dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
expectSource('dart:core', '/tmp/core.dart');
|
||||
expectSource('dart:fox', '/tmp/slippy.dart');
|
||||
expectSource('dart:deep', '/tmp/deep/directory/file.dart');
|
||||
expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart');
|
||||
});
|
||||
});
|
||||
runReflectiveTests(DartUriResolverTest);
|
||||
runReflectiveTests(EmbedderSdkTest);
|
||||
runReflectiveTests(EmbedderUriResolverTest);
|
||||
runReflectiveTests(EmbedderYamlLocatorTest);
|
||||
}
|
||||
|
||||
TestPathTranslator pathTranslator;
|
||||
ResourceProvider resourceProvider;
|
||||
@reflectiveTest
|
||||
class DartUriResolverTest extends EmbedderRelatedTest {
|
||||
void test_embedderYaml() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
|
||||
DartUriResolver resolver = new DartUriResolver(sdk);
|
||||
|
||||
buildResourceProvider() {
|
||||
var rawProvider = new MemoryResourceProvider(isWindows: isWindows);
|
||||
resourceProvider = new TestResourceProvider(rawProvider);
|
||||
pathTranslator = new TestPathTranslator(rawProvider)
|
||||
..newFolder('/empty')
|
||||
..newFolder('/tmp')
|
||||
..newFile(
|
||||
'/tmp/_embedder.yaml',
|
||||
r'''
|
||||
void expectResolved(dartUri, posixPath) {
|
||||
Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
|
||||
expect(source, isNotNull, reason: dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
// Check that they map to the correct paths.
|
||||
expectResolved('dart:core', '/tmp/core.dart');
|
||||
expectResolved('dart:fox', '/tmp/slippy.dart');
|
||||
expectResolved('dart:bear', '/tmp/grizzly.dart');
|
||||
expectResolved('dart:relative', '/relative.dart');
|
||||
expectResolved('dart:deep', '/tmp/deep/directory/file.dart');
|
||||
}
|
||||
}
|
||||
|
||||
abstract class EmbedderRelatedTest {
|
||||
TestPathTranslator pathTranslator;
|
||||
ResourceProvider resourceProvider;
|
||||
|
||||
buildResourceProvider() {
|
||||
MemoryResourceProvider rawProvider =
|
||||
new MemoryResourceProvider(isWindows: isWindows);
|
||||
resourceProvider = new TestResourceProvider(rawProvider);
|
||||
pathTranslator = new TestPathTranslator(rawProvider)
|
||||
..newFolder('/empty')
|
||||
..newFolder('/tmp')
|
||||
..newFile(
|
||||
'/tmp/_embedder.yaml',
|
||||
r'''
|
||||
embedded_libs:
|
||||
"dart:core" : "core.dart"
|
||||
"dart:fox": "slippy.dart"
|
||||
@@ -160,9 +70,161 @@ embedded_libs:
|
||||
"dart:deep": "deep/directory/file.dart"
|
||||
"fart:loudly": "nomatter.dart"
|
||||
''');
|
||||
}
|
||||
|
||||
clearResourceProvider() {
|
||||
resourceProvider = null;
|
||||
pathTranslator = null;
|
||||
}
|
||||
|
||||
void setUp() {
|
||||
initializeTestEnvironment(path.context);
|
||||
buildResourceProvider();
|
||||
}
|
||||
|
||||
void tearDown() {
|
||||
initializeTestEnvironment();
|
||||
clearResourceProvider();
|
||||
}
|
||||
}
|
||||
|
||||
clearResourceProvider() {
|
||||
resourceProvider = null;
|
||||
pathTranslator = null;
|
||||
@reflectiveTest
|
||||
class EmbedderSdkTest extends EmbedderRelatedTest {
|
||||
void test_creation() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
|
||||
|
||||
expect(sdk.urlMappings, hasLength(5));
|
||||
}
|
||||
|
||||
void test_fromFileUri() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
|
||||
|
||||
expectSource(String posixPath, String dartUri) {
|
||||
Uri uri = Uri.parse(posixToOSFileUri(posixPath));
|
||||
Source source = sdk.fromFileUri(uri);
|
||||
expect(source, isNotNull, reason: posixPath);
|
||||
expect(source.uri.toString(), dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
expectSource('/tmp/slippy.dart', 'dart:fox');
|
||||
expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
|
||||
expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
|
||||
}
|
||||
|
||||
void test_getSdkLibrary() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
|
||||
|
||||
SdkLibrary lib = sdk.getSdkLibrary('dart:fox');
|
||||
expect(lib, isNotNull);
|
||||
expect(lib.path, posixToOSPath('/tmp/slippy.dart'));
|
||||
expect(lib.shortName, 'dart:fox');
|
||||
}
|
||||
|
||||
void test_mapDartUri() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
EmbedderSdk sdk = new EmbedderSdk(locator.embedderYamls);
|
||||
|
||||
void expectSource(String dartUri, String posixPath) {
|
||||
Source source = sdk.mapDartUri(dartUri);
|
||||
expect(source, isNotNull, reason: posixPath);
|
||||
expect(source.uri.toString(), dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
expectSource('dart:core', '/tmp/core.dart');
|
||||
expectSource('dart:fox', '/tmp/slippy.dart');
|
||||
expectSource('dart:deep', '/tmp/deep/directory/file.dart');
|
||||
expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class EmbedderUriResolverTest extends EmbedderRelatedTest {
|
||||
void test_embedderYaml() {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
|
||||
expectResolved(dartUri, posixPath) {
|
||||
Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
|
||||
expect(source, isNotNull, reason: dartUri);
|
||||
expect(source.fullName, posixToOSPath(posixPath));
|
||||
}
|
||||
|
||||
// We have five mappings.
|
||||
expect(resolver, hasLength(5));
|
||||
// Check that they map to the correct paths.
|
||||
expectResolved('dart:core', '/tmp/core.dart');
|
||||
expectResolved('dart:fox', '/tmp/slippy.dart');
|
||||
expectResolved('dart:bear', '/tmp/grizzly.dart');
|
||||
expectResolved('dart:relative', '/relative.dart');
|
||||
expectResolved('dart:deep', '/tmp/deep/directory/file.dart');
|
||||
}
|
||||
|
||||
void test_nullEmbedderYamls() {
|
||||
var resolver = new EmbedderUriResolver(null);
|
||||
expect(resolver, hasLength(0));
|
||||
}
|
||||
|
||||
void test_restoreAbsolute() {
|
||||
var locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
var resolver = new EmbedderUriResolver(locator.embedderYamls);
|
||||
|
||||
expectRestore(String dartUri, [String expected]) {
|
||||
var parsedUri = Uri.parse(dartUri);
|
||||
var source = resolver.resolveAbsolute(parsedUri);
|
||||
expect(source, isNotNull);
|
||||
// Restore source's uri.
|
||||
var restoreUri = resolver.restoreAbsolute(source);
|
||||
expect(restoreUri, isNotNull, reason: dartUri);
|
||||
// Verify that it is 'dart:fox'.
|
||||
expect(restoreUri.toString(), expected ?? dartUri);
|
||||
List<String> split = (expected ?? dartUri).split(':');
|
||||
expect(restoreUri.scheme, split[0]);
|
||||
expect(restoreUri.path, split[1]);
|
||||
}
|
||||
|
||||
expectRestore('dart:deep');
|
||||
expectRestore('dart:deep/file.dart', 'dart:deep');
|
||||
expectRestore('dart:deep/part.dart');
|
||||
expectRestore('dart:deep/deep/file.dart');
|
||||
}
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class EmbedderYamlLocatorTest extends EmbedderRelatedTest {
|
||||
void test_empty() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/empty')]
|
||||
});
|
||||
expect(locator.embedderYamls, hasLength(0));
|
||||
}
|
||||
|
||||
void test_invalid() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator(null);
|
||||
locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
|
||||
expect(locator.embedderYamls, hasLength(0));
|
||||
}
|
||||
|
||||
void test_valid() {
|
||||
EmbedderYamlLocator locator = new EmbedderYamlLocator({
|
||||
'fox': [pathTranslator.getResource('/tmp')]
|
||||
});
|
||||
expect(locator.embedderYamls, hasLength(1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ class BuildMode {
|
||||
Driver.createAnalysisOptionsForCommandLineOptions(options);
|
||||
directorySdk.useSummary = !options.buildSummaryOnlyAst;
|
||||
sdk = directorySdk;
|
||||
sdkBundle = directorySdk.getSummarySdkBundle();
|
||||
sdkBundle = directorySdk.getSummarySdkBundle(options.strongMode);
|
||||
}
|
||||
|
||||
// In AST mode include SDK bundle to avoid parsing SDK sources.
|
||||
|
||||
Reference in New Issue
Block a user