| Index: pkg/analyzer/lib/src/context/builder.dart
|
| diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
|
| index 51c0a219a16a528dcbe222b42eace0dad093a0a1..65928bfc880aec876632bf435470e2b232248583 100644
|
| --- a/pkg/analyzer/lib/src/context/builder.dart
|
| +++ b/pkg/analyzer/lib/src/context/builder.dart
|
| @@ -9,6 +9,7 @@ import 'dart:core' hide Resource;
|
|
|
| import 'package:analyzer/context/declared_variables.dart';
|
| import 'package:analyzer/file_system/file_system.dart';
|
| +import 'package:analyzer/plugin/options.dart';
|
| import 'package:analyzer/plugin/resolver_provider.dart';
|
| import 'package:analyzer/source/analysis_options_provider.dart';
|
| import 'package:analyzer/source/package_map_resolver.dart';
|
| @@ -20,6 +21,7 @@ import 'package:analyzer/src/task/options.dart';
|
| import 'package:package_config/packages.dart';
|
| import 'package:package_config/packages_file.dart';
|
| import 'package:package_config/src/packages_impl.dart';
|
| +import 'package:path/src/context.dart';
|
| import 'package:yaml/yaml.dart';
|
|
|
| /**
|
| @@ -121,11 +123,9 @@ class ContextBuilder {
|
| * *Note:* This method is not yet fully implemented and should not be used.
|
| */
|
| AnalysisContext buildContext(String path) {
|
| - // TODO(brianwilkerson) Split getAnalysisOptions so we can capture the
|
| - // option map and use it to run the options processors.
|
| - AnalysisOptions options = getAnalysisOptions(path);
|
| InternalAnalysisContext context =
|
| AnalysisEngine.instance.createAnalysisContext();
|
| + AnalysisOptions options = getAnalysisOptions(context, path);
|
| context.contentCache = contentCache;
|
| context.sourceFactory = createSourceFactory(path, options);
|
| context.analysisOptions = options;
|
| @@ -184,6 +184,7 @@ class ContextBuilder {
|
| File configFile = resourceProvider.getFile(defaultPackageFilePath);
|
| List<int> bytes = configFile.readAsBytesSync();
|
| Map<String, Uri> map = parse(bytes, configFile.toUri());
|
| + resolveSymbolicLinks(map);
|
| return new MapPackages(map);
|
| } else if (defaultPackagesDirectoryPath != null) {
|
| Folder folder = resourceProvider.getFolder(defaultPackagesDirectoryPath);
|
| @@ -215,7 +216,7 @@ class ContextBuilder {
|
| packageResolver,
|
| fileResolver
|
| ];
|
| - return new SourceFactory(resolvers);
|
| + return new SourceFactory(resolvers, null, resourceProvider);
|
| }
|
| }
|
| Packages packages = createPackageMap(rootDirectoryPath);
|
| @@ -225,10 +226,12 @@ class ContextBuilder {
|
| if (packageMap != null) {
|
| // TODO(brianwilkerson) I think that we don't need a PackageUriResolver
|
| // when we can pass the packages object to the source factory directly.
|
| + // Actually, I think we're using it to restoreUri, which could lead to
|
| + // inconsistencies.
|
| resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
|
| }
|
| resolvers.add(fileResolver);
|
| - return new SourceFactory(resolvers);
|
| + return new SourceFactory(resolvers, packages, resourceProvider);
|
| }
|
|
|
| /**
|
| @@ -260,6 +263,7 @@ class ContextBuilder {
|
| List<int> fileBytes = location.readAsBytesSync();
|
| Map<String, Uri> map =
|
| parse(fileBytes, resourceProvider.pathContext.toUri(location.path));
|
| + resolveSymbolicLinks(map);
|
| return new MapPackages(map);
|
| } else if (location is Folder) {
|
| return getPackagesFromFolder(location);
|
| @@ -334,16 +338,24 @@ class ContextBuilder {
|
| }
|
|
|
| /**
|
| - * Return the analysis options that should be used when analyzing code in the
|
| - * directory with the given [path].
|
| + * Return the analysis options that should be used when the given [context] is
|
| + * used to analyze code in the directory with the given [path].
|
| */
|
| - AnalysisOptions getAnalysisOptions(String path) {
|
| + AnalysisOptions getAnalysisOptions(AnalysisContext context, String path) {
|
| AnalysisOptionsImpl options = createDefaultOptions();
|
| File optionsFile = getOptionsFile(path);
|
| if (optionsFile != null) {
|
| - Map<String, YamlNode> fileOptions =
|
| - new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
|
| - applyToAnalysisOptions(options, fileOptions);
|
| + List<OptionsProcessor> optionsProcessors =
|
| + AnalysisEngine.instance.optionsPlugin.optionsProcessors;
|
| + try {
|
| + Map<String, YamlNode> optionMap =
|
| + new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
|
| + optionsProcessors.forEach(
|
| + (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
|
| + applyToAnalysisOptions(options, optionMap);
|
| + } on Exception catch (exception) {
|
| + optionsProcessors.forEach((OptionsProcessor p) => p.onError(exception));
|
| + }
|
| }
|
| return options;
|
| }
|
| @@ -379,23 +391,49 @@ class ContextBuilder {
|
| * directory.
|
| */
|
| Packages getPackagesFromFolder(Folder folder) {
|
| + Context pathContext = resourceProvider.pathContext;
|
| Map<String, Uri> map = new HashMap<String, Uri>();
|
| for (Resource child in folder.getChildren()) {
|
| if (child is Folder) {
|
| - String packageName = resourceProvider.pathContext.basename(child.path);
|
| - // Create a file URI (rather than a directory URI) and add a '.' so that
|
| - // the URI is suitable for resolving relative URI's against it.
|
| - //
|
| - // TODO(brianwilkerson) Decide whether we need to pass in a 'windows:'
|
| - // argument for testing purposes.
|
| - map[packageName] = resourceProvider.pathContext.toUri(
|
| - resourceProvider.pathContext.join(folder.path, packageName, '.'));
|
| + // Inline resolveSymbolicLinks for performance reasons.
|
| + String packageName = pathContext.basename(child.path);
|
| + String folderPath = resolveSymbolicLink(child);
|
| + String uriPath = pathContext.join(folderPath, '.');
|
| + map[packageName] = pathContext.toUri(uriPath);
|
| }
|
| }
|
| return new MapPackages(map);
|
| }
|
|
|
| /**
|
| + * Resolve any symbolic links encoded in the path to the given [folder].
|
| + */
|
| + String resolveSymbolicLink(Folder folder) {
|
| + try {
|
| + return folder.resolveSymbolicLinksSync().path;
|
| + } on FileSystemException {
|
| + return folder.path;
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Resolve any symbolic links encoded in the URI's in the given [map] by
|
| + * replacing the values in the map.
|
| + */
|
| + void resolveSymbolicLinks(Map<String, Uri> map) {
|
| + Context pathContext = resourceProvider.pathContext;
|
| + for (String packageName in map.keys) {
|
| + Folder folder =
|
| + resourceProvider.getFolder(pathContext.fromUri(map[packageName]));
|
| + String folderPath = resolveSymbolicLink(folder);
|
| + // Add a '.' so that the URI is suitable for resolving relative URI's
|
| + // against it.
|
| + String uriPath = pathContext.join(folderPath, '.');
|
| + map[packageName] = pathContext.toUri(uriPath);
|
| + }
|
| + }
|
| +
|
| + /**
|
| * Find the location of the package resolution file/directory for the
|
| * directory at the given absolute [path].
|
| *
|
|
|