Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(13)

Side by Side Diff: packages/analyzer/lib/src/generated/package.dart

Issue 2990843002: Removed fixed dependencies (Closed)
Patch Set: Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4
5 library analyzer.src.generated.package;
6
7 import 'dart:collection';
8
9 import 'package:analyzer/exception/exception.dart';
10 import 'package:analyzer/file_system/file_system.dart';
11 import 'package:analyzer/source/package_map_resolver.dart';
12 import 'package:analyzer/src/context/builder.dart';
13 import 'package:analyzer/src/generated/engine.dart';
14 import 'package:analyzer/src/generated/sdk.dart';
15 import 'package:analyzer/src/generated/source.dart';
16 import 'package:analyzer/src/generated/utilities_general.dart';
17 import 'package:package_config/packages.dart';
18 import 'package:yaml/yaml.dart';
19
20 /**
21 * Traverses the package structure to determine the transitive dependencies for
22 * a given package.
23 */
24 class DependencyFinder {
25 /**
26 * The name of the pubspec.yaml file.
27 */
28 static const String pubspecName = 'pubspec.yaml';
29
30 /**
31 * The resource provider used to access the file system.
32 */
33 final ResourceProvider resourceProvider;
34
35 /**
36 * A table mapping the absolute paths of packages to a list of the names of
37 * the packages on which those packages depend.
38 */
39 final Map<String, List<String>> dependencyMap =
40 new HashMap<String, List<String>>();
41
42 /**
43 * Initialize a newly created dependency finder to use the given
44 * [resourceProvider] to access the file system.
45 */
46 DependencyFinder(this.resourceProvider);
47
48 /**
49 * Return a sorted list of the directories containing all of the packages on
50 * which the package at the given [packagePath] depends. The [packageMap]
51 * maps the names of packages to the directories in which they are contained.
52 *
53 * Throws an [AnalysisException] if any of the packages are missing their
54 * 'pubspec.yaml' file.
55 */
56 List<String> transitiveDependenciesFor(
57 Map<String, List<Folder>> packageMap, String packagePath) {
58 Set<String> processedPackages = new HashSet<String>();
59 Set<String> processedPaths = new HashSet<String>();
60 void process(String packageName) {
61 if (processedPackages.add(packageName)) {
62 List<Folder> folderList = packageMap[packageName];
63 if (folderList == null || folderList.isEmpty) {
64 throw new StateError('No mapping for package "$packageName"');
65 }
66 String packagePath = folderList[0].path;
67 processedPaths.add(packagePath);
68 List<String> dependencies = _dependenciesFor(packagePath);
69 for (String dependency in dependencies) {
70 process(dependency);
71 }
72 }
73 }
74
75 List<String> dependencies = _dependenciesFor(packagePath);
76 dependencies.forEach(process);
77 processedPaths.remove(packagePath);
78 List<String> transitiveDependencies = processedPaths.toList();
79 transitiveDependencies.sort();
80 return transitiveDependencies;
81 }
82
83 /**
84 * Add to the given set of [dependecies] all of the package names used as keys
85 * in the given [yamlMap].
86 */
87 void _collectDependencies(HashSet<String> dependencies, YamlMap yamlMap) {
88 if (yamlMap is Map) {
89 for (var key in yamlMap.keys) {
90 if (key is String) {
91 dependencies.add(key);
92 }
93 }
94 }
95 }
96
97 /**
98 * Return a list of the names of the packages on which the package at the
99 * [packagePath] depends.
100 */
101 List<String> _dependenciesFor(String packagePath) {
102 return dependencyMap.putIfAbsent(packagePath, () {
103 Set<String> dependencies = new HashSet<String>();
104 YamlNode yamlNode = _readPubspec(packagePath);
105 if (yamlNode is YamlMap) {
106 _collectDependencies(dependencies, yamlNode['dependencies']);
107 }
108 return dependencies.toList();
109 });
110 }
111
112 /**
113 * Read the content of the pubspec file in the directory at the given
114 * [directoryPath]. Return `null` if the file does not exist, cannot be read,
115 * or has content that is not valid YAML.
116 */
117 YamlNode _readPubspec(String directoryPath) {
118 try {
119 File yamlFile = resourceProvider
120 .getFolder(directoryPath)
121 .getChildAssumingFile(pubspecName);
122 String yamlContent = yamlFile.readAsStringSync();
123 return loadYamlNode(yamlContent);
124 } catch (exception, stackTrace) {
125 throw new AnalysisException('Missing $pubspecName in $directoryPath',
126 new CaughtException(exception, stackTrace));
127 }
128 }
129 }
130
131 /**
132 * A description of the context in which a package will be analyzed.
133 */
134 class PackageDescription {
135 /**
136 * The id of the package being described. The id encodes the actual locations
137 * of the package itself and all of the packages on which it depends.
138 */
139 final String id;
140
141 /**
142 * The SDK against which the package will be analyzed.
143 */
144 final DartSdk sdk;
145
146 /**
147 * The analysis options that will be used when analyzing the package.
148 */
149 final AnalysisOptions options;
150
151 /**
152 * Initialize a newly create package description to describe the package with
153 * the given [id] that is being analyzed against the given [sdk] using the
154 * given [options].
155 */
156 PackageDescription(this.id, this.sdk, this.options);
157
158 @override
159 int get hashCode {
160 int hashCode = options.encodeCrossContextOptions();
161 hashCode = JenkinsSmiHash.combine(hashCode, id.hashCode);
162 hashCode = JenkinsSmiHash.combine(hashCode, sdk.hashCode);
163 return JenkinsSmiHash.finish(hashCode);
164 }
165
166 @override
167 bool operator ==(Object other) {
168 return other is PackageDescription &&
169 other.sdk == sdk &&
170 other.options.encodeCrossContextOptions() ==
171 options.encodeCrossContextOptions() &&
172 other.id == id;
173 }
174 }
175
176 /**
177 * Manages the contexts in which each package is analyzed.
178 */
179 class PackageManager {
180 /**
181 * The resource provider used to access the file system.
182 */
183 final ResourceProvider resourceProvider;
184
185 /**
186 * A table mapping the id's of packages to the context in which the package is
187 * analyzed.
188 */
189 final Map<PackageDescription, AnalysisContext> contextMap =
190 new HashMap<PackageDescription, AnalysisContext>();
191
192 /**
193 * Initialize a newly created package manager.
194 */
195 PackageManager(this.resourceProvider);
196
197 /**
198 * Return the context in which the package at the given [packagePath] should
199 * be analyzed when the given [packages] object is used to resolve package
200 * names, the given [resolver] will be used to resolve 'dart:' URI's, and the
201 * given [options] will control the analysis.
202 */
203 AnalysisContext getContext(String packagePath, Packages packages,
204 DartUriResolver resolver, AnalysisOptions options) {
205 DartSdk sdk = resolver.dartSdk;
206 Map<String, List<Folder>> packageMap =
207 new ContextBuilder(resourceProvider, null, null)
208 .convertPackagesToMap(packages);
209 PackageDescription description =
210 new PackageDescription(_buildId(packagePath, packageMap), sdk, options);
211 return contextMap.putIfAbsent(description, () {
212 AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
213 context.sourceFactory = new SourceFactory(<UriResolver>[
214 resolver,
215 new PackageMapUriResolver(resourceProvider, packageMap),
216 new ResourceUriResolver(resourceProvider)
217 ], packages, resourceProvider);
218 context.analysisOptions = options;
219 return context;
220 });
221 }
222
223 /**
224 * Return the id associated with the package at the given [packagePath] when
225 * the given [packageMap] is used to resolve package names.
226 */
227 String _buildId(String packagePath, Map<String, List<Folder>> packageMap) {
228 DependencyFinder finder = new DependencyFinder(resourceProvider);
229 List<String> dependencies =
230 finder.transitiveDependenciesFor(packageMap, packagePath);
231 StringBuffer buffer = new StringBuffer();
232 buffer.write(packagePath);
233 for (String dependency in dependencies) {
234 buffer.write(';');
235 buffer.write(dependency);
236 }
237 return buffer.toString();
238 }
239 }
OLDNEW
« no previous file with comments | « packages/analyzer/lib/src/generated/java_io.dart ('k') | packages/analyzer/lib/src/generated/parser.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698