Add an option to use one-phase summaries.
When this flag is enabled, we fail:
2 language_2/ tests;
25 Analyzer tests (mostly by 2 reasons);
0 Analysis Server tests.
There is a know problem: because unlinked summaries don't include
initializers for variables, we fail to recognize API changes related
to inferred types. I will fix this be computing API signatures from
pertinent tokens.
R=brianwilkerson@google.com, paulberry@google.com
Change-Id: I61734e96ee26b3e04027a103ccf6850695815127
Reviewed-on: https://dart-review.googlesource.com/74700
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index 9bdaca9..8e90b2d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -11,6 +11,7 @@
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/analysis/defined_names.dart';
+import 'package:analyzer/src/dart/analysis/one_phase_summaries_selector.dart';
import 'package:analyzer/src/dart/analysis/referenced_names.dart';
import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
@@ -386,7 +387,8 @@
*
* If an exception happens during parsing, an empty unit is returned.
*/
- CompilationUnit parse(AnalysisErrorListener errorListener) {
+ CompilationUnit parse([AnalysisErrorListener errorListener]) {
+ errorListener ??= AnalysisErrorListener.NULL_LISTENER;
try {
return PerformanceStatistics.parse.makeCurrentWhile(() {
return _parse(errorListener);
@@ -430,9 +432,10 @@
{
bytes = _fsState._byteStore.get(_unlinkedKey);
if (bytes == null || bytes.isEmpty) {
- CompilationUnit unit = parse(AnalysisErrorListener.NULL_LISTENER);
+ CompilationUnit unit = parse();
_fsState._logger.run('Create unlinked for $path', () {
- UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
+ UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit,
+ serializeInferrableFields: !enableOnePhaseSummaries);
DefinedNames definedNames = computeDefinedNames(unit);
List<String> referencedNames = computeReferencedNames(unit).toList();
List<String> subtypedNames = computeSubtypedNames(unit).toList();
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_context.dart b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
index a212a8f..559ed4d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_context.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_context.dart
@@ -3,11 +3,13 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/declared_variables.dart';
+import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
import 'package:analyzer/dart/element/element.dart'
show CompilationUnitElement, LibraryElement;
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
+import 'package:analyzer/src/dart/analysis/one_phase_summaries_selector.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/handle.dart';
import 'package:analyzer/src/generated/engine.dart'
@@ -16,7 +18,9 @@
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/one_phase.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:front_end/src/api_prototype/byte_store.dart';
import 'package:front_end/src/base/performance_logger.dart';
@@ -93,7 +97,8 @@
appendLibraryFiles(targetLibrary);
});
- Set<String> libraryUrisToLink = new Set<String>();
+ var libraryUrisToLink = new Set<String>();
+ var libraryFilesToLink = new Set<FileState>();
logger.run('Load linked bundles', () {
for (FileState library in libraries.values) {
if (library.exists || library == targetLibrary) {
@@ -104,6 +109,7 @@
store.addLinkedLibrary(library.uriStr, linked);
} else {
libraryUrisToLink.add(library.uriStr);
+ libraryFilesToLink.add(library);
}
}
}
@@ -112,16 +118,47 @@
});
Map<String, LinkedLibraryBuilder> linkedLibraries = {};
- logger.run('Link bundles', () {
- linkedLibraries = link(libraryUrisToLink, (String uri) {
- LinkedLibrary linkedLibrary = store.linkedMap[uri];
- return linkedLibrary;
- }, (String uri) {
- UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
- return unlinkedUnit;
- }, (_) => null);
- logger.writeln('Linked ${linkedLibraries.length} bundles.');
- });
+ if (enableOnePhaseSummaries) {
+ var uriToUnit = <String, CompilationUnit>{};
+ logger.run('Parse files', () {
+ for (var library in libraryFilesToLink) {
+ for (var file in library.libraryFiles) {
+ uriToUnit[file.uriStr] = file.parse();
+ }
+ }
+ logger.writeln('Parsed ${uriToUnit.length} files.');
+ });
+
+ logger.run('Link libraries', () {
+ var assembler = new PackageBundleAssembler();
+ summarize(uriToUnit, store, assembler, (_) => null, true);
+
+ var bundle = assembler.assemble();
+ for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+ var uri = bundle.linkedLibraryUris[i];
+
+ // TODO(scheglov) At the moment we might get parts here.
+ if (!libraries.containsKey(uri)) {
+ continue;
+ }
+
+ linkedLibraries[uri] = bundle.linkedLibraries[i];
+ }
+
+ logger.writeln('Linked ${linkedLibraries.length} libraries.');
+ });
+ } else {
+ logger.run('Link libraries', () {
+ linkedLibraries = link(libraryUrisToLink, (String uri) {
+ LinkedLibrary linkedLibrary = store.linkedMap[uri];
+ return linkedLibrary;
+ }, (String uri) {
+ UnlinkedUnit unlinkedUnit = store.unlinkedMap[uri];
+ return unlinkedUnit;
+ }, (_) => null);
+ logger.writeln('Linked ${linkedLibraries.length} libraries.');
+ });
+ }
for (String uri in linkedLibraries.keys) {
LinkedLibraryBuilder linkedBuilder = linkedLibraries[uri];
diff --git a/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart b/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart
new file mode 100644
index 0000000..c172ea1
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/analysis/one_phase_summaries_selector.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2018, 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.
+
+/// A flag indicating whether analysis driver should work using one-phase,
+/// unresolved AST based summaries, or using old unlinked / link process.
+const bool enableOnePhaseSummaries =
+ const bool.fromEnvironment('enableOnePhaseSummaries', defaultValue: false);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index d8db996..ca03d8e 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -909,7 +909,7 @@
// Notify the driver about the change.
driver.changeFile(testFile);
- // The file was added, so it is scheduled for analysis.
+ // The file was changed, so it is scheduled for analysis.
expect(driver.test.fileTracker.isFilePending(testFile), isTrue);
// We get a new result.