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

Unified Diff: pkg/analyzer_cli/lib/src/incremental_analyzer.dart

Issue 2039773004: Start adding experimental incremental analysis mode into CLI analyzer. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/analyzer_cli/lib/src/driver.dart ('k') | pkg/analyzer_cli/lib/src/options.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/analyzer_cli/lib/src/incremental_analyzer.dart
diff --git a/pkg/analyzer_cli/lib/src/incremental_analyzer.dart b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
new file mode 100644
index 0000000000000000000000000000000000000000..be2316537d3b9b60b458e1d5c9520d8f2142fd84
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/incremental_analyzer.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2016, 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.
+
+library analyzer_cli.src.incremental_analyzer;
+
+import 'dart:io' as io;
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/sdk_io.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/incremental_cache.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:analyzer_cli/src/options.dart';
+
+/**
+ * If the given [options] enables incremental analysis and [context] and Dart
+ * SDK implementations support incremental analysis, configure it for the
+ * given [context] and return the handle to work with it.
+ */
+IncrementalAnalysisData configureIncrementalAnalysis(
+ CommandLineOptions options, AnalysisContext context) {
+ String cachePath = options.incrementalCachePath;
+ DartSdk sdk = context.sourceFactory.dartSdk;
+ // If supported implementations, configure for incremental analysis.
+ if (cachePath != null &&
+ context is InternalAnalysisContext &&
+ sdk is DirectoryBasedDartSdk) {
+ context.typeProvider = sdk.context.typeProvider;
+ // Set the result provide from the cache.
+ CacheStorage storage = new FolderCacheStorage(
+ PhysicalResourceProvider.INSTANCE.getFolder(cachePath),
+ '${io.pid}.temp');
+ List<int> configSalt = <int>[
+ context.analysisOptions.encodeCrossContextOptions()
+ ];
+ IncrementalCache cache = new IncrementalCache(storage, context, configSalt);
+ context.resultProvider = new _CacheBasedResultProvider(context, cache);
+ // Listen for new libraries to put into the cache.
+ _IncrementalAnalysisData incrementalData =
+ new _IncrementalAnalysisData(options, cache, context);
+ context
+ .onResultChanged(LIBRARY_ELEMENT1)
+ .listen((ResultChangedEvent event) {
+ if (event.wasComputed) {
+ incrementalData.librarySources.add(event.target.source);
+ }
+ });
+ return incrementalData;
+ }
+ // Incremental analysis cannot be used.
+ return null;
+}
+
+/**
+ * Interface that is exposed to the clients of incremental analysis.
+ */
+abstract class IncrementalAnalysisData {
+ /**
+ * Finish tasks required after incremental analysis - save results into the
+ * cache, evict old results, etc.
+ */
+ void finish();
+}
+
+/**
+ * The [ResultProvider] that provides results from [IncrementalCache].
+ */
+class _CacheBasedResultProvider extends ResynthesizerResultProvider {
+ final IncrementalCache cache;
+
+ final Set<Source> sourcesWithSummaries = new Set<Source>();
+ final Set<Source> sourcesWithoutSummaries = new Set<Source>();
+ final Set<String> addedLibraryBundleIds = new Set<String>();
+
+ _CacheBasedResultProvider(InternalAnalysisContext context, this.cache)
+ : super(context, new SummaryDataStore(<String>[])) {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ createResynthesizer(sdkContext, sdkContext.typeProvider);
+ }
+
+ @override
+ bool compute(CacheEntry entry, ResultDescriptor result) {
+ AnalysisTarget target = entry.target;
+ // TODO(scheglov) remove the check after finishing optimizations.
+ if (target.source != null &&
+ target.source.fullName
+ .endsWith('analysis_server/lib/src/computer/computer_hover.dart')) {
+ return false;
+ }
+ // Source based results.
+ if (target is Source) {
+ if (result == DART_ERRORS) {
+ // TODO(scheglov) provide actual errors
+ entry.setValue(result, <AnalysisError>[], TargetedResult.EMPTY_LIST);
+ return true;
+ }
+ }
+ return super.compute(entry, result);
+ }
+
+ @override
+ bool hasResultsForSource(Source source) {
+ // Check cache states.
+ if (sourcesWithSummaries.contains(source)) {
+ return true;
+ }
+ if (sourcesWithoutSummaries.contains(source)) {
+ return false;
+ }
+ // Try to load bundles.
+ List<LibraryBundleWithId> bundles = cache.getLibraryClosureBundles(source);
+ if (bundles == null) {
+ sourcesWithoutSummaries.add(source);
+ return false;
+ }
+ // Fill the resynthesizer.
+ sourcesWithSummaries.add(source);
+ for (LibraryBundleWithId bundleWithId in bundles) {
+ if (addedLibraryBundleIds.add(bundleWithId.id)) {
+ addBundle(null, bundleWithId.bundle);
+ }
+ }
+ return true;
+ }
+}
+
+class _IncrementalAnalysisData implements IncrementalAnalysisData {
+ final CommandLineOptions commandLineOptions;
+ final IncrementalCache cache;
+ final AnalysisContext context;
+
+ final Set<Source> librarySources = new Set<Source>();
+
+ _IncrementalAnalysisData(this.commandLineOptions, this.cache, this.context);
+
+ @override
+ void finish() {
+ // Finish computing new libraries and put them into the cache.
+ for (Source librarySource in librarySources) {
+ if (!commandLineOptions.machineFormat) {
+ print('Compute library element for $librarySource');
+ }
+ LibraryElement libraryElement =
+ context.computeResult(librarySource, LIBRARY_ELEMENT);
+ // TODO(scheglov) compute and store errors
+// context.computeResult(librarySource, DART_ERRORS);
+ try {
+ cache.putLibrary(libraryElement);
+ } catch (e) {}
+ }
+ }
+}
« no previous file with comments | « pkg/analyzer_cli/lib/src/driver.dart ('k') | pkg/analyzer_cli/lib/src/options.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698