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 .
This commit is contained in:
Konstantin Shcheglov
2017-08-11 12:00:33 -07:00
parent 0647d9a228
commit ada4db3fb6
3 changed files with 86 additions and 24 deletions
@@ -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<Null> _loadSdkOutline() async {
Future<Null> _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);
}
});
}
}
@@ -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<String> 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<core::String> 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 {
@@ -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<String> 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<dart.core::String>');
{
// 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<dart.core::String>');
// 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 {