mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 02:17:14 +00:00
Package map processing abstraction.
Babysteps towards a cleaner context creation story. Comments welcome! BUG= R=brianwilkerson@google.com Review URL: https://codereview.chromium.org/2043963004 .
This commit is contained in:
parent
e3e72aeb01
commit
995a19b26f
136
pkg/analyzer/lib/src/context/context_factory.dart
Normal file
136
pkg/analyzer/lib/src/context/context_factory.dart
Normal file
|
@ -0,0 +1,136 @@
|
|||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library analyzer.src.context_factory;
|
||||
|
||||
import 'dart:convert';
|
||||
import 'dart:core' hide Resource;
|
||||
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/src/generated/sdk.dart';
|
||||
import 'package:yaml/yaml.dart';
|
||||
import 'package:analyzer/src/generated/engine.dart';
|
||||
import 'dart:io' as io;
|
||||
|
||||
/// (Placeholder)
|
||||
abstract class ContextFactory {
|
||||
/// Create an analysis context for the given [source] directory or file, with
|
||||
/// the given [defaultOptions].
|
||||
AnalysisContext createContext(
|
||||
io.FileSystemEntity source, AnalysisOptions defaultOptions);
|
||||
}
|
||||
|
||||
/// Processes package maps, extracting SDK embedders and extenders, creating a
|
||||
/// consolidated [libraryMap].
|
||||
class PackageMapProcessor {
|
||||
static const String _EMBEDDED_LIB_MAP_KEY = 'embedded_libs';
|
||||
static const String _EMBEDDER_FILE_NAME = '_embedder.yaml';
|
||||
static const String _SDK_EXT_NAME = '_sdkext';
|
||||
|
||||
/// Map of processed embedder libraries.
|
||||
final LibraryMap embeddedLibraries = new LibraryMap();
|
||||
|
||||
/// Map of processed SDK extension libraries.
|
||||
final LibraryMap extendedLibraries = new LibraryMap();
|
||||
|
||||
/// Combined map of processed libraries.
|
||||
LibraryMap get libraryMap {
|
||||
LibraryMap libraryMap = new LibraryMap();
|
||||
|
||||
// Add extenders first, allowing for overwrite by embedders who take precedence.
|
||||
for (String uri in extendedLibraries.uris) {
|
||||
libraryMap.setLibrary(uri, extendedLibraries.getLibrary(uri));
|
||||
}
|
||||
for (String uri in embeddedLibraries.uris) {
|
||||
libraryMap.setLibrary(uri, embeddedLibraries.getLibrary(uri));
|
||||
}
|
||||
return libraryMap;
|
||||
}
|
||||
|
||||
/// Create a processor for the given [packageMap].
|
||||
PackageMapProcessor(Map<String, List<Folder>> packageMap) {
|
||||
packageMap?.forEach(_processPackage);
|
||||
}
|
||||
|
||||
/// Whether the package map contains an SDK embedder.
|
||||
bool get hasEmbedder => embeddedLibraries.size() > 0;
|
||||
|
||||
/// Whether the package map contains an SDK extension.
|
||||
bool get hasSdkExtension => extendedLibraries.size() > 0;
|
||||
|
||||
void _processEmbedderYaml(String embedderYaml, Folder libDir) {
|
||||
try {
|
||||
YamlNode map = loadYaml(embedderYaml);
|
||||
if (map is YamlMap) {
|
||||
YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
|
||||
if (embedded_libs is YamlMap) {
|
||||
embedded_libs.forEach(
|
||||
(k, v) => _processMapping(embeddedLibraries, k, v, libDir));
|
||||
}
|
||||
}
|
||||
} catch (_) {
|
||||
// Ignored.
|
||||
}
|
||||
}
|
||||
|
||||
void _processMapping(
|
||||
LibraryMap libraryMap, String name, String file, Folder libDir) {
|
||||
if (!_hasDartPrefix(name)) {
|
||||
// SDK libraries must begin with 'dart:'.
|
||||
return;
|
||||
}
|
||||
if (libraryMap.getLibrary(name) != null) {
|
||||
// Libraries can't be redefined.
|
||||
return;
|
||||
}
|
||||
String libPath = libDir.canonicalizePath(file);
|
||||
SdkLibraryImpl library = new SdkLibraryImpl(name)..path = libPath;
|
||||
libraryMap.setLibrary(name, library);
|
||||
}
|
||||
|
||||
void _processPackage(String name, List<Folder> libDirs) {
|
||||
for (Folder libDir in libDirs) {
|
||||
String embedderYaml = _readEmbedderYaml(libDir);
|
||||
if (embedderYaml != null) {
|
||||
_processEmbedderYaml(embedderYaml, libDir);
|
||||
}
|
||||
String sdkExt = _readDotSdkExt(libDir);
|
||||
if (sdkExt != null) {
|
||||
_processSdkExt(sdkExt, libDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void _processSdkExt(String sdkExtJSON, Folder libDir) {
|
||||
try {
|
||||
var sdkExt = JSON.decode(sdkExtJSON);
|
||||
if (sdkExt is Map) {
|
||||
sdkExt.forEach(
|
||||
(k, v) => _processMapping(extendedLibraries, k, v, libDir));
|
||||
}
|
||||
} catch (_) {
|
||||
// Ignored.
|
||||
}
|
||||
}
|
||||
|
||||
static bool _hasDartPrefix(String uri) =>
|
||||
uri.startsWith(DartSdk.DART_LIBRARY_PREFIX);
|
||||
|
||||
static String _readDotSdkExt(Folder libDir) =>
|
||||
_safeRead(libDir.getChild(_SDK_EXT_NAME));
|
||||
|
||||
static String _readEmbedderYaml(Folder libDir) =>
|
||||
_safeRead(libDir.getChild(_EMBEDDER_FILE_NAME));
|
||||
|
||||
static String _safeRead(Resource file) {
|
||||
try {
|
||||
if (file is File) {
|
||||
return file.readAsStringSync();
|
||||
}
|
||||
} on FileSystemException {
|
||||
// File can't be read.
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,11 @@ abstract class DartSdk {
|
|||
*/
|
||||
static const String DART_HTML = "dart:html";
|
||||
|
||||
/**
|
||||
* The prefix shared by all dart library URIs.
|
||||
*/
|
||||
static const String DART_LIBRARY_PREFIX = "dart:";
|
||||
|
||||
/**
|
||||
* The version number that is returned when the real version number could not
|
||||
* be determined.
|
||||
|
|
78
pkg/analyzer/test/src/context/context_factory_test.dart
Normal file
78
pkg/analyzer/test/src/context/context_factory_test.dart
Normal file
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
library analyzer.test.src.context.context_factory_test;
|
||||
|
||||
import 'package:analyzer/file_system/file_system.dart';
|
||||
import 'package:analyzer/file_system/memory_file_system.dart';
|
||||
import 'package:analyzer/src/context/context_factory.dart';
|
||||
import 'package:unittest/unittest.dart';
|
||||
|
||||
import '../../reflective_tests.dart';
|
||||
import '../../utils.dart';
|
||||
|
||||
main() {
|
||||
initializeTestEnvironment();
|
||||
runReflectiveTests(PackageMapProcessorTest);
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class PackageMapProcessorTest {
|
||||
static MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
|
||||
|
||||
static Folder empty = resourceProvider.newFolder('/empty');
|
||||
static Folder tmp_sdk_ext = resourceProvider.newFolder('/tmp_sdk_ext');
|
||||
static Folder tmp_embedder = resourceProvider.newFolder('/tmp_embedder');
|
||||
|
||||
static Map<String, List<Folder>> packageMap = <String, List<Folder>>{
|
||||
'empty': [empty],
|
||||
'tmp_embedder': [tmp_embedder],
|
||||
'tmp_sdk_ext': [tmp_sdk_ext]
|
||||
};
|
||||
|
||||
void test_basic_processing() {
|
||||
resourceProvider.newFile(
|
||||
'/tmp_sdk_ext/_sdkext',
|
||||
r'''
|
||||
{
|
||||
"dart:ui": "ui.dart"
|
||||
}''');
|
||||
resourceProvider.newFile(
|
||||
'/tmp_embedder/_embedder.yaml',
|
||||
r'''
|
||||
embedded_libs:
|
||||
"dart:core" : "core.dart"
|
||||
"dart:fox": "slippy.dart"
|
||||
"dart:bear": "grizzly.dart"
|
||||
"dart:relative": "../relative.dart"
|
||||
"dart:deep": "deep/directory/file.dart"
|
||||
''');
|
||||
|
||||
PackageMapProcessor proc = new PackageMapProcessor(packageMap);
|
||||
expect(proc.embeddedLibraries.size(), 5);
|
||||
expect(proc.extendedLibraries.size(), 1);
|
||||
}
|
||||
|
||||
void test_extenders_do_not_override() {
|
||||
resourceProvider.newFile(
|
||||
'/tmp_sdk_ext/_sdkext',
|
||||
r'''
|
||||
{
|
||||
"dart:ui": "ui2.dart"
|
||||
}''');
|
||||
resourceProvider.newFile(
|
||||
'/tmp_embedder/_embedder.yaml',
|
||||
r'''
|
||||
embedded_libs:
|
||||
"dart:core" : "core.dart"
|
||||
"dart:ui": "ui.dart"
|
||||
''');
|
||||
|
||||
PackageMapProcessor proc = new PackageMapProcessor(packageMap);
|
||||
expect(proc.embeddedLibraries.size(), 2);
|
||||
expect(proc.extendedLibraries.size(), 1);
|
||||
expect(proc.libraryMap.size(), 2);
|
||||
expect(proc.libraryMap.getLibrary('dart:ui').path, '/tmp_embedder/ui.dart');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue