Switch build mode to Analysis Driver.

R=brianwilkerson@google.com, paulberry@google.com
BUG=

Review-Url: https://codereview.chromium.org/2994763002 .
This commit is contained in:
Konstantin Shcheglov 2017-08-08 11:11:33 -07:00
parent 461ef144ab
commit 11b8c54e22
3 changed files with 62 additions and 59 deletions

View file

@ -7,9 +7,10 @@ library analyzer_cli.src.build_mode;
import 'dart:async';
import 'dart:io' as io;
import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
@ -23,12 +24,13 @@ import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summarize_ast.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
import 'package:analyzer/task/dart.dart';
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/error_formatter.dart';
import 'package:analyzer_cli/src/error_severity.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:bazel_worker/bazel_worker.dart';
import 'package:front_end/src/base/performace_logger.dart';
import 'package:front_end/src/byte_store/byte_store.dart';
/**
* Persistent Bazel worker.
@ -55,8 +57,10 @@ class AnalyzerWorkerLoop extends AsyncWorkerLoop {
/**
* Performs analysis with given [options].
*/
void analyze(CommandLineOptions options) {
new BuildMode(resourceProvider, options, new AnalysisStats()).analyze();
Future<Null> analyze(CommandLineOptions options) async {
var buildMode =
new BuildMode(resourceProvider, options, new AnalysisStats());
await buildMode.analyze();
AnalysisEngine.instance.clearCaches();
}
@ -81,7 +85,7 @@ class AnalyzerWorkerLoop extends AsyncWorkerLoop {
throw new ArgumentError(msg);
});
// Analyze and respond.
analyze(options);
await analyze(options);
String msg = _getErrorOutputBuffersText();
return new WorkResponse()
..exitCode = EXIT_CODE_OK
@ -129,7 +133,8 @@ class BuildMode {
final AnalysisStats stats;
SummaryDataStore summaryDataStore;
InternalAnalysisContext context;
AnalysisOptions analysisOptions;
AnalysisDriver analysisDriver;
Map<Uri, File> uriToFileMap;
final List<Source> explicitSources = <Source>[];
final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
@ -147,7 +152,7 @@ class BuildMode {
/**
* Perform package analysis according to the given [options].
*/
ErrorSeverity analyze() {
Future<ErrorSeverity> analyze() async {
// Write initial progress message.
if (!options.machineFormat) {
outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}...");
@ -169,9 +174,9 @@ class BuildMode {
uriPipePath.substring(uriPipePath.indexOf('|') + 1))
.toList());
// Prepare the analysis context.
// Prepare the analysis driver.
try {
_createContext();
_createAnalysisDriver();
} on ConflictingSummaryException catch (e) {
errorSink.writeln('$e');
io.exitCode = ErrorSeverity.ERROR.ordinal;
@ -179,7 +184,6 @@ class BuildMode {
}
// Add sources.
ChangeSet changeSet = new ChangeSet();
for (Uri uri in uriToFileMap.keys) {
File file = uriToFileMap[uri];
if (!file.exists) {
@ -189,18 +193,6 @@ class BuildMode {
}
Source source = new FileSource(file, uri);
explicitSources.add(source);
changeSet.addedSource(source);
}
context.applyChanges(changeSet);
if (!options.buildSummaryOnly) {
// Perform full analysis.
while (true) {
AnalysisResult analysisResult = context.performAnalysisTask();
if (!analysisResult.hasMoreWork) {
break;
}
}
}
// Write summary.
@ -208,7 +200,7 @@ class BuildMode {
if (_shouldOutputSummary) {
// Prepare all unlinked units.
for (var src in explicitSources) {
_prepareUnlinkedUnit('${src.uri}');
await _prepareUnlinkedUnit('${src.uri}');
}
// Build and assemble linked libraries.
@ -243,8 +235,8 @@ class BuildMode {
return ErrorSeverity.NONE;
} else {
// Process errors.
_printErrors(outputPath: options.buildAnalysisOutput);
return _computeMaxSeverity();
await _printErrors(outputPath: options.buildAnalysisOutput);
return await _computeMaxSeverity();
}
}
@ -264,19 +256,19 @@ class BuildMode {
libraryUris,
getDependency,
getUnit,
context.declaredVariables.get,
analysisDriver.declaredVariables.get,
options.strongMode);
linkResult.forEach(assembler.addLinkedLibrary);
}
ErrorSeverity _computeMaxSeverity() {
Future<ErrorSeverity> _computeMaxSeverity() async {
ErrorSeverity maxSeverity = ErrorSeverity.NONE;
if (!options.buildSuppressExitCode) {
for (Source source in explicitSources) {
AnalysisErrorInfo errorInfo = context.getErrors(source);
for (AnalysisError error in errorInfo.errors) {
ErrorsResult result = await analysisDriver.getErrors(source.fullName);
for (AnalysisError error in result.errors) {
ErrorSeverity processedSeverity = determineProcessedSeverity(
error, options, context.analysisOptions);
error, options, analysisDriver.analysisOptions);
if (processedSeverity != null) {
maxSeverity = maxSeverity.max(processedSeverity);
}
@ -286,7 +278,7 @@ class BuildMode {
return maxSeverity;
}
void _createContext() {
void _createAnalysisDriver() {
// Read the summaries.
summaryDataStore = new SummaryDataStore(<String>[],
recordDependencyInfo: _shouldOutputSummary);
@ -342,26 +334,30 @@ class BuildMode {
// Include SDK bundle to avoid parsing SDK sources.
summaryDataStore.addBundle(null, sdkBundle);
// Create the context.
context = AnalysisEngine.instance.createAnalysisContext();
context.sourceFactory = new SourceFactory(<UriResolver>[
var sourceFactory = new SourceFactory(<UriResolver>[
new DartUriResolver(sdk),
new InSummaryUriResolver(resourceProvider, summaryDataStore),
new ExplicitSourceResolver(uriToFileMap)
]);
// Set context options.
Driver.declareVariables(context.declaredVariables, options);
AnalysisOptionsImpl analysisOptions = Driver
.createAnalysisOptionsForCommandLineOptions(resourceProvider, options);
context.analysisOptions = analysisOptions;
analysisOptions = Driver.createAnalysisOptionsForCommandLineOptions(
resourceProvider, options);
if (!options.buildSummaryOnly) {
// Configure using summaries.
context.typeProvider = sdk.context.typeProvider;
context.resultProvider =
new InputPackagesResultProvider(context, summaryDataStore);
}
PerformanceLog logger = new PerformanceLog(null);
AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger);
analysisDriver = new AnalysisDriver(
scheduler,
logger,
resourceProvider,
new MemoryByteStore(),
new FileContentOverlay(),
null,
sourceFactory,
analysisOptions,
externalSummaries: summaryDataStore);
Driver.declareVariables(analysisDriver.declaredVariables, options);
scheduler.start();
}
/**
@ -393,21 +389,21 @@ class BuildMode {
*
* Otherwise compute it and store into the [uriToUnit] and [assembler].
*/
void _prepareUnlinkedUnit(String absoluteUri) {
Future<Null> _prepareUnlinkedUnit(String absoluteUri) async {
// Maybe an input package contains the source.
if (summaryDataStore.unlinkedMap[absoluteUri] != null) {
return;
}
// Parse the source and serialize its AST.
Uri uri = Uri.parse(absoluteUri);
Source source = context.sourceFactory.forUri2(uri);
Source source = analysisDriver.sourceFactory.forUri2(uri);
if (!source.exists()) {
// TODO(paulberry): we should report a warning/error because DDC
// compilations are unlikely to work.
return;
}
CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
var result = await analysisDriver.parseFile(source.fullName);
UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(result.unit);
uriToUnit[absoluteUri] = unlinkedUnit;
assembler.addUnlinkedUnit(source, unlinkedUnit);
}
@ -416,17 +412,18 @@ class BuildMode {
* Print errors for all explicit sources. If [outputPath] is supplied, output
* is sent to a new file at that path.
*/
void _printErrors({String outputPath}) {
Future<Null> _printErrors({String outputPath}) async {
StringBuffer buffer = new StringBuffer();
var severityProcessor = (AnalysisError error) =>
determineProcessedSeverity(error, options, context.analysisOptions);
determineProcessedSeverity(error, options, analysisOptions);
ErrorFormatter formatter = options.machineFormat
? new MachineErrorFormatter(buffer, options, stats,
severityProcessor: severityProcessor)
: new HumanErrorFormatter(buffer, options, stats,
severityProcessor: severityProcessor);
for (Source source in explicitSources) {
AnalysisErrorInfo errorInfo = context.getErrors(source);
var result = await analysisDriver.getErrors(source.fullName);
var errorInfo = new AnalysisErrorInfoImpl(result.errors, result.lineInfo);
formatter.formatErrors([errorInfo]);
}
formatter.flush();

View file

@ -180,7 +180,7 @@ class Driver implements CommandLineStarter {
// Do analysis.
if (options.buildMode) {
ErrorSeverity severity = _buildModeAnalyze(options);
ErrorSeverity severity = await _buildModeAnalyze(options);
// Propagate issues to the exit code.
if (_shouldBeFatal(severity, options)) {
io.exitCode = severity.ordinal;
@ -365,16 +365,20 @@ class Driver implements CommandLineStarter {
}
/// Perform analysis in build mode according to the given [options].
ErrorSeverity _buildModeAnalyze(CommandLineOptions options) {
return _analyzeAllTag.makeCurrentWhile(() {
Future<ErrorSeverity> _buildModeAnalyze(CommandLineOptions options) async {
PerformanceTag previous = _analyzeAllTag.makeCurrent();
try {
if (options.buildModePersistentWorker) {
new AnalyzerWorkerLoop.std(resourceProvider,
await new AnalyzerWorkerLoop.std(resourceProvider,
dartSdkPath: options.dartSdkPath)
.run();
return ErrorSeverity.NONE;
} else {
return new BuildMode(resourceProvider, options, stats).analyze();
return await new BuildMode(resourceProvider, options, stats).analyze();
}
});
} finally {
previous.makeCurrent();
}
}
/// Decide on the appropriate policy for which files need to be fully parsed

View file

@ -4,6 +4,8 @@
library analyzer_cli.test.built_mode;
import 'dart:async';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer_cli/src/build_mode.dart';
import 'package:analyzer_cli/src/driver.dart';
@ -30,7 +32,7 @@ class TestAnalyzerWorkerLoop extends AnalyzerWorkerLoop {
: super(new MemoryResourceProvider(), connection);
@override
void analyze(CommandLineOptions options) {
Future<Null> analyze(CommandLineOptions options) async {
if (_analyze != null) {
_analyze(options);
}