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; |
+ } |
+} |