| // Copyright (c) 2015, 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. |
| |
| import 'package:analyzer/file_system/file_system.dart' |
| show ResourceProvider, ResourceUriResolver; |
| import 'package:analyzer/file_system/physical_file_system.dart' |
| show PhysicalResourceProvider; |
| import 'package:analyzer/source/custom_resolver.dart'; |
| import 'package:analyzer/source/package_map_resolver.dart'; |
| import 'package:analyzer/src/command_line/arguments.dart'; |
| import 'package:analyzer/src/context/builder.dart'; |
| import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl; |
| import 'package:analyzer/src/generated/source.dart' |
| show DartUriResolver, SourceFactory, UriResolver; |
| import 'package:analyzer/src/summary/package_bundle_reader.dart' |
| show InSummaryUriResolver, SummaryDataStore; |
| import 'package:args/args.dart' show ArgParser, ArgResults; |
| import 'package:cli_util/cli_util.dart' show getSdkDir; |
| import 'package:path/path.dart' as path; |
| |
| // ignore_for_file: deprecated_member_use |
| |
| /// Options used to set up Source URI resolution in the analysis context. |
| class AnalyzerOptions { |
| final ContextBuilderOptions contextBuilderOptions; |
| |
| /// Custom URI mappings, such as "dart:foo" -> "path/to/foo.dart" |
| final Map<String, String> customUrlMappings; |
| |
| /// Package root when resolving 'package:' urls the standard way. |
| String get packageRoot => contextBuilderOptions.defaultPackagesDirectoryPath; |
| |
| /// List of summary file paths. |
| final List<String> summaryPaths; |
| |
| final Map<String, String> customSummaryModules = {}; |
| |
| /// Path to the dart-sdk, or `null` if the path couldn't be determined. |
| final String dartSdkPath; |
| |
| /// Path to the dart-sdk summary. If this is set, it will be used in favor |
| /// of the unsummarized one. |
| String get dartSdkSummaryPath => contextBuilderOptions.dartSdkSummaryPath; |
| |
| /// Defined variables used by `bool.fromEnvironment` etc. |
| Map<String, String> get declaredVariables => |
| contextBuilderOptions.declaredVariables; |
| |
| AnalyzerOptions._( |
| {this.contextBuilderOptions, |
| List<String> summaryPaths, |
| String dartSdkPath, |
| this.customUrlMappings = const {}}) |
| : dartSdkPath = dartSdkPath ?? getSdkDir().path, |
| summaryPaths = summaryPaths ?? const [] { |
| contextBuilderOptions.declaredVariables ??= const {}; |
| _parseCustomSummaryModules(); |
| } |
| |
| factory AnalyzerOptions.basic( |
| {String dartSdkPath, |
| String dartSdkSummaryPath, |
| List<String> summaryPaths}) { |
| var contextBuilderOptions = ContextBuilderOptions() |
| ..defaultOptions = (AnalysisOptionsImpl()..previewDart2 = true) |
| ..dartSdkSummaryPath = dartSdkSummaryPath; |
| |
| return AnalyzerOptions._( |
| contextBuilderOptions: contextBuilderOptions, |
| dartSdkPath: dartSdkPath, |
| summaryPaths: summaryPaths); |
| } |
| |
| factory AnalyzerOptions.fromArguments(ArgResults args, |
| {String dartSdkSummaryPath, List<String> summaryPaths}) { |
| var contextBuilderOptions = |
| createContextBuilderOptions(args, trackCacheDependencies: false); |
| (contextBuilderOptions.defaultOptions as AnalysisOptionsImpl).previewDart2 = |
| true; |
| |
| var dartSdkPath = args['dart-sdk'] as String ?? getSdkDir().path; |
| |
| dartSdkSummaryPath ??= contextBuilderOptions.dartSdkSummaryPath; |
| dartSdkSummaryPath ??= |
| path.join(dartSdkPath, 'lib', '_internal', 'ddc_sdk.sum'); |
| // For building the SDK, we explicitly set the path to none. |
| if (dartSdkSummaryPath == 'build') dartSdkSummaryPath = null; |
| contextBuilderOptions.dartSdkSummaryPath = dartSdkSummaryPath; |
| |
| return AnalyzerOptions._( |
| contextBuilderOptions: contextBuilderOptions, |
| summaryPaths: summaryPaths ?? args['summary'] as List<String>, |
| dartSdkPath: dartSdkPath, |
| customUrlMappings: |
| _parseUrlMappings(args['url-mapping'] as List<String>)); |
| } |
| |
| static void addArguments(ArgParser parser, {bool hide = true}) { |
| parser |
| ..addOption('summary', |
| abbr: 's', help: 'summary file(s) to include', allowMultiple: true) |
| ..addOption('url-mapping', |
| help: '--url-mapping=libraryUri,/path/to/library.dart uses\n' |
| 'library.dart as the source for an import of of "libraryUri".', |
| allowMultiple: true, |
| splitCommas: false, |
| hide: hide); |
| } |
| |
| static Map<String, String> _parseUrlMappings(List<String> argument) { |
| var mappings = <String, String>{}; |
| for (var mapping in argument) { |
| var splitMapping = mapping.split(','); |
| if (splitMapping.length >= 2) { |
| mappings[splitMapping[0]] = path.absolute(splitMapping[1]); |
| } |
| } |
| return mappings; |
| } |
| |
| /// A summary path can contain "=" followed by an explicit module name to |
| /// allow working with summaries whose physical location is outside of the |
| /// module root directory. |
| /// |
| /// Removes any explicit module names from [summaryPaths] and populates with |
| /// [customSummaryModules] with them. |
| void _parseCustomSummaryModules() { |
| for (var i = 0; i < summaryPaths.length; i++) { |
| var summaryPath = summaryPaths[i]; |
| var pipe = summaryPath.indexOf("="); |
| if (pipe != -1) { |
| summaryPaths[i] = summaryPath.substring(0, pipe); |
| customSummaryModules[summaryPaths[i]] = summaryPath.substring(pipe + 1); |
| } |
| } |
| } |
| } |
| |
| /// Creates a SourceFactory configured by the [options]. |
| /// |
| /// If supplied, [fileResolvers] will override the default `file:` and |
| /// `package:` URI resolvers. |
| SourceFactory createSourceFactory(AnalyzerOptions options, |
| {DartUriResolver sdkResolver, |
| List<UriResolver> fileResolvers, |
| SummaryDataStore summaryData, |
| ResourceProvider resourceProvider}) { |
| resourceProvider ??= PhysicalResourceProvider.INSTANCE; |
| var resolvers = <UriResolver>[]; |
| if (options.customUrlMappings.isNotEmpty) { |
| resolvers |
| .add(CustomUriResolver(resourceProvider, options.customUrlMappings)); |
| } |
| resolvers.add(sdkResolver); |
| if (summaryData != null) { |
| resolvers.add(InSummaryUriResolver(resourceProvider, summaryData)); |
| } |
| |
| if (fileResolvers == null) |
| fileResolvers = |
| createFileResolvers(options, resourceProvider: resourceProvider); |
| resolvers.addAll(fileResolvers); |
| return SourceFactory(resolvers, null, resourceProvider); |
| } |
| |
| List<UriResolver> createFileResolvers(AnalyzerOptions options, |
| {ResourceProvider resourceProvider}) { |
| resourceProvider ??= PhysicalResourceProvider.INSTANCE; |
| UriResolver packageResolver() { |
| var builderOptions = ContextBuilderOptions(); |
| if (options.packageRoot != null) { |
| builderOptions.defaultPackagesDirectoryPath = options.packageRoot; |
| } |
| var builder = |
| ContextBuilder(resourceProvider, null, null, options: builderOptions); |
| |
| return PackageMapUriResolver(resourceProvider, |
| builder.convertPackagesToMap(builder.createPackageMap(''))); |
| } |
| |
| return [ResourceUriResolver(resourceProvider), packageResolver()]; |
| } |