Skip to content

update frontend server compile api to always return a result, but have a nullable output dill #1641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions frontend_server_client/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
## 3.0.0-dev

- Update the `compile` api to return a non-null `CompileResult`, and instead
make the `dillOutput` field nullable. This allows you to still get compiler
output if no dill file was produced.

## 2.1.3

- Update `package:vm_service` to version `^8.0.0`

## 2.1.2
Expand Down
4 changes: 2 additions & 2 deletions frontend_server_client/example/vm_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void main(List<String> args) async {
Process appProcess;
final vmServiceCompleter = Completer<VmService>();
appProcess = await Process.start(Platform.resolvedExecutable,
['--observe', '--no-pause-isolates-on-exit', result!.dillOutput]);
['--observe', '--no-pause-isolates-on-exit', result.dillOutput!]);
appProcess.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
Expand Down Expand Up @@ -65,7 +65,7 @@ void main(List<String> args) async {
_print('reloading $app');
var vm = await vmService.getVM();
await vmService.reloadSources(vm.isolates!.first.id!,
rootLibUri: result!.dillOutput);
rootLibUri: result.dillOutput!);

_print('restoring $app to original contents');
await appFile.writeAsString(originalContent);
Expand Down
1 change: 0 additions & 1 deletion frontend_server_client/example/web_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8
import 'dart:convert';
import 'dart:io';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
String bootstrapJs() => throw UnimplementedError();

/// Updates [_assets] for [result].
void _updateAssets(CompileResult? result) {
if (result == null) {
void _updateAssets(CompileResult result) {
if (result.dillOutput == null) {
return;
}
final manifest =
jsonDecode(File(result.jsManifestOutput).readAsStringSync())
jsonDecode(File(result.jsManifestOutput!).readAsStringSync())
as Map<String, dynamic>;
final sourceBytes = File(result.jsSourcesOutput).readAsBytesSync();
final sourceMapBytes = File(result.jsSourceMapsOutput).readAsBytesSync();
final sourceBytes = File(result.jsSourcesOutput!).readAsBytesSync();
final sourceMapBytes = File(result.jsSourceMapsOutput!).readAsBytesSync();

for (var entry in manifest.entries) {
var metadata = entry.value as Map<String, dynamic>;
Expand All @@ -130,7 +130,7 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
}

@override
Future<CompileResult?> compile([List<Uri>? invalidatedUris]) async {
Future<CompileResult> compile([List<Uri>? invalidatedUris]) async {
return _lastResult = await _frontendServerClient.compile(invalidatedUris);
}

Expand Down Expand Up @@ -168,7 +168,7 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
@override
void accept() {
_frontendServerClient.accept();
_updateAssets(_lastResult);
if (_lastResult != null) _updateAssets(_lastResult!);
_lastResult = null;
}

Expand Down
21 changes: 10 additions & 11 deletions frontend_server_client/lib/src/frontend_server_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class FrontendServerClient {
/// [invalidatedUris] must not be null for all but the very first compile.
///
/// The frontend server _does not_ do any of its own invalidation.
Future<CompileResult?> compile([List<Uri>? invalidatedUris]) async {
Future<CompileResult> compile([List<Uri>? invalidatedUris]) async {
String action;
switch (_state) {
case _ClientState.waitingForFirstCompile:
Expand Down Expand Up @@ -190,10 +190,6 @@ class FrontendServerClient {
}
}

if (outputDillPath == null) {
return null;
}

return CompileResult._(
dillOutput: outputDillPath,
errorCount: errorCount,
Expand Down Expand Up @@ -339,9 +335,9 @@ class CompileResult {
required this.newSources,
required this.removedSources});

/// The produced dill output file, this will either be a full dill file or an
/// incremental dill file.
final String dillOutput;
/// The produced dill output file, this will either be a full dill file, an
/// incremental dill file, or `null` if no file was produced.
final String? dillOutput;

/// All output from the compiler, typically this would contain errors or
/// warnings.
Expand All @@ -354,16 +350,19 @@ class CompileResult {
/// A single file containing all source maps for all JS outputs.
///
/// Read [jsManifestOutput] for file offsets for each sourcemap.
String get jsSourceMapsOutput => '$dillOutput.map';
String? get jsSourceMapsOutput =>
dillOutput == null ? null : '$dillOutput.map';

/// A single file containing all JS outputs.
///
/// Read [jsManifestOutput] for file offsets for each source.
String get jsSourcesOutput => '$dillOutput.sources';
String? get jsSourcesOutput =>
dillOutput == null ? null : '$dillOutput.sources';

/// A JSON manifest containing offsets for the sources and source maps in
/// the [jsSourcesOutput] and [jsSourceMapsOutput] files.
String get jsManifestOutput => '$dillOutput.json';
String? get jsManifestOutput =>
dillOutput == null ? null : '$dillOutput.json';

/// All the transitive source dependencies that were added as a part of this
/// compile.
Expand Down
7 changes: 6 additions & 1 deletion frontend_server_client/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: frontend_server_client
version: 2.1.3
version: 3.0.0-dev
description: >-
Client code to start and interact with the frontend_server compiler from the
Dart SDK.
Expand All @@ -20,3 +20,8 @@ dev_dependencies:
test: ^1.16.0
test_descriptor: ^2.0.0
vm_service: ^8.0.0

dependency_overrides:
# Necessary to get a version solve until test_core allows version 3.x of
# this package
test_core: ^0.4.13
63 changes: 22 additions & 41 deletions frontend_server_client/test/frontend_sever_client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,10 @@ dependencies:
path: ^1.0.0

environment:
sdk: '>=2.12.0-0 <3.0.0'
sdk: '>=2.12.0 <3.0.0'
'''),
d.dir('bin', [
d.file('main.dart', '''
// @dart = 2.8
import 'package:path/path.dart' as p;

void main() async {
Expand Down Expand Up @@ -64,9 +63,6 @@ String get message => p.join('hello', 'world');
client = await FrontendServerClient.start(
entrypoint, p.join(packageRoot, 'out.dill'), vmPlatformDill);
var result = await client.compile();
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();
expect(result.compilerOutputLines, isEmpty);
expect(result.errorCount, 0);
Expand All @@ -77,12 +73,13 @@ String get message => p.join('hello', 'world');
packageConfig.resolve(Uri.parse('package:path/path.dart')),
]));
expect(result.removedSources, isEmpty);
expect(File(result.dillOutput).existsSync(), true);
expect(result.dillOutput, isNotNull);
expect(File(result.dillOutput!).existsSync(), true);
var process = await Process.start(Platform.resolvedExecutable, [
'--observe',
'--no-pause-isolates-on-exit',
'--pause-isolates-on-start',
result.dillOutput
result.dillOutput!
]);
addTearDown(process.kill);
var stdoutLines = StreamQueue(
Expand All @@ -102,9 +99,6 @@ String get message => p.join('hello', 'world');
await appFile.writeAsString(newContent);

result = await client.compile([File(entrypoint).uri]);
if (result == null) {
fail('Expected compilation to be non-null');
}

client.accept();
expect(result.newSources, isEmpty);
Expand All @@ -130,9 +124,6 @@ String get message => p.join('hello', 'world');
client = await FrontendServerClient.start(
entrypoint, p.join(packageRoot, 'out.dill'), vmPlatformDill);
var result = await client.compile();
if (result == null) {
fail('Expected compilation to be non-null');
}

client.accept();
expect(result.errorCount, 2);
Expand All @@ -145,13 +136,14 @@ String get message => p.join('hello', 'world');
packageConfig.resolve(Uri.parse('package:path/path.dart')),
]));
expect(result.removedSources, isEmpty);
expect(File(result.dillOutput).existsSync(), true);
expect(result.dillOutput, isNotNull);
expect(File(result.dillOutput!).existsSync(), true);

var process = await Process.start(Platform.resolvedExecutable, [
'--observe',
'--no-pause-isolates-on-exit',
'--pause-isolates-on-start',
result.dillOutput
result.dillOutput!
]);
addTearDown(process.kill);
var stdoutLines = StreamQueue(
Expand All @@ -170,15 +162,13 @@ String get message => p.join('hello', 'world');
await entrypointFile
.writeAsString(originalContent.replaceFirst('hello', 'goodbye'));
result = await client.compile([entrypointFile.uri]);
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();
expect(result.errorCount, 0);
expect(result.compilerOutputLines, isEmpty);
expect(result.newSources, isEmpty);
expect(result.removedSources, isEmpty);
expect(File(result.dillOutput).existsSync(), true);
expect(result.dillOutput, isNotNull);
expect(File(result.dillOutput!).existsSync(), true);

await vmService.reloadSources(isolate.id!, rootLibUri: result.dillOutput);

Expand All @@ -190,11 +180,12 @@ String get message => p.join('hello', 'world');
var entrypoint =
p.toUri(p.join(packageRoot, 'bin', 'main.dart')).toString();
var dartDevcClient = client = await DartDevcFrontendServerClient.start(
entrypoint, p.join(packageRoot, 'out.dill'));
entrypoint, p.join(packageRoot, 'out.dill'),
platformKernel: p
.toUri(
p.join(sdkDir, 'lib', '_internal', 'ddc_platform_sound.dill'))
.toString());
var result = await client.compile();
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();

expect(result.compilerOutputLines, isEmpty);
Expand All @@ -207,9 +198,10 @@ String get message => p.join('hello', 'world');
]));
expect(result.removedSources, isEmpty);

expect(File(result.jsManifestOutput).existsSync(), true);
expect(File(result.jsSourcesOutput).existsSync(), true);
expect(File(result.jsSourceMapsOutput).existsSync(), true);
expect(result.dillOutput, isNotNull);
expect(File(result.jsManifestOutput!).existsSync(), true);
expect(File(result.jsSourcesOutput!).existsSync(), true);
expect(File(result.jsSourceMapsOutput!).existsSync(), true);

var entrypointUri = Uri.parse(entrypoint);
expect(
Expand All @@ -222,9 +214,6 @@ String get message => p.join('hello', 'world');
await appFile.writeAsString(newContent);

result = await client.compile([entrypointUri]);
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();
expect(result.newSources, isEmpty);
expect(result.removedSources, isEmpty);
Expand Down Expand Up @@ -257,9 +246,6 @@ void main() {
entrypoint, p.join(packageRoot, 'out.dill'), vmPlatformDill,
enabledExperiments: ['non-nullable']);
var result = await client.compile();
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();
expect(result.errorCount, 1);
expect(result.compilerOutputLines, contains(contains('int x;')));
Expand All @@ -280,9 +266,6 @@ void main() {
client = await FrontendServerClient.start(entrypoint,
p.join(packageRoot, 'out with spaces.dill'), vmPlatformDill);
var result = await client.compile();
if (result == null) {
fail('Expected compilation to be non-null');
}
client.accept();
expect(result.compilerOutputLines, isEmpty);
expect(result.errorCount, 0);
Expand All @@ -292,9 +275,10 @@ void main() {
File(entrypoint).uri,
]));
expect(result.removedSources, isEmpty);
expect(File(result.dillOutput).existsSync(), true);
expect(result.dillOutput, isNotNull);
expect(File(result.dillOutput!).existsSync(), true);
var processResult =
await Process.run(Platform.resolvedExecutable, [result.dillOutput]);
await Process.run(Platform.resolvedExecutable, [result.dillOutput!]);

expect(processResult.stdout, startsWith('hello world'));
expect(processResult.exitCode, 0);
Expand All @@ -304,16 +288,13 @@ void main() {
var newContent = originalContent.replaceFirst('hello', 'goodbye');
await appFile.writeAsString(newContent);
result = await client.compile([appFile.uri]);
if (result == null) {
fail('Expected compilation to be non-null');
}
expect(result.compilerOutputLines, isEmpty);
expect(result.errorCount, 0);
expect(result.newSources, isEmpty);
expect(result.removedSources, isEmpty);

processResult =
await Process.run(Platform.resolvedExecutable, [result.dillOutput]);
await Process.run(Platform.resolvedExecutable, [result.dillOutput!]);
expect(processResult.stdout, startsWith('goodbye world'));
expect(processResult.exitCode, 0);
});
Expand Down