Chromium Code Reviews| Index: pkg/analyzer/lib/src/context/context_factory.dart |
| diff --git a/pkg/analyzer/lib/src/context/context_factory.dart b/pkg/analyzer/lib/src/context/context_factory.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4bb877db057aacc72b252748b2902aad3cc6561b |
| --- /dev/null |
| +++ b/pkg/analyzer/lib/src/context/context_factory.dart |
| @@ -0,0 +1,137 @@ |
| +// 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(); |
| + for (String uri in embeddedLibraries.uris) { |
| + libraryMap.setLibrary(uri, embeddedLibraries.getLibrary(uri)); |
| + } |
| + // Extenders extend but do not override. |
| + for (String uri in extendedLibraries.uris) { |
|
Brian Wilkerson
2016/06/07 20:48:48
It would be more efficient to add the extensions t
pquitslund
2016/06/07 20:59:58
Done.
|
| + if (embeddedLibraries.getLibrary(uri) == null) { |
| + libraryMap.setLibrary(uri, extendedLibraries.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; |
| + } |
| +} |