From ada4db3fb6c7cb067e0f0bb98f9ec23d9362e5a5 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Fri, 11 Aug 2017 12:00:33 -0700 Subject: [PATCH] When using SDK outline, transplant its names into the name root. It's a bit messy that we have to break immutability of CanonicalName(s) here. The alternative is not re-load SDK outline from bytes every time. It is relatively expensive for small tests, although probably relatively less expensive for large apps when we load hundreds of other libraries. Thoughts? R=ahe@google.com, paulberry@google.com, sigmund@google.com BUG= https://github.com/dart-lang/sdk/issues/30409 Review-Url: https://codereview.chromium.org/2995773002 . --- .../lib/src/incremental/kernel_driver.dart | 27 +++++------ .../incremental_kernel_generator_test.dart | 36 +++++++++++--- .../src/incremental/kernel_driver_test.dart | 47 +++++++++++++++++-- 3 files changed, 86 insertions(+), 24 deletions(-) diff --git a/pkg/front_end/lib/src/incremental/kernel_driver.dart b/pkg/front_end/lib/src/incremental/kernel_driver.dart index 4e029a276c1..be9b602b199 100644 --- a/pkg/front_end/lib/src/incremental/kernel_driver.dart +++ b/pkg/front_end/lib/src/incremental/kernel_driver.dart @@ -8,6 +8,7 @@ import 'package:front_end/file_system.dart'; import 'package:front_end/src/base/api_signature.dart'; import 'package:front_end/src/base/performace_logger.dart'; import 'package:front_end/src/base/processed_options.dart'; +import 'package:front_end/src/byte_store/byte_store.dart'; import 'package:front_end/src/fasta/compiler_context.dart'; import 'package:front_end/src/fasta/dill/dill_library_builder.dart'; import 'package:front_end/src/fasta/dill/dill_target.dart'; @@ -15,7 +16,6 @@ import 'package:front_end/src/fasta/kernel/kernel_target.dart'; import 'package:front_end/src/fasta/kernel/utils.dart'; import 'package:front_end/src/fasta/ticker.dart'; import 'package:front_end/src/fasta/uri_translator.dart'; -import 'package:front_end/src/byte_store/byte_store.dart'; import 'package:front_end/src/incremental/file_state.dart'; import 'package:kernel/binary/ast_from_binary.dart'; import 'package:kernel/core_types.dart'; @@ -131,9 +131,11 @@ class KernelDriver { return await runWithFrontEndContext('Compute delta', () async { await _refreshInvalidatedFiles(); + CanonicalName nameRoot = new CanonicalName.root(); + // Load the SDK outline before building the graph, so that the file // system state is configured to skip SDK libraries. - await _loadSdkOutline(); + await _loadSdkOutline(nameRoot); // Ensure that the graph starting at the entry point is ready. FileState entryLibrary = @@ -147,7 +149,6 @@ class KernelDriver { return cycles; }); - CanonicalName nameRoot = new CanonicalName.root(); DillTarget dillTarget = new DillTarget( new Ticker(isVerbose: false), _uriTranslator, _options.target); @@ -359,18 +360,16 @@ class KernelDriver { /// Load the SDK outline if its bytes are provided, and configure the file /// system state to skip SDK library files. - Future _loadSdkOutline() async { + Future _loadSdkOutline(CanonicalName nameRoot) async { if (_sdkOutlineBytes != null) { - if (_sdkOutline == null) { - await _logger.runAsync('Load SDK outline from bytes.', () async { - _sdkOutline = new Program(); - new BinaryBuilder(_sdkOutlineBytes).readProgram(_sdkOutline); - // Configure the file system state to skip the outline libraries. - for (var outlineLibrary in _sdkOutline.libraries) { - _fsState.skipSdkLibraries.add(outlineLibrary.importUri); - } - }); - } + await _logger.runAsync('Load SDK outline from bytes.', () async { + _sdkOutline = new Program(nameRoot: nameRoot); + new BinaryBuilder(_sdkOutlineBytes).readProgram(_sdkOutline); + // Configure the file system state to skip the outline libraries. + for (var outlineLibrary in _sdkOutline.libraries) { + _fsState.skipSdkLibraries.add(outlineLibrary.importUri); + } + }); } } diff --git a/pkg/front_end/test/incremental_kernel_generator_test.dart b/pkg/front_end/test/incremental_kernel_generator_test.dart index 184c0a1c73b..226d6dc632d 100644 --- a/pkg/front_end/test/incremental_kernel_generator_test.dart +++ b/pkg/front_end/test/incremental_kernel_generator_test.dart @@ -8,6 +8,7 @@ import 'package:front_end/compiler_options.dart'; import 'package:front_end/incremental_kernel_generator.dart'; import 'package:front_end/memory_file_system.dart'; import 'package:front_end/src/byte_store/byte_store.dart'; +import 'package:front_end/src/fasta/kernel/utils.dart'; import 'package:front_end/src/incremental_kernel_generator_impl.dart'; import 'package:front_end/summary_generator.dart'; import 'package:kernel/ast.dart'; @@ -201,19 +202,29 @@ b() { fileSystem.entityForUri(sdkOutlineUri).writeAsBytesSync(sdkOutlineBytes); writeFile('/test/.packages', 'test:lib/'); - String path = '/test/lib/test.dart'; - Uri uri = writeFile(path, r''' + String aPath = '/test/lib/a.dart'; + String bPath = '/test/lib/b.dart'; + Uri aUri = writeFile(aPath, r''' +int getValue() { + return 1; +} +'''); + Uri bUri = writeFile(bPath, r''' import 'dart:async'; +import 'a.dart'; + var a = 1; Future b; '''); - Program program = await getInitialState(uri, sdkOutlineUri: sdkOutlineUri); + Program program = await getInitialState(bUri, sdkOutlineUri: sdkOutlineUri); + incrementalKernelGenerator.acceptLastDelta(); _assertLibraryUris(program, - includes: [uri], excludes: [Uri.parse('dart:core')]); + includes: [bUri], excludes: [Uri.parse('dart:core')]); - Library library = _getLibrary(program, uri); - expect(_getLibraryText(library), r'''library; + Library library = _getLibrary(program, bUri); + expect(_getLibraryText(library), r''' +library; import self as self; import "dart:core" as core; import "dart:async" as asy; @@ -221,6 +232,19 @@ import "dart:async" as asy; static field core::int a = 1; static field asy::Future b; '''); + + // Update a.dart and recompile. + writeFile(aPath, r''' +int getValue() { + return 2; +} +'''); + incrementalKernelGenerator.invalidate(aUri); + var deltaProgram = await incrementalKernelGenerator.computeDelta(); + + // Check that the canonical names for SDK libraries are serializable. + serializeProgram(deltaProgram.newProgram, + filter: (library) => !library.importUri.isScheme('dart')); } test_computeDelta_hasAnotherRunning() async { diff --git a/pkg/front_end/test/src/incremental/kernel_driver_test.dart b/pkg/front_end/test/src/incremental/kernel_driver_test.dart index 0bb7511ecdd..f4de69e9097 100644 --- a/pkg/front_end/test/src/incremental/kernel_driver_test.dart +++ b/pkg/front_end/test/src/incremental/kernel_driver_test.dart @@ -8,9 +8,9 @@ import 'package:front_end/compiler_options.dart'; import 'package:front_end/memory_file_system.dart'; import 'package:front_end/src/base/performace_logger.dart'; import 'package:front_end/src/base/processed_options.dart'; +import 'package:front_end/src/byte_store/byte_store.dart'; import 'package:front_end/src/fasta/kernel/utils.dart'; import 'package:front_end/src/fasta/uri_translator_impl.dart'; -import 'package:front_end/src/byte_store/byte_store.dart'; import 'package:front_end/src/incremental/kernel_driver.dart'; import 'package:front_end/summary_generator.dart'; import 'package:kernel/ast.dart'; @@ -295,24 +295,63 @@ static field (core::String) → core::int f; writeFile('/test/.packages', 'test:lib/'); String aPath = '/test/lib/a.dart'; + String bPath = '/test/lib/b.dart'; Uri aUri = writeFile(aPath, r''' +int getValue() { + return 1; +} +'''); + Uri bUri = writeFile(bPath, r''' import 'dart:async'; +import 'a.dart'; var a = 1; Future b; '''); - KernelResult result = await driver.getKernel(aUri); + KernelResult result = await driver.getKernel(bUri); // The result does not include SDK libraries. _assertLibraryUris(result, - includes: [aUri], + includes: [bUri], excludes: [Uri.parse('dart:core'), Uri.parse('dart:core')]); // The types of top-level variables are resolved. - var library = _getLibrary(result, aUri); + var library = _getLibrary(result, bUri); expect(library.fields[0].type.toString(), 'dart.core::int'); expect(library.fields[1].type.toString(), 'dart.async::Future'); + + { + // Update a.dart and recompile. + writeFile(aPath, r''' +int getValue() { + return 2; +} +'''); + driver.invalidate(aUri); + var kernelResult = await driver.getKernel(bUri); + var allLibraries = kernelResult.results + .map((c) => c.kernelLibraries) + .expand((libs) => libs) + .toList(); + + // The result does not include SDK libraries. + _assertLibraryUris(result, + includes: [bUri], + excludes: [Uri.parse('dart:core'), Uri.parse('dart:core')]); + + // The types of top-level variables are resolved. + var library = _getLibrary(result, bUri); + expect(library.fields[0].type.toString(), 'dart.core::int'); + expect(library.fields[1].type.toString(), + 'dart.async::Future'); + + // We should be able to serialize the libraries without SDK. + var program = + new Program(nameRoot: kernelResult.nameRoot, libraries: allLibraries); + serializeProgram(program, + filter: (library) => !library.importUri.isScheme('dart')); + } } test_limitedStore_exportDependencies() async {