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

Side by Side Diff: pkg/analyzer/lib/src/context/builder.dart

Issue 2286923002: Convert analysis server over to use ContextBuilder (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: address comment, fix bugs, clean-up Created 4 years, 3 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
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library analyzer.src.context.context_builder; 5 library analyzer.src.context.context_builder;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 import 'dart:core' hide Resource; 8 import 'dart:core' hide Resource;
9 9
10 import 'package:analyzer/context/declared_variables.dart'; 10 import 'package:analyzer/context/declared_variables.dart';
11 import 'package:analyzer/file_system/file_system.dart'; 11 import 'package:analyzer/file_system/file_system.dart';
12 import 'package:analyzer/plugin/options.dart';
12 import 'package:analyzer/plugin/resolver_provider.dart'; 13 import 'package:analyzer/plugin/resolver_provider.dart';
13 import 'package:analyzer/source/analysis_options_provider.dart'; 14 import 'package:analyzer/source/analysis_options_provider.dart';
14 import 'package:analyzer/source/package_map_resolver.dart'; 15 import 'package:analyzer/source/package_map_resolver.dart';
15 import 'package:analyzer/src/dart/sdk/sdk.dart'; 16 import 'package:analyzer/src/dart/sdk/sdk.dart';
16 import 'package:analyzer/src/generated/engine.dart'; 17 import 'package:analyzer/src/generated/engine.dart';
17 import 'package:analyzer/src/generated/sdk.dart'; 18 import 'package:analyzer/src/generated/sdk.dart';
18 import 'package:analyzer/src/generated/source.dart'; 19 import 'package:analyzer/src/generated/source.dart';
19 import 'package:analyzer/src/task/options.dart'; 20 import 'package:analyzer/src/task/options.dart';
20 import 'package:package_config/packages.dart'; 21 import 'package:package_config/packages.dart';
21 import 'package:package_config/packages_file.dart'; 22 import 'package:package_config/packages_file.dart';
22 import 'package:package_config/src/packages_impl.dart'; 23 import 'package:package_config/src/packages_impl.dart';
24 import 'package:path/src/context.dart';
23 import 'package:yaml/yaml.dart'; 25 import 'package:yaml/yaml.dart';
24 26
25 /** 27 /**
26 * A utility class used to build an analysis context for a given directory. 28 * A utility class used to build an analysis context for a given directory.
27 * 29 *
28 * The construction of analysis contexts is as follows: 30 * The construction of analysis contexts is as follows:
29 * 31 *
30 * 1. Determine how package: URI's are to be resolved. This follows the lookup 32 * 1. Determine how package: URI's are to be resolved. This follows the lookup
31 * algorithm defined by the [package specification][1]. 33 * algorithm defined by the [package specification][1].
32 * 34 *
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 */ 116 */
115 ContextBuilder(this.resourceProvider, this.sdkManager, this.contentCache); 117 ContextBuilder(this.resourceProvider, this.sdkManager, this.contentCache);
116 118
117 /** 119 /**
118 * Return an analysis context that is configured correctly to analyze code in 120 * Return an analysis context that is configured correctly to analyze code in
119 * the directory with the given [path]. 121 * the directory with the given [path].
120 * 122 *
121 * *Note:* This method is not yet fully implemented and should not be used. 123 * *Note:* This method is not yet fully implemented and should not be used.
122 */ 124 */
123 AnalysisContext buildContext(String path) { 125 AnalysisContext buildContext(String path) {
124 // TODO(brianwilkerson) Split getAnalysisOptions so we can capture the
125 // option map and use it to run the options processors.
126 AnalysisOptions options = getAnalysisOptions(path);
127 InternalAnalysisContext context = 126 InternalAnalysisContext context =
128 AnalysisEngine.instance.createAnalysisContext(); 127 AnalysisEngine.instance.createAnalysisContext();
128 AnalysisOptions options = getAnalysisOptions(context, path);
129 context.contentCache = contentCache; 129 context.contentCache = contentCache;
130 context.sourceFactory = createSourceFactory(path, options); 130 context.sourceFactory = createSourceFactory(path, options);
131 context.analysisOptions = options; 131 context.analysisOptions = options;
132 //_processAnalysisOptions(context, optionMap); 132 //_processAnalysisOptions(context, optionMap);
133 declareVariables(context); 133 declareVariables(context);
134 return context; 134 return context;
135 } 135 }
136 136
137 Map<String, List<Folder>> convertPackagesToMap(Packages packages) { 137 Map<String, List<Folder>> convertPackagesToMap(Packages packages) {
138 if (packages == null || packages == Packages.noPackages) { 138 if (packages == null || packages == Packages.noPackages) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 return new AnalysisOptionsImpl(); 177 return new AnalysisOptionsImpl();
178 } 178 }
179 return new AnalysisOptionsImpl.from(defaultOptions); 179 return new AnalysisOptionsImpl.from(defaultOptions);
180 } 180 }
181 181
182 Packages createPackageMap(String rootDirectoryPath) { 182 Packages createPackageMap(String rootDirectoryPath) {
183 if (defaultPackageFilePath != null) { 183 if (defaultPackageFilePath != null) {
184 File configFile = resourceProvider.getFile(defaultPackageFilePath); 184 File configFile = resourceProvider.getFile(defaultPackageFilePath);
185 List<int> bytes = configFile.readAsBytesSync(); 185 List<int> bytes = configFile.readAsBytesSync();
186 Map<String, Uri> map = parse(bytes, configFile.toUri()); 186 Map<String, Uri> map = parse(bytes, configFile.toUri());
187 resolveSymbolicLinks(map);
187 return new MapPackages(map); 188 return new MapPackages(map);
188 } else if (defaultPackagesDirectoryPath != null) { 189 } else if (defaultPackagesDirectoryPath != null) {
189 Folder folder = resourceProvider.getFolder(defaultPackagesDirectoryPath); 190 Folder folder = resourceProvider.getFolder(defaultPackagesDirectoryPath);
190 return getPackagesFromFolder(folder); 191 return getPackagesFromFolder(folder);
191 } 192 }
192 return findPackagesFromFile(rootDirectoryPath); 193 return findPackagesFromFile(rootDirectoryPath);
193 } 194 }
194 195
195 SourceFactory createSourceFactory( 196 SourceFactory createSourceFactory(
196 String rootDirectoryPath, AnalysisOptions options) { 197 String rootDirectoryPath, AnalysisOptions options) {
(...skipping 11 matching lines...) Expand all
208 UriResolver packageResolver = packageResolverProvider(folder()); 209 UriResolver packageResolver = packageResolverProvider(folder());
209 if (packageResolver != null) { 210 if (packageResolver != null) {
210 // TODO(brianwilkerson) This doesn't support either embedder files or 211 // TODO(brianwilkerson) This doesn't support either embedder files or
211 // sdk extensions because we don't have a way to get the package map 212 // sdk extensions because we don't have a way to get the package map
212 // from the resolver. 213 // from the resolver.
213 List<UriResolver> resolvers = <UriResolver>[ 214 List<UriResolver> resolvers = <UriResolver>[
214 new DartUriResolver(findSdk(null, options)), 215 new DartUriResolver(findSdk(null, options)),
215 packageResolver, 216 packageResolver,
216 fileResolver 217 fileResolver
217 ]; 218 ];
218 return new SourceFactory(resolvers); 219 return new SourceFactory(resolvers, null, resourceProvider);
219 } 220 }
220 } 221 }
221 Packages packages = createPackageMap(rootDirectoryPath); 222 Packages packages = createPackageMap(rootDirectoryPath);
222 Map<String, List<Folder>> packageMap = convertPackagesToMap(packages); 223 Map<String, List<Folder>> packageMap = convertPackagesToMap(packages);
223 List<UriResolver> resolvers = <UriResolver>[]; 224 List<UriResolver> resolvers = <UriResolver>[];
224 resolvers.add(new DartUriResolver(findSdk(packageMap, options))); 225 resolvers.add(new DartUriResolver(findSdk(packageMap, options)));
225 if (packageMap != null) { 226 if (packageMap != null) {
226 // TODO(brianwilkerson) I think that we don't need a PackageUriResolver 227 // TODO(brianwilkerson) I think that we don't need a PackageUriResolver
227 // when we can pass the packages object to the source factory directly. 228 // when we can pass the packages object to the source factory directly.
229 // Actually, I think we're using it to restoreUri, which could lead to
230 // inconsistencies.
228 resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap)); 231 resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
229 } 232 }
230 resolvers.add(fileResolver); 233 resolvers.add(fileResolver);
231 return new SourceFactory(resolvers); 234 return new SourceFactory(resolvers, packages, resourceProvider);
232 } 235 }
233 236
234 /** 237 /**
235 * Add any [declaredVariables] to the list of declared variables used by the 238 * Add any [declaredVariables] to the list of declared variables used by the
236 * given [context]. 239 * given [context].
237 */ 240 */
238 void declareVariables(InternalAnalysisContext context) { 241 void declareVariables(InternalAnalysisContext context) {
239 if (declaredVariables != null && declaredVariables.isNotEmpty) { 242 if (declaredVariables != null && declaredVariables.isNotEmpty) {
240 DeclaredVariables contextVariables = context.declaredVariables; 243 DeclaredVariables contextVariables = context.declaredVariables;
241 declaredVariables.forEach((String variableName, String value) { 244 declaredVariables.forEach((String variableName, String value) {
(...skipping 11 matching lines...) Expand all
253 * directory in the same place. If that also fails, it starts checking parent 256 * directory in the same place. If that also fails, it starts checking parent
254 * directories for a `.packages` file, and stops if it finds it. Otherwise it 257 * directories for a `.packages` file, and stops if it finds it. Otherwise it
255 * gives up and returns [Packages.noPackages]. 258 * gives up and returns [Packages.noPackages].
256 */ 259 */
257 Packages findPackagesFromFile(String path) { 260 Packages findPackagesFromFile(String path) {
258 Resource location = _findPackagesLocation(path); 261 Resource location = _findPackagesLocation(path);
259 if (location is File) { 262 if (location is File) {
260 List<int> fileBytes = location.readAsBytesSync(); 263 List<int> fileBytes = location.readAsBytesSync();
261 Map<String, Uri> map = 264 Map<String, Uri> map =
262 parse(fileBytes, resourceProvider.pathContext.toUri(location.path)); 265 parse(fileBytes, resourceProvider.pathContext.toUri(location.path));
266 resolveSymbolicLinks(map);
263 return new MapPackages(map); 267 return new MapPackages(map);
264 } else if (location is Folder) { 268 } else if (location is Folder) {
265 return getPackagesFromFolder(location); 269 return getPackagesFromFolder(location);
266 } 270 }
267 return Packages.noPackages; 271 return Packages.noPackages;
268 } 272 }
269 273
270 /** 274 /**
271 * Return the SDK that should be used to analyze code. Use the given 275 * Return the SDK that should be used to analyze code. Use the given
272 * [packageMap] and [options] to locate the SDK. 276 * [packageMap] and [options] to locate the SDK.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 return sdkManager.getSdk(description, () { 331 return sdkManager.getSdk(description, () {
328 FolderBasedDartSdk sdk = new FolderBasedDartSdk( 332 FolderBasedDartSdk sdk = new FolderBasedDartSdk(
329 resourceProvider, resourceProvider.getFolder(sdkPath)); 333 resourceProvider, resourceProvider.getFolder(sdkPath));
330 sdk.analysisOptions = options; 334 sdk.analysisOptions = options;
331 sdk.useSummary = sdkManager.canUseSummaries; 335 sdk.useSummary = sdkManager.canUseSummaries;
332 return sdk; 336 return sdk;
333 }); 337 });
334 } 338 }
335 339
336 /** 340 /**
337 * Return the analysis options that should be used when analyzing code in the 341 * Return the analysis options that should be used when the given [context] is
338 * directory with the given [path]. 342 * used to analyze code in the directory with the given [path].
339 */ 343 */
340 AnalysisOptions getAnalysisOptions(String path) { 344 AnalysisOptions getAnalysisOptions(AnalysisContext context, String path) {
341 AnalysisOptionsImpl options = createDefaultOptions(); 345 AnalysisOptionsImpl options = createDefaultOptions();
342 File optionsFile = getOptionsFile(path); 346 File optionsFile = getOptionsFile(path);
343 if (optionsFile != null) { 347 if (optionsFile != null) {
344 Map<String, YamlNode> fileOptions = 348 List<OptionsProcessor> optionsProcessors =
345 new AnalysisOptionsProvider().getOptionsFromFile(optionsFile); 349 AnalysisEngine.instance.optionsPlugin.optionsProcessors;
346 applyToAnalysisOptions(options, fileOptions); 350 try {
351 Map<String, YamlNode> optionMap =
352 new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
353 optionsProcessors.forEach(
354 (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
355 applyToAnalysisOptions(options, optionMap);
356 } on Exception catch (exception) {
357 optionsProcessors.forEach((OptionsProcessor p) => p.onError(exception));
358 }
347 } 359 }
348 return options; 360 return options;
349 } 361 }
350 362
351 /** 363 /**
352 * Return the analysis options file that should be used when analyzing code in 364 * Return the analysis options file that should be used when analyzing code in
353 * the directory with the given [path]. 365 * the directory with the given [path].
354 */ 366 */
355 File getOptionsFile(String path) { 367 File getOptionsFile(String path) {
356 if (defaultAnalysisOptionsFilePath != null) { 368 if (defaultAnalysisOptionsFilePath != null) {
(...skipping 15 matching lines...) Expand all
372 return null; 384 return null;
373 } 385 }
374 386
375 /** 387 /**
376 * Create a [Packages] object for a 'package' directory ([folder]). 388 * Create a [Packages] object for a 'package' directory ([folder]).
377 * 389 *
378 * Package names are resolved as relative to sub-directories of the package 390 * Package names are resolved as relative to sub-directories of the package
379 * directory. 391 * directory.
380 */ 392 */
381 Packages getPackagesFromFolder(Folder folder) { 393 Packages getPackagesFromFolder(Folder folder) {
394 Context pathContext = resourceProvider.pathContext;
382 Map<String, Uri> map = new HashMap<String, Uri>(); 395 Map<String, Uri> map = new HashMap<String, Uri>();
383 for (Resource child in folder.getChildren()) { 396 for (Resource child in folder.getChildren()) {
384 if (child is Folder) { 397 if (child is Folder) {
385 String packageName = resourceProvider.pathContext.basename(child.path); 398 // Inline resolveSymbolicLinks for performance reasons.
386 // Create a file URI (rather than a directory URI) and add a '.' so that 399 String packageName = pathContext.basename(child.path);
387 // the URI is suitable for resolving relative URI's against it. 400 String folderPath = resolveSymbolicLink(child);
388 // 401 String uriPath = pathContext.join(folderPath, '.');
389 // TODO(brianwilkerson) Decide whether we need to pass in a 'windows:' 402 map[packageName] = pathContext.toUri(uriPath);
390 // argument for testing purposes.
391 map[packageName] = resourceProvider.pathContext.toUri(
392 resourceProvider.pathContext.join(folder.path, packageName, '.'));
393 } 403 }
394 } 404 }
395 return new MapPackages(map); 405 return new MapPackages(map);
396 } 406 }
397 407
398 /** 408 /**
409 * Resolve any symbolic links encoded in the path to the given [folder].
410 */
411 String resolveSymbolicLink(Folder folder) {
412 try {
413 return folder.resolveSymbolicLinksSync().path;
414 } on FileSystemException {
415 return folder.path;
416 }
417 }
418
419 /**
420 * Resolve any symbolic links encoded in the URI's in the given [map] by
421 * replacing the values in the map.
422 */
423 void resolveSymbolicLinks(Map<String, Uri> map) {
424 Context pathContext = resourceProvider.pathContext;
425 for (String packageName in map.keys) {
426 Folder folder =
427 resourceProvider.getFolder(pathContext.fromUri(map[packageName]));
428 String folderPath = resolveSymbolicLink(folder);
429 // Add a '.' so that the URI is suitable for resolving relative URI's
430 // against it.
431 String uriPath = pathContext.join(folderPath, '.');
432 map[packageName] = pathContext.toUri(uriPath);
433 }
434 }
435
436 /**
399 * Find the location of the package resolution file/directory for the 437 * Find the location of the package resolution file/directory for the
400 * directory at the given absolute [path]. 438 * directory at the given absolute [path].
401 * 439 *
402 * Checks for a `.packages` file in the [path]. If not found, 440 * Checks for a `.packages` file in the [path]. If not found,
403 * checks for a `packages` directory in the same directory. If still not 441 * checks for a `packages` directory in the same directory. If still not
404 * found, starts checking parent directories for `.packages` until reaching 442 * found, starts checking parent directories for `.packages` until reaching
405 * the root directory. 443 * the root directory.
406 * 444 *
407 * Return a [File] object representing a `.packages` file if one is found, a 445 * Return a [File] object representing a `.packages` file if one is found, a
408 * [Folder] object for the `packages/` directory if that is found, or `null` 446 * [Folder] object for the `packages/` directory if that is found, or `null`
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 String _readEmbedderYaml(Folder libDir) { 569 String _readEmbedderYaml(Folder libDir) {
532 File file = libDir.getChild(EMBEDDER_FILE_NAME); 570 File file = libDir.getChild(EMBEDDER_FILE_NAME);
533 try { 571 try {
534 return file.readAsStringSync(); 572 return file.readAsStringSync();
535 } on FileSystemException { 573 } on FileSystemException {
536 // File can't be read. 574 // File can't be read.
537 return null; 575 return null;
538 } 576 }
539 } 577 }
540 } 578 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/file_system/physical_file_system.dart ('k') | pkg/analyzer/lib/src/dart/sdk/sdk.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698