Chromium Code Reviews| Index: pkg/analyzer_cli/lib/src/package_analyzer.dart |
| diff --git a/pkg/analyzer_cli/lib/src/package_analyzer.dart b/pkg/analyzer_cli/lib/src/package_analyzer.dart |
| index f159869a3d5528f9046abed606c8030f03b985f3..914a05351f1c0139e46797177a9fd9ff088dc4dc 100644 |
| --- a/pkg/analyzer_cli/lib/src/package_analyzer.dart |
| +++ b/pkg/analyzer_cli/lib/src/package_analyzer.dart |
| @@ -10,7 +10,6 @@ import 'dart:io' as io; |
| import 'package:analyzer/dart/element/element.dart'; |
| import 'package:analyzer/file_system/file_system.dart'; |
| import 'package:analyzer/file_system/physical_file_system.dart'; |
| -import 'package:analyzer/source/package_map_resolver.dart'; |
| import 'package:analyzer/src/generated/engine.dart'; |
| import 'package:analyzer/src/generated/error.dart'; |
| import 'package:analyzer/src/generated/java_io.dart'; |
| @@ -24,65 +23,56 @@ import 'package:analyzer_cli/src/analyzer_impl.dart'; |
| import 'package:analyzer_cli/src/driver.dart'; |
| import 'package:analyzer_cli/src/error_formatter.dart'; |
| import 'package:analyzer_cli/src/options.dart'; |
| -import 'package:path/path.dart' as pathos; |
| /** |
| - * The hermetic whole package analyzer. |
| + * Analyzer used when the "--build-mode" option is supplied. |
| */ |
| -class PackageAnalyzer { |
| +class BuildMode { |
| final CommandLineOptions options; |
| final AnalysisStats stats; |
| - String packagePath; |
| - String packageLibPath; |
| - |
| final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE; |
| InternalAnalysisContext context; |
| + Map<Uri, JavaFile> uriToFileMap; |
| final List<Source> explicitSources = <Source>[]; |
| - PackageAnalyzer(this.options, this.stats); |
| + BuildMode(this.options, this.stats); |
| /** |
| * Perform package analysis according to the given [options]. |
| */ |
| ErrorSeverity analyze() { |
| - packagePath = resourceProvider.pathContext.normalize(resourceProvider |
| - .pathContext |
| - .join(io.Directory.current.absolute.path, options.packageModePath)); |
| - packageLibPath = resourceProvider.pathContext.join(packagePath, 'lib'); |
| - if (packageLibPath == null) { |
| - errorSink.writeln('--package-mode-path must be set to the root ' |
| - 'folder of the package to analyze.'); |
| - io.exitCode = ErrorSeverity.ERROR.ordinal; |
| - return ErrorSeverity.ERROR; |
| - } |
| - |
| - // Write the progress message. |
| + // Write initial progress message. |
| if (!options.machineFormat) { |
| outSink.writeln("Analyzing sources ${options.sourceFiles}..."); |
| } |
| + // Create the URI to file map. |
| + uriToFileMap = _createUriToFileMap(options.sourceFiles); |
| + if (uriToFileMap == null) { |
| + io.exitCode = ErrorSeverity.ERROR.ordinal; |
| + return ErrorSeverity.ERROR; |
| + } |
| + |
| // Prepare the analysis context. |
| _createContext(); |
| // Add sources. |
| ChangeSet changeSet = new ChangeSet(); |
| - for (String path in options.sourceFiles) { |
| - if (AnalysisEngine.isDartFileName(path)) { |
| - File file = resourceProvider.getFile(path); |
| - if (!file.exists) { |
| - errorSink.writeln('File not found: $path'); |
| - io.exitCode = ErrorSeverity.ERROR.ordinal; |
| - return ErrorSeverity.ERROR; |
| - } |
| - Source source = _createSourceInContext(file); |
| - explicitSources.add(source); |
| - changeSet.addedSource(source); |
| + for (Uri uri in uriToFileMap.keys) { |
| + JavaFile file = uriToFileMap[uri]; |
| + if (!file.exists()) { |
| + errorSink.writeln('File not found: ${file.getPath()}'); |
| + io.exitCode = ErrorSeverity.ERROR.ordinal; |
| + return ErrorSeverity.ERROR; |
| } |
| + Source source = new FileBasedSource(file, uri); |
| + explicitSources.add(source); |
| + changeSet.addedSource(source); |
| } |
| context.applyChanges(changeSet); |
| - if (!options.packageSummaryOnly) { |
| + if (!options.buildSummaryOnly) { |
| // Perform full analysis. |
| while (true) { |
| AnalysisResult analysisResult = context.performAnalysisTask(); |
| @@ -92,42 +82,42 @@ class PackageAnalyzer { |
| } |
| } |
| - // Write summary for Dart libraries. |
| - if (options.packageSummaryOutput != null) { |
| + // Write summary. |
| + if (options.buildSummaryOutput != null) { |
| PackageBundleAssembler assembler = new PackageBundleAssembler(); |
| for (Source source in explicitSources) { |
| if (context.computeKindOf(source) != SourceKind.LIBRARY) { |
| continue; |
| } |
| - if (pathos.isWithin(packageLibPath, source.fullName)) { |
| - LibraryElement libraryElement = context.computeLibraryElement(source); |
| - assembler.serializeLibraryElement(libraryElement); |
| - } |
| + LibraryElement libraryElement = context.computeLibraryElement(source); |
| + assembler.serializeLibraryElement(libraryElement); |
| } |
| // Write the whole package bundle. |
| PackageBundleBuilder sdkBundle = assembler.assemble(); |
| - io.File file = new io.File(options.packageSummaryOutput); |
| + io.File file = new io.File(options.buildSummaryOutput); |
| file.writeAsBytesSync(sdkBundle.toBuffer(), mode: io.FileMode.WRITE_ONLY); |
| } |
| - if (options.packageSummaryOnly) { |
| + if (options.buildSummaryOnly) { |
| return ErrorSeverity.NONE; |
| } else { |
| // Process errors. |
| - _printErrors(); |
| + _printErrors(outputPath: options.buildAnalysisOutput); |
| return _computeMaxSeverity(); |
| } |
| } |
| ErrorSeverity _computeMaxSeverity() { |
| ErrorSeverity maxSeverity = ErrorSeverity.NONE; |
| - for (Source source in explicitSources) { |
| - AnalysisErrorInfo errorInfo = context.getErrors(source); |
| - for (AnalysisError error in errorInfo.errors) { |
| - ProcessedSeverity processedSeverity = |
| - AnalyzerImpl.processError(error, options, context); |
| - if (processedSeverity != null) { |
| - maxSeverity = maxSeverity.max(processedSeverity.severity); |
| + if (!options.buildSuppressExitCode) { |
| + for (Source source in explicitSources) { |
| + AnalysisErrorInfo errorInfo = context.getErrors(source); |
| + for (AnalysisError error in errorInfo.errors) { |
| + ProcessedSeverity processedSeverity = |
| + AnalyzerImpl.processError(error, options, context); |
| + if (processedSeverity != null) { |
| + maxSeverity = maxSeverity.max(processedSeverity.severity); |
| + } |
| } |
| } |
| } |
| @@ -138,17 +128,16 @@ class PackageAnalyzer { |
| DirectoryBasedDartSdk sdk = |
| new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath)); |
| + // Read the summaries. |
| + SummaryDataStore summaryDataStore = |
| + new SummaryDataStore(options.buildSummaryInputs); |
| + |
| // Create the context. |
| context = AnalysisEngine.instance.createAnalysisContext(); |
| context.sourceFactory = new SourceFactory(<UriResolver>[ |
| new DartUriResolver(sdk), |
| - new InSummaryPackageUriResolver(options.packageSummaryInputs), |
| - new PackageMapUriResolver(resourceProvider, <String, List<Folder>>{ |
| - options.packageName: <Folder>[ |
| - resourceProvider.getFolder(packageLibPath) |
| - ], |
| - }), |
| - new FileUriResolver() |
| + new InSummaryPackageUriResolver(summaryDataStore), |
| + new ExplicitSourceResolver(uriToFileMap) |
| ]); |
| // Set context options. |
| @@ -159,28 +148,17 @@ class PackageAnalyzer { |
| sdk.useSummary = true; |
| context.typeProvider = sdk.context.typeProvider; |
| context.resultProvider = |
| - new InputPackagesResultProvider(context, options.packageSummaryInputs); |
| + new InputPackagesResultProvider(context, summaryDataStore); |
| } |
| /** |
| - * Create and return a source representing the given [file]. |
| + * Print errors for all explicit sources. If [outputPath] is supplied, output |
| + * is sent to a new file at that path. |
| */ |
| - Source _createSourceInContext(File file) { |
| - Source source = file.createSource(); |
| - if (context == null) { |
| - return source; |
| - } |
| - Uri uri = context.sourceFactory.restoreUri(source); |
| - return file.createSource(uri); |
| - } |
| - |
| - /** |
| - * Print errors for all explicit sources. |
| - */ |
| - void _printErrors() { |
| - StringSink sink = options.machineFormat ? errorSink : outSink; |
| + void _printErrors({String outputPath}) { |
| + StringBuffer buffer = new StringBuffer(); |
| ErrorFormatter formatter = new ErrorFormatter( |
| - sink, |
| + buffer, |
| options, |
| stats, |
| (AnalysisError error) => |
| @@ -190,7 +168,34 @@ class PackageAnalyzer { |
| formatter.formatErrors([errorInfo]); |
| } |
| if (!options.machineFormat) { |
| - stats.print(sink); |
| + stats.print(buffer); |
| + } |
| + if (outputPath == null) { |
| + StringSink sink = options.machineFormat ? errorSink : outSink; |
| + sink.write(buffer); |
| + } else { |
| + new io.File(outputPath).writeAsStringSync(buffer.toString()); |
| + } |
| + } |
| + |
| + /** |
| + * Convert the list of input source files to a map from URI to source file |
| + * path. If an error occurs, report the error and return null. |
| + */ |
| + static Map<Uri, JavaFile> _createUriToFileMap(List<String> sourceFiles) { |
|
scheglov
2016/03/23 01:11:50
Naming the argument source "files" is a little mis
Paul Berry
2016/03/23 03:28:02
Done.
|
| + Map<Uri, JavaFile> uriToFileMap = <Uri, JavaFile>{}; |
| + for (String sourceFile in sourceFiles) { |
| + int pipeIndex = sourceFile.indexOf('|'); |
| + if (pipeIndex == -1) { |
| + // TODO(paulberry): add the ability to guess the URI from the path. |
| + errorSink.writeln( |
| + 'Illegal input file (must be "\$uri|\$path"): $sourceFile'); |
| + return null; |
| + } |
| + Uri uri = Uri.parse(sourceFile.substring(0, pipeIndex)); |
| + String path = sourceFile.substring(pipeIndex + 1); |
| + uriToFileMap[uri] = new JavaFile(path); |
| } |
| + return uriToFileMap; |
| } |
| } |