blob: e88a7dd8c60c8e7bbee20d74259e4f9e84190017 [file] [log] [blame]
// Copyright (c) 2022, 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.md file.
// @dart = 2.9
import 'dart:async';
import 'dart:io' show Directory, File, InternetAddress, stdin;
import 'package:args/args.dart';
import 'package:path/path.dart' as path;
import 'package:vm/incremental_compiler.dart' show IncrementalCompiler;
import 'frontend_server.dart';
import 'src/binary_protocol.dart';
import 'src/resident_frontend_server.dart';
/// Entry point for this module, that creates either a `_FrontendCompiler`
/// instance or a `ResidentFrontendServer` instance and
/// processes user input.
/// `compiler` is an optional parameter so it can be replaced with mocked
/// version for testing.
Future<int> starter(
List<String> args, {
CompilerInterface compiler,
Stream<List<int>> input,
StringSink output,
IncrementalCompiler generator,
BinaryPrinterFactory binaryPrinterFactory,
}) async {
ArgResults options;
try {
options = argParser.parse(args);
} catch (error) {
print('ERROR: $error\n');
print(usage);
return 1;
}
if (options['resident-info-file-name'] != null) {
var serverSubscription = await residentListenAndCompile(
InternetAddress.loopbackIPv4,
0,
File(options['resident-info-file-name']));
return serverSubscription == null ? 1 : 0;
}
if (options['train']) {
if (options.rest.isEmpty) {
throw Exception('Must specify input.dart');
}
final String input = options.rest[0];
final String sdkRoot = options['sdk-root'];
final String platform = options['platform'];
final Directory temp =
Directory.systemTemp.createTempSync('train_frontend_server');
try {
final String outputTrainingDill = path.join(temp.path, 'app.dill');
final List<String> args = <String>[
'--incremental',
'--sdk-root=$sdkRoot',
'--output-dill=$outputTrainingDill',
];
if (platform != null) {
args.add('--platform=${Uri.file(platform)}');
}
options = argParser.parse(args);
compiler ??=
FrontendCompiler(output, printerFactory: binaryPrinterFactory);
await compiler.compile(input, options, generator: generator);
compiler.acceptLastDelta();
await compiler.recompileDelta();
compiler.acceptLastDelta();
compiler.resetIncrementalCompiler();
await compiler.recompileDelta();
compiler.acceptLastDelta();
await compiler.recompileDelta();
compiler.acceptLastDelta();
return 0;
} finally {
temp.deleteSync(recursive: true);
}
}
final binaryProtocolAddressStr = options['binary-protocol-address'];
if (binaryProtocolAddressStr is String) {
runBinaryProtocol(binaryProtocolAddressStr);
return 0;
}
compiler ??= FrontendCompiler(output,
printerFactory: binaryPrinterFactory,
unsafePackageSerialization: options["unsafe-package-serialization"],
incrementalSerialization: options["incremental-serialization"],
useDebuggerModuleNames: options['debugger-module-names'],
emitDebugMetadata: options['experimental-emit-debug-metadata'],
emitDebugSymbols: options['emit-debug-symbols']);
if (options.rest.isNotEmpty) {
return await compiler.compile(options.rest[0], options,
generator: generator)
? 0
: 254;
}
Completer<int> completer = Completer<int>();
var subscription = listenAndCompile(
compiler, input ?? stdin, options, completer,
generator: generator);
return completer.future..then((value) => subscription.cancel());
}