Format frontend_server_client
Change-Id: Ibfdf6a7afedaf9e1486624a85e7d04437db13e49 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494460 Reviewed-by: Nicholas Shahan <nshahan@google.com> Commit-Queue: Nicholas Shahan <nshahan@google.com> Auto-Submit: Jonas Jensen <jonasfj@google.com>
This commit is contained in:
committed by
Commit Queue
parent
ef6054d688
commit
8ffc0dddd0
@@ -174,8 +174,8 @@ void _print(String message) {
|
||||
}
|
||||
|
||||
void _prompt() => stdout.write(
|
||||
'Enter a new message to print and recompile, or type `quit` to exit:',
|
||||
);
|
||||
'Enter a new message to print and recompile, or type `quit` to exit:',
|
||||
);
|
||||
|
||||
final app = 'example/app/main.dart';
|
||||
final dartSdkJs = p.join('.dart_tool', 'out', 'dart_sdk.js');
|
||||
|
||||
@@ -41,16 +41,19 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
final String? _mainModuleJs;
|
||||
|
||||
DartDevcFrontendServerClient._(
|
||||
this._frontendServerClient, this._entrypoint, String moduleFormat)
|
||||
: _bootstrapJs = moduleFormat == 'amd'
|
||||
? generateAmdBootstrapScript(
|
||||
requireUrl: 'require.js',
|
||||
mapperUrl: 'dart_stack_trace_mapper.js',
|
||||
entrypoint: _entrypoint)
|
||||
: null,
|
||||
_mainModuleJs = moduleFormat == 'amd'
|
||||
? generateAmdMainModule(entrypoint: _entrypoint)
|
||||
: null {
|
||||
this._frontendServerClient,
|
||||
this._entrypoint,
|
||||
String moduleFormat,
|
||||
) : _bootstrapJs = moduleFormat == 'amd'
|
||||
? generateAmdBootstrapScript(
|
||||
requireUrl: 'require.js',
|
||||
mapperUrl: 'dart_stack_trace_mapper.js',
|
||||
entrypoint: _entrypoint,
|
||||
)
|
||||
: null,
|
||||
_mainModuleJs = moduleFormat == 'amd'
|
||||
? generateAmdMainModule(entrypoint: _entrypoint)
|
||||
: null {
|
||||
_resetAssets();
|
||||
}
|
||||
|
||||
@@ -86,7 +89,10 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
verbose: verbose,
|
||||
);
|
||||
return DartDevcFrontendServerClient._(
|
||||
feServer, Uri.parse(entrypoint).path, dartdevcModuleFormat);
|
||||
feServer,
|
||||
Uri.parse(entrypoint).path,
|
||||
dartdevcModuleFormat,
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the current bytes for the asset at [path].
|
||||
@@ -121,11 +127,15 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
for (final entry in manifest.entries) {
|
||||
final metadata = entry.value as Map<String, dynamic>;
|
||||
final sourceOffsets = metadata['code'] as List;
|
||||
_assets[entry.key] =
|
||||
sourceBytes.sublist(sourceOffsets[0] as int, sourceOffsets[1] as int);
|
||||
_assets[entry.key] = sourceBytes.sublist(
|
||||
sourceOffsets[0] as int,
|
||||
sourceOffsets[1] as int,
|
||||
);
|
||||
final sourceMapOffsets = metadata['sourcemap'] as List;
|
||||
_assets['${entry.key}.map'] = sourceMapBytes.sublist(
|
||||
sourceMapOffsets[0] as int, sourceMapOffsets[1] as int);
|
||||
sourceMapOffsets[0] as int,
|
||||
sourceMapOffsets[1] as int,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,9 +152,9 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
required String klass,
|
||||
required String libraryUri,
|
||||
required List<String> typeDefinitions,
|
||||
}) =>
|
||||
throw UnsupportedError(
|
||||
'Use `compileExpressionToJs` for dartdevc based clients');
|
||||
}) => throw UnsupportedError(
|
||||
'Use `compileExpressionToJs` for dartdevc based clients',
|
||||
);
|
||||
|
||||
@override
|
||||
Future<CompileResult> compileExpressionToJs({
|
||||
@@ -155,15 +165,15 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
required String libraryUri,
|
||||
required int line,
|
||||
required String moduleName,
|
||||
}) =>
|
||||
_frontendServerClient.compileExpressionToJs(
|
||||
expression: expression,
|
||||
column: column,
|
||||
jsFrameValues: jsFrameValues,
|
||||
jsModules: jsModules,
|
||||
libraryUri: libraryUri,
|
||||
line: line,
|
||||
moduleName: moduleName);
|
||||
}) => _frontendServerClient.compileExpressionToJs(
|
||||
expression: expression,
|
||||
column: column,
|
||||
jsFrameValues: jsFrameValues,
|
||||
jsModules: jsModules,
|
||||
libraryUri: libraryUri,
|
||||
line: line,
|
||||
moduleName: moduleName,
|
||||
);
|
||||
|
||||
@override
|
||||
void accept() {
|
||||
@@ -201,11 +211,13 @@ class DartDevcFrontendServerClient implements FrontendServerClient {
|
||||
}
|
||||
final mainModuleJs = _mainModuleJs;
|
||||
if (mainModuleJs != null) {
|
||||
_assets['$_entrypoint.bootstrap.js'] =
|
||||
Uint8List.fromList(utf8.encode(mainModuleJs));
|
||||
_assets['$_entrypoint.bootstrap.js'] = Uint8List.fromList(
|
||||
utf8.encode(mainModuleJs),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final _dartdevcPlatformKernel =
|
||||
p.toUri(p.join(sdkDir, 'lib', '_internal', 'ddc_sdk.dill')).toString();
|
||||
final _dartdevcPlatformKernel = p
|
||||
.toUri(p.join(sdkDir, 'lib', '_internal', 'ddc_sdk.dill'))
|
||||
.toString();
|
||||
|
||||
@@ -21,10 +21,12 @@ class FrontendServerClient {
|
||||
_ClientState _state;
|
||||
|
||||
FrontendServerClient._(
|
||||
this._entrypoint, this._feServer, this._feServerStdoutLines,
|
||||
{bool? verbose})
|
||||
: _verbose = verbose ?? false,
|
||||
_state = _ClientState.waitingForFirstCompile {
|
||||
this._entrypoint,
|
||||
this._feServer,
|
||||
this._feServerStdoutLines, {
|
||||
bool? verbose,
|
||||
}) : _verbose = verbose ?? false,
|
||||
_state = _ClientState.waitingForFirstCompile {
|
||||
_feServer.stderr.transform(utf8.decoder).listen(stderr.write);
|
||||
}
|
||||
|
||||
@@ -89,49 +91,39 @@ class FrontendServerClient {
|
||||
if (enabledExperiments != null)
|
||||
for (final experiment in enabledExperiments)
|
||||
'--enable-experiment=$experiment',
|
||||
for (final source in additionalSources) ...[
|
||||
'--source',
|
||||
source,
|
||||
],
|
||||
if (nativeAssets != null) ...[
|
||||
'--native-assets',
|
||||
nativeAssets,
|
||||
],
|
||||
for (final source in additionalSources) ...['--source', source],
|
||||
if (nativeAssets != null) ...['--native-assets', nativeAssets],
|
||||
];
|
||||
late final Process feServer;
|
||||
if (frontendServerPath != null) {
|
||||
feServer = await Process.start(
|
||||
Platform.resolvedExecutable,
|
||||
<String>[
|
||||
if (debug) '--observe',
|
||||
frontendServerPath,
|
||||
...commonArguments,
|
||||
],
|
||||
);
|
||||
feServer = await Process.start(Platform.resolvedExecutable, <String>[
|
||||
if (debug) '--observe',
|
||||
frontendServerPath,
|
||||
...commonArguments,
|
||||
]);
|
||||
} else if (File(_feServerAotSnapshotPath).existsSync()) {
|
||||
if (debug) {
|
||||
throw ArgumentError('The debug argument cannot be set to true when the '
|
||||
'frontendServerPath argument is omitted.');
|
||||
throw ArgumentError(
|
||||
'The debug argument cannot be set to true when the '
|
||||
'frontendServerPath argument is omitted.',
|
||||
);
|
||||
}
|
||||
feServer = await Process.start(
|
||||
_dartAotRuntimePath,
|
||||
<String>[_feServerAotSnapshotPath, ...commonArguments],
|
||||
);
|
||||
feServer = await Process.start(_dartAotRuntimePath, <String>[
|
||||
_feServerAotSnapshotPath,
|
||||
...commonArguments,
|
||||
]);
|
||||
} else {
|
||||
// AOT snapshots cannot be generated on IA32, so we need this fallback
|
||||
// branch until support for IA32 is dropped (https://dartbug.com/49969).
|
||||
feServer = await Process.start(
|
||||
Platform.resolvedExecutable,
|
||||
<String>[
|
||||
if (debug) '--observe',
|
||||
_feServerAppJitSnapshotPath,
|
||||
...commonArguments,
|
||||
],
|
||||
);
|
||||
feServer = await Process.start(Platform.resolvedExecutable, <String>[
|
||||
if (debug) '--observe',
|
||||
_feServerAppJitSnapshotPath,
|
||||
...commonArguments,
|
||||
]);
|
||||
}
|
||||
final feServerStdoutLines = StreamQueue(feServer.stdout
|
||||
.transform(utf8.decoder)
|
||||
.transform(const LineSplitter()));
|
||||
final feServerStdoutLines = StreamQueue(
|
||||
feServer.stdout.transform(utf8.decoder).transform(const LineSplitter()),
|
||||
);
|
||||
|
||||
// The frontend_server doesn't appear to recursively create files, so we
|
||||
// need to make sure the output dir already exists.
|
||||
@@ -162,16 +154,20 @@ class FrontendServerClient {
|
||||
break;
|
||||
case _ClientState.waitingForAcceptOrReject:
|
||||
throw StateError(
|
||||
'Previous `CompileResult` must be accepted or rejected by '
|
||||
'calling `accept` or `reject`.');
|
||||
'Previous `CompileResult` must be accepted or rejected by '
|
||||
'calling `accept` or `reject`.',
|
||||
);
|
||||
case _ClientState.compiling:
|
||||
throw StateError(
|
||||
'App is already being compiled, you must wait for that to '
|
||||
'complete and `accept` or `reject` the result before compiling '
|
||||
'again.');
|
||||
'App is already being compiled, you must wait for that to '
|
||||
'complete and `accept` or `reject` the result before compiling '
|
||||
'again.',
|
||||
);
|
||||
case _ClientState.rejecting:
|
||||
throw StateError('Still waiting for previous `reject` call to finish. '
|
||||
'You must await that before compiling again.');
|
||||
throw StateError(
|
||||
'Still waiting for previous `reject` call to finish. '
|
||||
'You must await that before compiling again.',
|
||||
);
|
||||
}
|
||||
_state = _ClientState.compiling;
|
||||
|
||||
@@ -180,8 +176,9 @@ class FrontendServerClient {
|
||||
if (action == 'recompile') {
|
||||
if (invalidatedUris == null || invalidatedUris.isEmpty) {
|
||||
throw StateError(
|
||||
'Subsequent compile invocations must provide a non-empty list '
|
||||
'of invalidated uris.');
|
||||
'Subsequent compile invocations must provide a non-empty list '
|
||||
'of invalidated uris.',
|
||||
);
|
||||
}
|
||||
final boundaryKey = generateUuidV4();
|
||||
command.writeln(' $boundaryKey');
|
||||
@@ -199,8 +196,8 @@ class FrontendServerClient {
|
||||
final compilerOutputLines = <String>[];
|
||||
var errorCount = 0;
|
||||
String? outputDillPath;
|
||||
while (
|
||||
state != _CompileState.done && await _feServerStdoutLines.hasNext) {
|
||||
while (state != _CompileState.done &&
|
||||
await _feServerStdoutLines.hasNext) {
|
||||
final line = await _nextInputLine();
|
||||
switch (state) {
|
||||
case _CompileState.started:
|
||||
@@ -230,8 +227,9 @@ class FrontendServerClient {
|
||||
removedSources.add(diffUri);
|
||||
} else {
|
||||
throw StateError(
|
||||
'unrecognized diff line, should start with a + or - '
|
||||
'but got: $line');
|
||||
'unrecognized diff line, should start with a + or - '
|
||||
'but got: $line',
|
||||
);
|
||||
}
|
||||
continue;
|
||||
case _CompileState.done:
|
||||
@@ -240,11 +238,12 @@ class FrontendServerClient {
|
||||
}
|
||||
|
||||
return CompileResult._(
|
||||
dillOutput: outputDillPath,
|
||||
errorCount: errorCount,
|
||||
newSources: newSources,
|
||||
removedSources: removedSources,
|
||||
compilerOutputLines: compilerOutputLines);
|
||||
dillOutput: outputDillPath,
|
||||
errorCount: errorCount,
|
||||
newSources: newSources,
|
||||
removedSources: removedSources,
|
||||
compilerOutputLines: compilerOutputLines,
|
||||
);
|
||||
} finally {
|
||||
_state = _ClientState.waitingForAcceptOrReject;
|
||||
}
|
||||
@@ -258,8 +257,7 @@ class FrontendServerClient {
|
||||
required String klass,
|
||||
required String libraryUri,
|
||||
required List<String> typeDefinitions,
|
||||
}) =>
|
||||
throw UnimplementedError();
|
||||
}) => throw UnimplementedError();
|
||||
|
||||
/// TODO: Document
|
||||
Future<CompileResult> compileExpressionToJs({
|
||||
@@ -270,8 +268,7 @@ class FrontendServerClient {
|
||||
required String libraryUri,
|
||||
required int line,
|
||||
required String moduleName,
|
||||
}) =>
|
||||
throw UnimplementedError();
|
||||
}) => throw UnimplementedError();
|
||||
|
||||
/// Should be invoked when results of compilation are accepted by the client.
|
||||
///
|
||||
@@ -279,7 +276,8 @@ class FrontendServerClient {
|
||||
void accept() {
|
||||
if (_state != _ClientState.waitingForAcceptOrReject) {
|
||||
throw StateError(
|
||||
'Called `accept` but there was no previous compile to accept.');
|
||||
'Called `accept` but there was no previous compile to accept.',
|
||||
);
|
||||
}
|
||||
_sendCommand('accept');
|
||||
_state = _ClientState.waitingForRecompile;
|
||||
@@ -294,7 +292,8 @@ class FrontendServerClient {
|
||||
Future<void> reject() async {
|
||||
if (_state != _ClientState.waitingForAcceptOrReject) {
|
||||
throw StateError(
|
||||
'Called `reject` but there was no previous compile to reject.');
|
||||
'Called `reject` but there was no previous compile to reject.',
|
||||
);
|
||||
}
|
||||
_state = _ClientState.rejecting;
|
||||
_sendCommand('reject');
|
||||
@@ -307,8 +306,9 @@ class FrontendServerClient {
|
||||
case _RejectState.started:
|
||||
if (!line.startsWith('result')) {
|
||||
throw StateError(
|
||||
'Expected a line like `result <boundary-key>` after a `reject` '
|
||||
'command, but got:\n$line');
|
||||
'Expected a line like `result <boundary-key>` after a `reject` '
|
||||
'command, but got:\n$line',
|
||||
);
|
||||
}
|
||||
boundaryKey = line.split(' ').last;
|
||||
rejectState = _RejectState.waitingForKey;
|
||||
@@ -332,8 +332,9 @@ class FrontendServerClient {
|
||||
void reset() {
|
||||
if (_state == _ClientState.compiling) {
|
||||
throw StateError(
|
||||
'Called `reset` during an active compile, you must wait for that to '
|
||||
'complete first.');
|
||||
'Called `reset` during an active compile, you must wait for that to '
|
||||
'complete first.',
|
||||
);
|
||||
}
|
||||
_sendCommand('reset');
|
||||
_state = _ClientState.waitingForRecompile;
|
||||
@@ -377,12 +378,13 @@ class FrontendServerClient {
|
||||
|
||||
/// The result of a compile call.
|
||||
class CompileResult {
|
||||
const CompileResult._(
|
||||
{required this.dillOutput,
|
||||
required this.compilerOutputLines,
|
||||
required this.errorCount,
|
||||
required this.newSources,
|
||||
required this.removedSources});
|
||||
const CompileResult._({
|
||||
required this.dillOutput,
|
||||
required this.compilerOutputLines,
|
||||
required this.errorCount,
|
||||
required this.newSources,
|
||||
required this.removedSources,
|
||||
});
|
||||
|
||||
/// The produced dill output file, this will either be a full dill file, an
|
||||
/// incremental dill file, or `null` if no file was produced.
|
||||
@@ -432,24 +434,23 @@ enum _ClientState {
|
||||
}
|
||||
|
||||
/// Frontend server interaction states for a `compile` call.
|
||||
enum _CompileState {
|
||||
started,
|
||||
waitingForKey,
|
||||
gettingSourceDiffs,
|
||||
done,
|
||||
}
|
||||
enum _CompileState { started, waitingForKey, gettingSourceDiffs, done }
|
||||
|
||||
/// Frontend server interaction states for a `reject` call.
|
||||
enum _RejectState {
|
||||
started,
|
||||
waitingForKey,
|
||||
done,
|
||||
}
|
||||
enum _RejectState { started, waitingForKey, done }
|
||||
|
||||
final _dartAotRuntimePath = p.join(sdkDir, 'bin', 'dartaotruntime');
|
||||
|
||||
final _feServerAppJitSnapshotPath =
|
||||
p.join(sdkDir, 'bin', 'snapshots', 'frontend_server.dart.snapshot');
|
||||
final _feServerAppJitSnapshotPath = p.join(
|
||||
sdkDir,
|
||||
'bin',
|
||||
'snapshots',
|
||||
'frontend_server.dart.snapshot',
|
||||
);
|
||||
|
||||
final _feServerAotSnapshotPath =
|
||||
p.join(sdkDir, 'bin', 'snapshots', 'frontend_server_aot.dart.snapshot');
|
||||
final _feServerAotSnapshotPath = p.join(
|
||||
sdkDir,
|
||||
'bin',
|
||||
'snapshots',
|
||||
'frontend_server_aot.dart.snapshot',
|
||||
);
|
||||
|
||||
@@ -18,16 +18,26 @@ void main() {
|
||||
final exampleFilePath = await pathFromNearestPackageConfig(
|
||||
'example/vm_client.dart',
|
||||
);
|
||||
final process = await TestProcess.start(
|
||||
Platform.resolvedExecutable, ['run', exampleFilePath]);
|
||||
await expectLater(process.stdout,
|
||||
emitsThrough(contains('done compiling example/app/main.dart')));
|
||||
final process = await TestProcess.start(Platform.resolvedExecutable, [
|
||||
'run',
|
||||
exampleFilePath,
|
||||
]);
|
||||
await expectLater(
|
||||
process.stdout, emitsThrough(contains('APP -> hello/world')));
|
||||
await expectLater(process.stdout,
|
||||
emitsThrough(contains('done recompiling example/app/main.dart')));
|
||||
process.stdout,
|
||||
emitsThrough(contains('done compiling example/app/main.dart')),
|
||||
);
|
||||
await expectLater(
|
||||
process.stdout, emitsThrough(contains('APP -> goodbye/world')));
|
||||
process.stdout,
|
||||
emitsThrough(contains('APP -> hello/world')),
|
||||
);
|
||||
await expectLater(
|
||||
process.stdout,
|
||||
emitsThrough(contains('done recompiling example/app/main.dart')),
|
||||
);
|
||||
await expectLater(
|
||||
process.stdout,
|
||||
emitsThrough(contains('APP -> goodbye/world')),
|
||||
);
|
||||
expect(await process.exitCode, 0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -18,15 +18,19 @@ void main() {
|
||||
final exampleFilePath = await pathFromNearestPackageConfig(
|
||||
'example/web_client.dart',
|
||||
);
|
||||
final process = await TestProcess.start(
|
||||
Platform.resolvedExecutable, ['run', exampleFilePath]);
|
||||
await expectLater(process.stdout,
|
||||
emitsThrough(contains('done compiling example/app/main.dart')));
|
||||
final process = await TestProcess.start(Platform.resolvedExecutable, [
|
||||
'run',
|
||||
exampleFilePath,
|
||||
]);
|
||||
await expectLater(
|
||||
process.stdout,
|
||||
emitsThrough(contains('done compiling example/app/main.dart')),
|
||||
);
|
||||
process.stdin.writeln('new message');
|
||||
await expectLater(
|
||||
process.stdout,
|
||||
emitsThrough(
|
||||
contains('Recompile succeeded for example/app/main.dart')));
|
||||
process.stdout,
|
||||
emitsThrough(contains('Recompile succeeded for example/app/main.dart')),
|
||||
);
|
||||
process.stdin.writeln('quit');
|
||||
expect(await process.exitCode, 0);
|
||||
});
|
||||
|
||||
@@ -52,15 +52,13 @@ String get message => p.join('hello', 'world');
|
||||
]),
|
||||
]).create();
|
||||
packageRoot = p.join(d.sandbox, 'a');
|
||||
await Process.run(
|
||||
Platform.resolvedExecutable,
|
||||
[
|
||||
'pub',
|
||||
'get',
|
||||
],
|
||||
workingDirectory: packageRoot);
|
||||
await Process.run(Platform.resolvedExecutable, [
|
||||
'pub',
|
||||
'get',
|
||||
], workingDirectory: packageRoot);
|
||||
packageConfig = (await findPackageConfig(Directory(packageRoot)))!;
|
||||
packagesJsonPath = findNearestPackageConfigPath(Directory(packageRoot)) ??
|
||||
packagesJsonPath =
|
||||
findNearestPackageConfigPath(Directory(packageRoot)) ??
|
||||
p.join(packageRoot, '.dart_tool', 'package_config.json');
|
||||
});
|
||||
|
||||
@@ -207,8 +205,9 @@ String get message => p.join('hello', 'world');
|
||||
});
|
||||
|
||||
test('can compile and recompile a dartdevc app', () async {
|
||||
final entrypoint =
|
||||
p.toUri(p.join(packageRoot, 'bin', 'main.dart')).toString();
|
||||
final entrypoint = p
|
||||
.toUri(p.join(packageRoot, 'bin', 'main.dart'))
|
||||
.toString();
|
||||
final dartDevcClient = client = await DartDevcFrontendServerClient.start(
|
||||
entrypoint,
|
||||
p.join(packageRoot, 'out.dill'),
|
||||
|
||||
Reference in New Issue
Block a user