Unverified Commit 4bcf8fb4 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate compile to null safety (#83153)

parent ade6e1f9
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
...@@ -26,8 +24,8 @@ import 'convert.dart'; ...@@ -26,8 +24,8 @@ import 'convert.dart';
class TargetModel { class TargetModel {
/// Parse a [TargetModel] from a raw string. /// Parse a [TargetModel] from a raw string.
/// ///
/// Throws an [AssertionError] if passed a value other than 'flutter' or /// Throws an exception if passed a value other than 'flutter',
/// 'flutter_runner'. /// 'flutter_runner', 'vm', or 'dartdevc'.
factory TargetModel(String rawValue) { factory TargetModel(String rawValue) {
switch (rawValue) { switch (rawValue) {
case 'flutter': case 'flutter':
...@@ -39,8 +37,7 @@ class TargetModel { ...@@ -39,8 +37,7 @@ class TargetModel {
case 'dartdevc': case 'dartdevc':
return dartdevc; return dartdevc;
} }
assert(false); throw Exception('Unexpected target model $rawValue');
return null;
} }
const TargetModel._(this._value); const TargetModel._(this._value);
...@@ -71,7 +68,7 @@ class CompilerOutput { ...@@ -71,7 +68,7 @@ class CompilerOutput {
final List<Uri> sources; final List<Uri> sources;
/// This field is only non-null for expression compilation requests. /// This field is only non-null for expression compilation requests.
final Uint8List expressionData; final Uint8List? expressionData;
} }
enum StdoutState { CollectDiagnostic, CollectDependencies } enum StdoutState { CollectDiagnostic, CollectDependencies }
...@@ -79,8 +76,8 @@ enum StdoutState { CollectDiagnostic, CollectDependencies } ...@@ -79,8 +76,8 @@ enum StdoutState { CollectDiagnostic, CollectDependencies }
/// Handles stdin/stdout communication with the frontend server. /// Handles stdin/stdout communication with the frontend server.
class StdoutHandler { class StdoutHandler {
StdoutHandler({ StdoutHandler({
@required Logger logger, required Logger logger,
@required FileSystem fileSystem, required FileSystem fileSystem,
}) : _logger = logger, }) : _logger = logger,
_fileSystem = fileSystem { _fileSystem = fileSystem {
reset(); reset();
...@@ -89,14 +86,14 @@ class StdoutHandler { ...@@ -89,14 +86,14 @@ class StdoutHandler {
final Logger _logger; final Logger _logger;
final FileSystem _fileSystem; final FileSystem _fileSystem;
String boundaryKey; String? boundaryKey;
StdoutState state = StdoutState.CollectDiagnostic; StdoutState state = StdoutState.CollectDiagnostic;
Completer<CompilerOutput> compilerOutput; Completer<CompilerOutput?>? compilerOutput;
final List<Uri> sources = <Uri>[]; final List<Uri> sources = <Uri>[];
bool _suppressCompilerMessages; bool _suppressCompilerMessages = false;
bool _expectSources; bool _expectSources = true;
bool _readFile; bool _readFile = false;
void handler(String message) { void handler(String message) {
const String kResultPrefix = 'result '; const String kResultPrefix = 'result ';
...@@ -104,21 +101,22 @@ class StdoutHandler { ...@@ -104,21 +101,22 @@ class StdoutHandler {
boundaryKey = message.substring(kResultPrefix.length); boundaryKey = message.substring(kResultPrefix.length);
return; return;
} }
if (message.startsWith(boundaryKey)) { final String? messageBoundaryKey = boundaryKey;
if (messageBoundaryKey != null && message.startsWith(messageBoundaryKey)) {
if (_expectSources) { if (_expectSources) {
if (state == StdoutState.CollectDiagnostic) { if (state == StdoutState.CollectDiagnostic) {
state = StdoutState.CollectDependencies; state = StdoutState.CollectDependencies;
return; return;
} }
} }
if (message.length <= boundaryKey.length) { if (message.length <= messageBoundaryKey.length) {
compilerOutput.complete(null); compilerOutput?.complete(null);
return; return;
} }
final int spaceDelimiter = message.lastIndexOf(' '); final int spaceDelimiter = message.lastIndexOf(' ');
final String fileName = message.substring(boundaryKey.length + 1, spaceDelimiter); final String fileName = message.substring(messageBoundaryKey.length + 1, spaceDelimiter);
final int errorCount = int.parse(message.substring(spaceDelimiter + 1).trim()); final int errorCount = int.parse(message.substring(spaceDelimiter + 1).trim());
Uint8List expressionData; Uint8List? expressionData;
if (_readFile) { if (_readFile) {
expressionData = _fileSystem.file(fileName).readAsBytesSync(); expressionData = _fileSystem.file(fileName).readAsBytesSync();
} }
...@@ -128,7 +126,7 @@ class StdoutHandler { ...@@ -128,7 +126,7 @@ class StdoutHandler {
sources, sources,
expressionData: expressionData, expressionData: expressionData,
); );
compilerOutput.complete(output); compilerOutput?.complete(output);
return; return;
} }
if (state == StdoutState.CollectDiagnostic) { if (state == StdoutState.CollectDiagnostic) {
...@@ -156,7 +154,7 @@ class StdoutHandler { ...@@ -156,7 +154,7 @@ class StdoutHandler {
// with its own boundary key and new completer. // with its own boundary key and new completer.
void reset({ bool suppressCompilerMessages = false, bool expectSources = true, bool readFile = false }) { void reset({ bool suppressCompilerMessages = false, bool expectSources = true, bool readFile = false }) {
boundaryKey = null; boundaryKey = null;
compilerOutput = Completer<CompilerOutput>(); compilerOutput = Completer<CompilerOutput?>();
_suppressCompilerMessages = suppressCompilerMessages; _suppressCompilerMessages = suppressCompilerMessages;
_expectSources = expectSources; _expectSources = expectSources;
_readFile = readFile; _readFile = readFile;
...@@ -193,13 +191,13 @@ List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) { ...@@ -193,13 +191,13 @@ List<String> buildModeOptions(BuildMode mode, List<String> dartDefines) {
/// A compiler interface for producing single (non-incremental) kernel files. /// A compiler interface for producing single (non-incremental) kernel files.
class KernelCompiler { class KernelCompiler {
KernelCompiler({ KernelCompiler({
@required FileSystem fileSystem, required FileSystem fileSystem,
@required Logger logger, required Logger logger,
@required ProcessManager processManager, required ProcessManager processManager,
@required Artifacts artifacts, required Artifacts artifacts,
@required List<String> fileSystemRoots, required List<String> fileSystemRoots,
@required String fileSystemScheme, required String fileSystemScheme,
@visibleForTesting StdoutHandler stdoutHandler, @visibleForTesting StdoutHandler? stdoutHandler,
}) : _logger = logger, }) : _logger = logger,
_fileSystem = fileSystem, _fileSystem = fileSystem,
_artifacts = artifacts, _artifacts = artifacts,
...@@ -216,26 +214,26 @@ class KernelCompiler { ...@@ -216,26 +214,26 @@ class KernelCompiler {
final List<String> _fileSystemRoots; final List<String> _fileSystemRoots;
final StdoutHandler _stdoutHandler; final StdoutHandler _stdoutHandler;
Future<CompilerOutput> compile({ Future<CompilerOutput?> compile({
String sdkRoot, required String sdkRoot,
String mainPath, String? mainPath,
String outputFilePath, String? outputFilePath,
String depFilePath, String? depFilePath,
TargetModel targetModel = TargetModel.flutter, TargetModel targetModel = TargetModel.flutter,
bool linkPlatformKernelIn = false, bool linkPlatformKernelIn = false,
bool aot = false, bool aot = false,
List<String> extraFrontEndOptions, List<String>? extraFrontEndOptions,
List<String> fileSystemRoots, List<String>? fileSystemRoots,
String fileSystemScheme, String? fileSystemScheme,
String initializeFromDill, String? initializeFromDill,
String platformDill, String? platformDill,
Directory buildDir, Directory? buildDir,
bool checkDartPluginRegistry = false, bool checkDartPluginRegistry = false,
@required String packagesPath, required String? packagesPath,
@required BuildMode buildMode, required BuildMode buildMode,
@required bool trackWidgetCreation, required bool trackWidgetCreation,
@required List<String> dartDefines, required List<String> dartDefines,
@required PackageConfig packageConfig, required PackageConfig packageConfig,
}) async { }) async {
final String frontendServer = _artifacts.getArtifactPath( final String frontendServer = _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk Artifact.frontendServerSnapshotForEngineDartSdk
...@@ -248,7 +246,7 @@ class KernelCompiler { ...@@ -248,7 +246,7 @@ class KernelCompiler {
if (!_processManager.canRun(engineDartPath)) { if (!_processManager.canRun(engineDartPath)) {
throwToolExit('Unable to find Dart binary at $engineDartPath'); throwToolExit('Unable to find Dart binary at $engineDartPath');
} }
String mainUri; String? mainUri;
final File mainFile = _fileSystem.file(mainPath); final File mainFile = _fileSystem.file(mainPath);
final Uri mainFileUri = mainFile.uri; final Uri mainFileUri = mainFile.uri;
if (packagesPath != null) { if (packagesPath != null) {
...@@ -314,7 +312,7 @@ class KernelCompiler { ...@@ -314,7 +312,7 @@ class KernelCompiler {
platformDill, platformDill,
], ],
...?extraFrontEndOptions, ...?extraFrontEndOptions,
mainUri ?? mainPath, mainUri,
]; ];
_logger.printTrace(command.join(' ')); _logger.printTrace(command.join(' '));
...@@ -329,7 +327,7 @@ class KernelCompiler { ...@@ -329,7 +327,7 @@ class KernelCompiler {
.listen(_stdoutHandler.handler); .listen(_stdoutHandler.handler);
final int exitCode = await server.exitCode; final int exitCode = await server.exitCode;
if (exitCode == 0) { if (exitCode == 0) {
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
return null; return null;
} }
...@@ -339,9 +337,9 @@ class KernelCompiler { ...@@ -339,9 +337,9 @@ class KernelCompiler {
abstract class _CompilationRequest { abstract class _CompilationRequest {
_CompilationRequest(this.completer); _CompilationRequest(this.completer);
Completer<CompilerOutput> completer; Completer<CompilerOutput?> completer;
Future<CompilerOutput> _run(DefaultResidentCompiler compiler); Future<CompilerOutput?> _run(DefaultResidentCompiler compiler);
Future<void> run(DefaultResidentCompiler compiler) async { Future<void> run(DefaultResidentCompiler compiler) async {
completer.complete(await _run(compiler)); completer.complete(await _run(compiler));
...@@ -350,7 +348,7 @@ abstract class _CompilationRequest { ...@@ -350,7 +348,7 @@ abstract class _CompilationRequest {
class _RecompileRequest extends _CompilationRequest { class _RecompileRequest extends _CompilationRequest {
_RecompileRequest( _RecompileRequest(
Completer<CompilerOutput> completer, Completer<CompilerOutput?> completer,
this.mainUri, this.mainUri,
this.invalidatedFiles, this.invalidatedFiles,
this.outputPath, this.outputPath,
...@@ -359,19 +357,19 @@ class _RecompileRequest extends _CompilationRequest { ...@@ -359,19 +357,19 @@ class _RecompileRequest extends _CompilationRequest {
) : super(completer); ) : super(completer);
Uri mainUri; Uri mainUri;
List<Uri> invalidatedFiles; List<Uri>? invalidatedFiles;
String outputPath; String outputPath;
PackageConfig packageConfig; PackageConfig packageConfig;
bool suppressErrors; bool suppressErrors;
@override @override
Future<CompilerOutput> _run(DefaultResidentCompiler compiler) async => Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
compiler._recompile(this); compiler._recompile(this);
} }
class _CompileExpressionRequest extends _CompilationRequest { class _CompileExpressionRequest extends _CompilationRequest {
_CompileExpressionRequest( _CompileExpressionRequest(
Completer<CompilerOutput> completer, Completer<CompilerOutput?> completer,
this.expression, this.expression,
this.definitions, this.definitions,
this.typeDefinitions, this.typeDefinitions,
...@@ -381,20 +379,20 @@ class _CompileExpressionRequest extends _CompilationRequest { ...@@ -381,20 +379,20 @@ class _CompileExpressionRequest extends _CompilationRequest {
) : super(completer); ) : super(completer);
String expression; String expression;
List<String> definitions; List<String>? definitions;
List<String> typeDefinitions; List<String>? typeDefinitions;
String libraryUri; String? libraryUri;
String klass; String? klass;
bool isStatic; bool isStatic;
@override @override
Future<CompilerOutput> _run(DefaultResidentCompiler compiler) async => Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
compiler._compileExpression(this); compiler._compileExpression(this);
} }
class _CompileExpressionToJsRequest extends _CompilationRequest { class _CompileExpressionToJsRequest extends _CompilationRequest {
_CompileExpressionToJsRequest( _CompileExpressionToJsRequest(
Completer<CompilerOutput> completer, Completer<CompilerOutput?> completer,
this.libraryUri, this.libraryUri,
this.line, this.line,
this.column, this.column,
...@@ -404,24 +402,24 @@ class _CompileExpressionToJsRequest extends _CompilationRequest { ...@@ -404,24 +402,24 @@ class _CompileExpressionToJsRequest extends _CompilationRequest {
this.expression, this.expression,
) : super(completer); ) : super(completer);
final String libraryUri; final String? libraryUri;
final int line; final int line;
final int column; final int column;
final Map<String, String> jsModules; final Map<String, String>? jsModules;
final Map<String, String> jsFrameValues; final Map<String, String>? jsFrameValues;
final String moduleName; final String? moduleName;
final String expression; final String? expression;
@override @override
Future<CompilerOutput> _run(DefaultResidentCompiler compiler) async => Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
compiler._compileExpressionToJs(this); compiler._compileExpressionToJs(this);
} }
class _RejectRequest extends _CompilationRequest { class _RejectRequest extends _CompilationRequest {
_RejectRequest(Completer<CompilerOutput> completer) : super(completer); _RejectRequest(Completer<CompilerOutput?> completer) : super(completer);
@override @override
Future<CompilerOutput> _run(DefaultResidentCompiler compiler) async => Future<CompilerOutput?> _run(DefaultResidentCompiler compiler) async =>
compiler._reject(); compiler._reject();
} }
...@@ -432,23 +430,23 @@ class _RejectRequest extends _CompilationRequest { ...@@ -432,23 +430,23 @@ class _RejectRequest extends _CompilationRequest {
/// restarts the Flutter app. /// restarts the Flutter app.
abstract class ResidentCompiler { abstract class ResidentCompiler {
factory ResidentCompiler(String sdkRoot, { factory ResidentCompiler(String sdkRoot, {
@required BuildMode buildMode, required BuildMode buildMode,
@required Logger logger, required Logger logger,
@required ProcessManager processManager, required ProcessManager processManager,
@required Artifacts artifacts, required Artifacts artifacts,
@required Platform platform, required Platform platform,
@required FileSystem fileSystem, required FileSystem fileSystem,
bool testCompilation, bool testCompilation,
bool trackWidgetCreation, bool trackWidgetCreation,
String packagesPath, String packagesPath,
List<String> fileSystemRoots, List<String> fileSystemRoots,
String fileSystemScheme, String? fileSystemScheme,
String initializeFromDill, String initializeFromDill,
TargetModel targetModel, TargetModel targetModel,
bool unsafePackageSerialization, bool unsafePackageSerialization,
List<String> extraFrontEndOptions, List<String> extraFrontEndOptions,
String platformDill, String platformDill,
List<String> dartDefines, List<String>? dartDefines,
String librariesSpec, String librariesSpec,
}) = DefaultResidentCompiler; }) = DefaultResidentCompiler;
...@@ -464,22 +462,22 @@ abstract class ResidentCompiler { ...@@ -464,22 +462,22 @@ abstract class ResidentCompiler {
/// point that is used for recompilation. /// point that is used for recompilation.
/// Binary file name is returned if compilation was successful, otherwise /// Binary file name is returned if compilation was successful, otherwise
/// null is returned. /// null is returned.
Future<CompilerOutput> recompile( Future<CompilerOutput?> recompile(
Uri mainUri, Uri mainUri,
List<Uri> invalidatedFiles, { List<Uri>? invalidatedFiles, {
@required String outputPath, required String outputPath,
@required PackageConfig packageConfig, required PackageConfig packageConfig,
@required String projectRootPath, required String projectRootPath,
@required FileSystem fs, required FileSystem fs,
bool suppressErrors = false, bool suppressErrors = false,
}); });
Future<CompilerOutput> compileExpression( Future<CompilerOutput?> compileExpression(
String expression, String expression,
List<String> definitions, List<String>? definitions,
List<String> typeDefinitions, List<String>? typeDefinitions,
String libraryUri, String? libraryUri,
String klass, String? klass,
bool isStatic, bool isStatic,
); );
...@@ -503,7 +501,7 @@ abstract class ResidentCompiler { ...@@ -503,7 +501,7 @@ abstract class ResidentCompiler {
/// { 'dart':'dart_sdk', 'main': '/packages/hello_world_main.dart' } /// { 'dart':'dart_sdk', 'main': '/packages/hello_world_main.dart' }
/// Returns a [CompilerOutput] including the name of the file containing the /// Returns a [CompilerOutput] including the name of the file containing the
/// compilation result and a number of errors. /// compilation result and a number of errors.
Future<CompilerOutput> compileExpressionToJs( Future<CompilerOutput?> compileExpressionToJs(
String libraryUri, String libraryUri,
int line, int line,
int column, int column,
...@@ -521,39 +519,39 @@ abstract class ResidentCompiler { ...@@ -521,39 +519,39 @@ abstract class ResidentCompiler {
/// Should be invoked when results of compilation are rejected by the client. /// Should be invoked when results of compilation are rejected by the client.
/// ///
/// Either [accept] or [reject] should be called after every [recompile] call. /// Either [accept] or [reject] should be called after every [recompile] call.
Future<CompilerOutput> reject(); Future<CompilerOutput?> reject();
/// Should be invoked when frontend server compiler should forget what was /// Should be invoked when frontend server compiler should forget what was
/// accepted previously so that next call to [recompile] produces complete /// accepted previously so that next call to [recompile] produces complete
/// kernel file. /// kernel file.
void reset(); void reset();
Future<dynamic> shutdown(); Future<Object> shutdown();
} }
@visibleForTesting @visibleForTesting
class DefaultResidentCompiler implements ResidentCompiler { class DefaultResidentCompiler implements ResidentCompiler {
DefaultResidentCompiler( DefaultResidentCompiler(
String sdkRoot, { String sdkRoot, {
@required this.buildMode, required this.buildMode,
@required Logger logger, required Logger logger,
@required ProcessManager processManager, required ProcessManager processManager,
@required Artifacts artifacts, required Artifacts artifacts,
@required Platform platform, required Platform platform,
@required FileSystem fileSystem, required FileSystem fileSystem,
this.testCompilation = false, this.testCompilation = false,
this.trackWidgetCreation = true, this.trackWidgetCreation = true,
this.packagesPath, this.packagesPath,
this.fileSystemRoots, this.fileSystemRoots = const <String>[],
this.fileSystemScheme, this.fileSystemScheme,
this.initializeFromDill, this.initializeFromDill,
this.targetModel = TargetModel.flutter, this.targetModel = TargetModel.flutter,
this.unsafePackageSerialization, this.unsafePackageSerialization = false,
this.extraFrontEndOptions, this.extraFrontEndOptions,
this.platformDill, this.platformDill,
List<String> dartDefines, List<String>? dartDefines,
this.librariesSpec, this.librariesSpec,
@visibleForTesting StdoutHandler stdoutHandler, @visibleForTesting StdoutHandler? stdoutHandler,
}) : assert(sdkRoot != null), }) : assert(sdkRoot != null),
_logger = logger, _logger = logger,
_processManager = processManager, _processManager = processManager,
...@@ -572,15 +570,15 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -572,15 +570,15 @@ class DefaultResidentCompiler implements ResidentCompiler {
final bool testCompilation; final bool testCompilation;
final BuildMode buildMode; final BuildMode buildMode;
final bool trackWidgetCreation; final bool trackWidgetCreation;
final String packagesPath; final String? packagesPath;
final TargetModel targetModel; final TargetModel targetModel;
final List<String> fileSystemRoots; final List<String> fileSystemRoots;
final String fileSystemScheme; final String? fileSystemScheme;
final String initializeFromDill; final String? initializeFromDill;
final bool unsafePackageSerialization; final bool unsafePackageSerialization;
final List<String> extraFrontEndOptions; final List<String>? extraFrontEndOptions;
final List<String> dartDefines; final List<String> dartDefines;
final String librariesSpec; final String? librariesSpec;
@override @override
void addFileSystemRoot(String root) { void addFileSystemRoot(String root) {
...@@ -595,23 +593,23 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -595,23 +593,23 @@ class DefaultResidentCompiler implements ResidentCompiler {
/// The path to the platform dill file. /// The path to the platform dill file.
/// ///
/// This does not need to be provided for the normal Flutter workflow. /// This does not need to be provided for the normal Flutter workflow.
final String platformDill; final String? platformDill;
Process _server; Process? _server;
final StdoutHandler _stdoutHandler; final StdoutHandler _stdoutHandler;
bool _compileRequestNeedsConfirmation = false; bool _compileRequestNeedsConfirmation = false;
final StreamController<_CompilationRequest> _controller = StreamController<_CompilationRequest>(); final StreamController<_CompilationRequest> _controller = StreamController<_CompilationRequest>();
@override @override
Future<CompilerOutput> recompile( Future<CompilerOutput?> recompile(
Uri mainUri, Uri mainUri,
List<Uri> invalidatedFiles, { List<Uri>? invalidatedFiles, {
@required String outputPath, required String outputPath,
@required PackageConfig packageConfig, required PackageConfig packageConfig,
bool suppressErrors = false, bool suppressErrors = false,
String projectRootPath, String? projectRootPath,
FileSystem fs, FileSystem? fs,
}) async { }) async {
assert(outputPath != null); assert(outputPath != null);
if (!_controller.hasListener) { if (!_controller.hasListener) {
...@@ -631,14 +629,14 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -631,14 +629,14 @@ class DefaultResidentCompiler implements ResidentCompiler {
mainUri = generatedMainDart.uri; mainUri = generatedMainDart.uri;
} }
} }
final Completer<CompilerOutput> completer = Completer<CompilerOutput>(); final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
_controller.add( _controller.add(
_RecompileRequest(completer, mainUri, invalidatedFiles, outputPath, packageConfig, suppressErrors) _RecompileRequest(completer, mainUri, invalidatedFiles, outputPath, packageConfig, suppressErrors)
); );
return completer.future; return completer.future;
} }
Future<CompilerOutput> _recompile(_RecompileRequest request) async { Future<CompilerOutput?> _recompile(_RecompileRequest request) async {
_stdoutHandler.reset(); _stdoutHandler.reset();
_compileRequestNeedsConfirmation = true; _compileRequestNeedsConfirmation = true;
_stdoutHandler._suppressCompilerMessages = request.suppressErrors; _stdoutHandler._suppressCompilerMessages = request.suppressErrors;
...@@ -646,14 +644,17 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -646,14 +644,17 @@ class DefaultResidentCompiler implements ResidentCompiler {
final String mainUri = request.packageConfig.toPackageUri(request.mainUri)?.toString() ?? final String mainUri = request.packageConfig.toPackageUri(request.mainUri)?.toString() ??
toMultiRootPath(request.mainUri, fileSystemScheme, fileSystemRoots, _platform.isWindows); toMultiRootPath(request.mainUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);
if (_server == null) { final Process? server = _server;
if (server == null) {
return _compile(mainUri, request.outputPath); return _compile(mainUri, request.outputPath);
} }
final String inputKey = Uuid().generateV4(); final String inputKey = Uuid().generateV4();
_server.stdin.writeln('recompile $mainUri $inputKey'); server.stdin.writeln('recompile $mainUri $inputKey');
_logger.printTrace('<- recompile $mainUri $inputKey'); _logger.printTrace('<- recompile $mainUri $inputKey');
for (final Uri fileUri in request.invalidatedFiles) { final List<Uri>? invalidatedFiles = request.invalidatedFiles;
if (invalidatedFiles != null) {
for (final Uri fileUri in invalidatedFiles) {
String message; String message;
if (fileUri.scheme == 'package') { if (fileUri.scheme == 'package') {
message = fileUri.toString(); message = fileUri.toString();
...@@ -661,13 +662,14 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -661,13 +662,14 @@ class DefaultResidentCompiler implements ResidentCompiler {
message = request.packageConfig.toPackageUri(fileUri)?.toString() ?? message = request.packageConfig.toPackageUri(fileUri)?.toString() ??
toMultiRootPath(fileUri, fileSystemScheme, fileSystemRoots, _platform.isWindows); toMultiRootPath(fileUri, fileSystemScheme, fileSystemRoots, _platform.isWindows);
} }
_server.stdin.writeln(message); server.stdin.writeln(message);
_logger.printTrace(message); _logger.printTrace(message);
} }
_server.stdin.writeln(inputKey); }
server.stdin.writeln(inputKey);
_logger.printTrace('<- $inputKey'); _logger.printTrace('<- $inputKey');
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
final List<_CompilationRequest> _compilationQueue = <_CompilationRequest>[]; final List<_CompilationRequest> _compilationQueue = <_CompilationRequest>[];
...@@ -687,9 +689,9 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -687,9 +689,9 @@ class DefaultResidentCompiler implements ResidentCompiler {
} }
} }
Future<CompilerOutput> _compile( Future<CompilerOutput?> _compile(
String scriptUri, String scriptUri,
String outputPath, String? outputPath,
) async { ) async {
final String frontendServer = _artifacts.getArtifactPath( final String frontendServer = _artifacts.getArtifactPath(
Artifact.frontendServerSnapshotForEngineDartSdk Artifact.frontendServerSnapshotForEngineDartSdk
...@@ -720,11 +722,11 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -720,11 +722,11 @@ class DefaultResidentCompiler implements ResidentCompiler {
], ],
if (librariesSpec != null) ...<String>[ if (librariesSpec != null) ...<String>[
'--libraries-spec', '--libraries-spec',
librariesSpec, librariesSpec!,
], ],
if (packagesPath != null) ...<String>[ if (packagesPath != null) ...<String>[
'--packages', '--packages',
packagesPath, packagesPath!,
], ],
...buildModeOptions(buildMode, dartDefines), ...buildModeOptions(buildMode, dartDefines),
if (trackWidgetCreation) '--track-widget-creation', if (trackWidgetCreation) '--track-widget-creation',
...@@ -735,22 +737,22 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -735,22 +737,22 @@ class DefaultResidentCompiler implements ResidentCompiler {
], ],
if (fileSystemScheme != null) ...<String>[ if (fileSystemScheme != null) ...<String>[
'--filesystem-scheme', '--filesystem-scheme',
fileSystemScheme, fileSystemScheme!,
], ],
if (initializeFromDill != null) ...<String>[ if (initializeFromDill != null) ...<String>[
'--initialize-from-dill', '--initialize-from-dill',
initializeFromDill, initializeFromDill!,
], ],
if (platformDill != null) ...<String>[ if (platformDill != null) ...<String>[
'--platform', '--platform',
platformDill, platformDill!,
], ],
if (unsafePackageSerialization == true) '--unsafe-package-serialization', if (unsafePackageSerialization == true) '--unsafe-package-serialization',
...?extraFrontEndOptions, ...?extraFrontEndOptions,
]; ];
_logger.printTrace(command.join(' ')); _logger.printTrace(command.join(' '));
_server = await _processManager.start(command); _server = await _processManager.start(command);
_server.stdout _server?.stdout
.transform<String>(utf8.decoder) .transform<String>(utf8.decoder)
.transform<String>(const LineSplitter()) .transform<String>(const LineSplitter())
.listen( .listen(
...@@ -758,76 +760,77 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -758,76 +760,77 @@ class DefaultResidentCompiler implements ResidentCompiler {
onDone: () { onDone: () {
// when outputFilename future is not completed, but stdout is closed // when outputFilename future is not completed, but stdout is closed
// process has died unexpectedly. // process has died unexpectedly.
if (!_stdoutHandler.compilerOutput.isCompleted) { if (_stdoutHandler.compilerOutput?.isCompleted == false) {
_stdoutHandler.compilerOutput.complete(null); _stdoutHandler.compilerOutput?.complete(null);
throwToolExit('the Dart compiler exited unexpectedly.'); throwToolExit('the Dart compiler exited unexpectedly.');
} }
}); });
_server.stderr _server?.stderr
.transform<String>(utf8.decoder) .transform<String>(utf8.decoder)
.transform<String>(const LineSplitter()) .transform<String>(const LineSplitter())
.listen(_logger.printError); .listen(_logger.printError);
unawaited(_server.exitCode.then((int code) { unawaited(_server?.exitCode.then((int code) {
if (code != 0) { if (code != 0) {
throwToolExit('the Dart compiler exited unexpectedly.'); throwToolExit('the Dart compiler exited unexpectedly.');
} }
})); }));
_server.stdin.writeln('compile $scriptUri'); _server?.stdin.writeln('compile $scriptUri');
_logger.printTrace('<- compile $scriptUri'); _logger.printTrace('<- compile $scriptUri');
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
@override @override
Future<CompilerOutput> compileExpression( Future<CompilerOutput?> compileExpression(
String expression, String expression,
List<String> definitions, List<String>? definitions,
List<String> typeDefinitions, List<String>? typeDefinitions,
String libraryUri, String? libraryUri,
String klass, String? klass,
bool isStatic, bool isStatic,
) async { ) async {
if (!_controller.hasListener) { if (!_controller.hasListener) {
_controller.stream.listen(_handleCompilationRequest); _controller.stream.listen(_handleCompilationRequest);
} }
final Completer<CompilerOutput> completer = Completer<CompilerOutput>(); final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
final _CompileExpressionRequest request = _CompileExpressionRequest( final _CompileExpressionRequest request = _CompileExpressionRequest(
completer, expression, definitions, typeDefinitions, libraryUri, klass, isStatic); completer, expression, definitions, typeDefinitions, libraryUri, klass, isStatic);
_controller.add(request); _controller.add(request);
return completer.future; return completer.future;
} }
Future<CompilerOutput> _compileExpression(_CompileExpressionRequest request) async { Future<CompilerOutput?> _compileExpression(_CompileExpressionRequest request) async {
_stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false, readFile: true); _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false, readFile: true);
// 'compile-expression' should be invoked after compiler has been started, // 'compile-expression' should be invoked after compiler has been started,
// program was compiled. // program was compiled.
if (_server == null) { final Process? server = _server;
if (server == null) {
return null; return null;
} }
final String inputKey = Uuid().generateV4(); final String inputKey = Uuid().generateV4();
_server.stdin server.stdin
..writeln('compile-expression $inputKey') ..writeln('compile-expression $inputKey')
..writeln(request.expression); ..writeln(request.expression);
request.definitions?.forEach(_server.stdin.writeln); request.definitions?.forEach(server.stdin.writeln);
_server.stdin.writeln(inputKey); server.stdin.writeln(inputKey);
request.typeDefinitions?.forEach(_server.stdin.writeln); request.typeDefinitions?.forEach(server.stdin.writeln);
_server.stdin server.stdin
..writeln(inputKey) ..writeln(inputKey)
..writeln(request.libraryUri ?? '') ..writeln(request.libraryUri ?? '')
..writeln(request.klass ?? '') ..writeln(request.klass ?? '')
..writeln(request.isStatic ?? false); ..writeln(request.isStatic);
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
@override @override
Future<CompilerOutput> compileExpressionToJs( Future<CompilerOutput?> compileExpressionToJs(
String libraryUri, String libraryUri,
int line, int line,
int column, int column,
...@@ -840,7 +843,7 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -840,7 +843,7 @@ class DefaultResidentCompiler implements ResidentCompiler {
_controller.stream.listen(_handleCompilationRequest); _controller.stream.listen(_handleCompilationRequest);
} }
final Completer<CompilerOutput> completer = Completer<CompilerOutput>(); final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
_controller.add( _controller.add(
_CompileExpressionToJsRequest( _CompileExpressionToJsRequest(
completer, libraryUri, line, column, jsModules, jsFrameValues, moduleName, expression) completer, libraryUri, line, column, jsModules, jsFrameValues, moduleName, expression)
...@@ -848,85 +851,87 @@ class DefaultResidentCompiler implements ResidentCompiler { ...@@ -848,85 +851,87 @@ class DefaultResidentCompiler implements ResidentCompiler {
return completer.future; return completer.future;
} }
Future<CompilerOutput> _compileExpressionToJs(_CompileExpressionToJsRequest request) async { Future<CompilerOutput?> _compileExpressionToJs(_CompileExpressionToJsRequest request) async {
_stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false); _stdoutHandler.reset(suppressCompilerMessages: true, expectSources: false);
// 'compile-expression-to-js' should be invoked after compiler has been started, // 'compile-expression-to-js' should be invoked after compiler has been started,
// program was compiled. // program was compiled.
if (_server == null) { final Process? server = _server;
if (server == null) {
return null; return null;
} }
final String inputKey = Uuid().generateV4(); final String inputKey = Uuid().generateV4();
_server.stdin server.stdin
..writeln('compile-expression-to-js $inputKey') ..writeln('compile-expression-to-js $inputKey')
..writeln(request.libraryUri ?? '') ..writeln(request.libraryUri ?? '')
..writeln(request.line) ..writeln(request.line)
..writeln(request.column); ..writeln(request.column);
request.jsModules?.forEach((String k, String v) { _server.stdin.writeln('$k:$v'); }); request.jsModules?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
_server.stdin.writeln(inputKey); server.stdin.writeln(inputKey);
request.jsFrameValues?.forEach((String k, String v) { _server.stdin.writeln('$k:$v'); }); request.jsFrameValues?.forEach((String k, String v) { server.stdin.writeln('$k:$v'); });
_server.stdin server.stdin
..writeln(inputKey) ..writeln(inputKey)
..writeln(request.moduleName ?? '') ..writeln(request.moduleName ?? '')
..writeln(request.expression ?? ''); ..writeln(request.expression ?? '');
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
@override @override
void accept() { void accept() {
if (_compileRequestNeedsConfirmation) { if (_compileRequestNeedsConfirmation) {
_server.stdin.writeln('accept'); _server?.stdin.writeln('accept');
_logger.printTrace('<- accept'); _logger.printTrace('<- accept');
} }
_compileRequestNeedsConfirmation = false; _compileRequestNeedsConfirmation = false;
} }
@override @override
Future<CompilerOutput> reject() { Future<CompilerOutput?> reject() {
if (!_controller.hasListener) { if (!_controller.hasListener) {
_controller.stream.listen(_handleCompilationRequest); _controller.stream.listen(_handleCompilationRequest);
} }
final Completer<CompilerOutput> completer = Completer<CompilerOutput>(); final Completer<CompilerOutput?> completer = Completer<CompilerOutput?>();
_controller.add(_RejectRequest(completer)); _controller.add(_RejectRequest(completer));
return completer.future; return completer.future;
} }
Future<CompilerOutput> _reject() { Future<CompilerOutput?> _reject() async {
if (!_compileRequestNeedsConfirmation) { if (!_compileRequestNeedsConfirmation) {
return Future<CompilerOutput>.value(null); return Future<CompilerOutput?>.value(null);
} }
_stdoutHandler.reset(expectSources: false); _stdoutHandler.reset(expectSources: false);
_server.stdin.writeln('reject'); _server?.stdin.writeln('reject');
_logger.printTrace('<- reject'); _logger.printTrace('<- reject');
_compileRequestNeedsConfirmation = false; _compileRequestNeedsConfirmation = false;
return _stdoutHandler.compilerOutput.future; return _stdoutHandler.compilerOutput?.future;
} }
@override @override
void reset() { void reset() {
_server?.stdin?.writeln('reset'); _server?.stdin.writeln('reset');
_logger.printTrace('<- reset'); _logger.printTrace('<- reset');
} }
@override @override
Future<dynamic> shutdown() async { Future<Object> shutdown() async {
// Server was never successfully created. // Server was never successfully created.
if (_server == null) { final Process? server = _server;
if (server == null) {
return 0; return 0;
} }
_logger.printTrace('killing pid ${_server.pid}'); _logger.printTrace('killing pid ${server.pid}');
_server.kill(); server.kill();
return _server.exitCode; return server.exitCode;
} }
} }
/// Convert a file URI into a multi-root scheme URI if provided, otherwise /// Convert a file URI into a multi-root scheme URI if provided, otherwise
/// return unmodified. /// return unmodified.
@visibleForTesting @visibleForTesting
String toMultiRootPath(Uri fileUri, String scheme, List<String> fileSystemRoots, bool windows) { String toMultiRootPath(Uri fileUri, String? scheme, List<String> fileSystemRoots, bool windows) {
if (scheme == null || fileSystemRoots.isEmpty || fileUri.scheme != 'file') { if (scheme == null || fileSystemRoots.isEmpty || fileUri.scheme != 'file') {
return fileUri.toString(); return fileUri.toString();
} }
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
...@@ -24,10 +22,10 @@ void main() { ...@@ -24,10 +22,10 @@ void main() {
stdoutHandler.reset(); stdoutHandler.reset();
'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'.split('\n').forEach(stdoutHandler.handler); 'result abc\nline1\nline2\nabc\nabc /path/to/main.dart.dill 0'.split('\n').forEach(stdoutHandler.handler);
final CompilerOutput output = await stdoutHandler.compilerOutput.future; final CompilerOutput? output = await stdoutHandler.compilerOutput?.future;
expect(logger.errorText, equals('line1\nline2\n')); expect(logger.errorText, equals('line1\nline2\n'));
expect(output.outputFilename, equals('/path/to/main.dart.dill')); expect(output?.outputFilename, equals('/path/to/main.dart.dill'));
}); });
testWithoutContext('StdoutHandler can parse output for failed batch compilation', () async { testWithoutContext('StdoutHandler can parse output for failed batch compilation', () async {
...@@ -36,7 +34,7 @@ void main() { ...@@ -36,7 +34,7 @@ void main() {
stdoutHandler.reset(); stdoutHandler.reset();
'result abc\nline1\nline2\nabc\nabc'.split('\n').forEach(stdoutHandler.handler); 'result abc\nline1\nline2\nabc\nabc'.split('\n').forEach(stdoutHandler.handler);
final CompilerOutput output = await stdoutHandler.compilerOutput.future; final CompilerOutput? output = await stdoutHandler.compilerOutput?.future;
expect(logger.errorText, equals('line1\nline2\n')); expect(logger.errorText, equals('line1\nline2\n'));
expect(output, equals(null)); expect(output, equals(null));
...@@ -73,7 +71,7 @@ void main() { ...@@ -73,7 +71,7 @@ void main() {
]), ]),
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -81,10 +79,10 @@ void main() { ...@@ -81,10 +79,10 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect((await output).outputFilename, ''); expect((await output)?.outputFilename, '');
}); });
testWithoutContext('KernelCompiler returns null if StdoutHandler returns null', () async { testWithoutContext('KernelCompiler returns null if StdoutHandler returns null', () async {
...@@ -118,7 +116,7 @@ void main() { ...@@ -118,7 +116,7 @@ void main() {
]), ]),
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -126,7 +124,7 @@ void main() { ...@@ -126,7 +124,7 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(null); stdoutHandler.compilerOutput?.complete(null);
completer.complete(); completer.complete();
expect(await output, null); expect(await output, null);
...@@ -163,7 +161,7 @@ void main() { ...@@ -163,7 +161,7 @@ void main() {
]), ]),
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -171,7 +169,7 @@ void main() { ...@@ -171,7 +169,7 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect(await output, null); expect(await output, null);
...@@ -209,7 +207,7 @@ void main() { ...@@ -209,7 +207,7 @@ void main() {
]), ]),
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.profile, buildMode: BuildMode.profile,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -218,10 +216,10 @@ void main() { ...@@ -218,10 +216,10 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect((await output).outputFilename, ''); expect((await output)?.outputFilename, '');
}); });
testWithoutContext('passes correct AOT config to kernel compiler in aot/release mode', () async { testWithoutContext('passes correct AOT config to kernel compiler in aot/release mode', () async {
...@@ -256,7 +254,7 @@ void main() { ...@@ -256,7 +254,7 @@ void main() {
]), ]),
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.release, buildMode: BuildMode.release,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -265,10 +263,10 @@ void main() { ...@@ -265,10 +263,10 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect((await output).outputFilename, ''); expect((await output)?.outputFilename, '');
}); });
testWithoutContext('KernelCompiler passes dartDefines to the frontend_server', () async { testWithoutContext('KernelCompiler passes dartDefines to the frontend_server', () async {
...@@ -305,7 +303,7 @@ void main() { ...@@ -305,7 +303,7 @@ void main() {
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/path/to/main.dart', mainPath: '/path/to/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -314,10 +312,10 @@ void main() { ...@@ -314,10 +312,10 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect((await output).outputFilename, ''); expect((await output)?.outputFilename, '');
}); });
testWithoutContext('KernelCompiler maps a file to a multi-root scheme if provided', () async { testWithoutContext('KernelCompiler maps a file to a multi-root scheme if provided', () async {
...@@ -354,7 +352,7 @@ void main() { ...@@ -354,7 +352,7 @@ void main() {
stdoutHandler: stdoutHandler, stdoutHandler: stdoutHandler,
); );
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/foo/bar/fizz/main.dart', mainPath: '/foo/bar/fizz/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -363,10 +361,10 @@ void main() { ...@@ -363,10 +361,10 @@ void main() {
packagesPath: '.packages', packagesPath: '.packages',
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
expect((await output).outputFilename, ''); expect((await output)?.outputFilename, '');
}); });
testWithoutContext('KernelCompiler uses generated entrypoint', () async { testWithoutContext('KernelCompiler uses generated entrypoint', () async {
...@@ -409,7 +407,7 @@ void main() { ...@@ -409,7 +407,7 @@ void main() {
buildDir.parent.childFile('generated_main.dart').createSync(recursive: true); buildDir.parent.childFile('generated_main.dart').createSync(recursive: true);
final Future<CompilerOutput> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot', final Future<CompilerOutput?> output = kernelCompiler.compile(sdkRoot: '/path/to/sdkroot',
mainPath: '/foo/bar/fizz/main.dart', mainPath: '/foo/bar/fizz/main.dart',
buildMode: BuildMode.debug, buildMode: BuildMode.debug,
trackWidgetCreation: false, trackWidgetCreation: false,
...@@ -420,7 +418,7 @@ void main() { ...@@ -420,7 +418,7 @@ void main() {
checkDartPluginRegistry: true, checkDartPluginRegistry: true,
); );
stdoutHandler.compilerOutput.complete(const CompilerOutput('', 0, <Uri>[])); stdoutHandler.compilerOutput?.complete(const CompilerOutput('', 0, <Uri>[]));
completer.complete(); completer.complete();
await output; await output;
}); });
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
...@@ -24,12 +22,12 @@ import '../src/fake_process_manager.dart'; ...@@ -24,12 +22,12 @@ import '../src/fake_process_manager.dart';
import '../src/fakes.dart'; import '../src/fakes.dart';
void main() { void main() {
FakeProcessManager processManager; late FakeProcessManager processManager;
ResidentCompiler generator; late ResidentCompiler generator;
MemoryIOSink frontendServerStdIn; late MemoryIOSink frontendServerStdIn;
StreamController<String> stdErrStreamController; late StreamController<String> stdErrStreamController;
BufferLogger testLogger; late BufferLogger testLogger;
MemoryFileSystem fileSystem; late MemoryFileSystem fileSystem;
setUp(() { setUp(() {
testLogger = BufferLogger.test(); testLogger = BufferLogger.test();
...@@ -52,7 +50,7 @@ void main() { ...@@ -52,7 +50,7 @@ void main() {
}); });
testWithoutContext('compile expression fails if not previously compiled', () async { testWithoutContext('compile expression fails if not previously compiled', () async {
final CompilerOutput result = await generator.compileExpression( final CompilerOutput? result = await generator.compileExpression(
'2+2', null, null, null, null, false); '2+2', null, null, null, null, false);
expect(result, isNull); expect(result, isNull);
...@@ -82,12 +80,12 @@ void main() { ...@@ -82,12 +80,12 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
projectRootPath: '', projectRootPath: '',
fs: fileSystem, fs: fileSystem,
).then((CompilerOutput output) { ).then((CompilerOutput? output) {
expect(frontendServerStdIn.getAndClear(), expect(frontendServerStdIn.getAndClear(),
'compile file:///path/to/main.dart\n'); 'compile file:///path/to/main.dart\n');
expect(testLogger.errorText, expect(testLogger.errorText,
equals('line1\nline2\n')); equals('line1\nline2\n'));
expect(output.outputFilename, equals('/path/to/main.dart.dill')); expect(output!.outputFilename, equals('/path/to/main.dart.dill'));
compileExpressionResponseCompleter.complete( compileExpressionResponseCompleter.complete(
Future<List<int>>.value(utf8.encode( Future<List<int>>.value(utf8.encode(
...@@ -95,9 +93,9 @@ void main() { ...@@ -95,9 +93,9 @@ void main() {
))); )));
generator.compileExpression( generator.compileExpression(
'2+2', null, null, null, null, false).then( '2+2', null, null, null, null, false).then(
(CompilerOutput outputExpression) { (CompilerOutput? outputExpression) {
expect(outputExpression, isNotNull); expect(outputExpression, isNotNull);
expect(outputExpression.expressionData, <int>[1, 2, 3, 4]); expect(outputExpression!.expressionData, <int>[1, 2, 3, 4]);
} }
); );
}); });
...@@ -126,10 +124,10 @@ void main() { ...@@ -126,10 +124,10 @@ void main() {
packageConfig: PackageConfig.empty, packageConfig: PackageConfig.empty,
projectRootPath: '', projectRootPath: '',
fs: MemoryFileSystem(), fs: MemoryFileSystem(),
).then((CompilerOutput outputCompile) { ).then((CompilerOutput? outputCompile) {
expect(testLogger.errorText, expect(testLogger.errorText,
equals('line1\nline2\n')); equals('line1\nline2\n'));
expect(outputCompile.outputFilename, equals('/path/to/main.dart.dill')); expect(outputCompile!.outputFilename, equals('/path/to/main.dart.dill'));
fileSystem.file('/path/to/main.dart.dill.incremental') fileSystem.file('/path/to/main.dart.dill.incremental')
..createSync(recursive: true) ..createSync(recursive: true)
...@@ -144,9 +142,9 @@ void main() { ...@@ -144,9 +142,9 @@ void main() {
final Completer<bool> lastExpressionCompleted = Completer<bool>(); final Completer<bool> lastExpressionCompleted = Completer<bool>();
unawaited( unawaited(
generator.compileExpression('0+1', null, null, null, null, false).then( generator.compileExpression('0+1', null, null, null, null, false).then(
(CompilerOutput outputExpression) { (CompilerOutput? outputExpression) {
expect(outputExpression, isNotNull); expect(outputExpression, isNotNull);
expect(outputExpression.expressionData, <int>[0, 1, 2, 3]); expect(outputExpression!.expressionData, <int>[0, 1, 2, 3]);
fileSystem.file('/path/to/main.dart.dill.incremental') fileSystem.file('/path/to/main.dart.dill.incremental')
..createSync(recursive: true) ..createSync(recursive: true)
...@@ -161,9 +159,9 @@ void main() { ...@@ -161,9 +159,9 @@ void main() {
// The test manages timing via completers. // The test manages timing via completers.
unawaited( unawaited(
generator.compileExpression('1+1', null, null, null, null, false).then( generator.compileExpression('1+1', null, null, null, null, false).then(
(CompilerOutput outputExpression) { (CompilerOutput? outputExpression) {
expect(outputExpression, isNotNull); expect(outputExpression, isNotNull);
expect(outputExpression.expressionData, <int>[4, 5, 6, 7]); expect(outputExpression!.expressionData, <int>[4, 5, 6, 7]);
lastExpressionCompleted.complete(true); lastExpressionCompleted.complete(true);
}, },
), ),
...@@ -179,13 +177,13 @@ void main() { ...@@ -179,13 +177,13 @@ void main() {
class FakeProcess extends Fake implements Process { class FakeProcess extends Fake implements Process {
@override @override
Stream<List<int>> stdout; Stream<List<int>> stdout = const Stream<List<int>>.empty();
@override @override
Stream<List<int>> stderr; Stream<List<int>> stderr = const Stream<List<int>>.empty();
@override @override
IOSink stdin; IOSink stdin = IOSink(StreamController<List<int>>().sink);
@override @override
Future<int> get exitCode => Completer<int>().future; Future<int> get exitCode => Completer<int>().future;
...@@ -195,12 +193,12 @@ class FakeProcessManager extends Fake implements ProcessManager { ...@@ -195,12 +193,12 @@ class FakeProcessManager extends Fake implements ProcessManager {
final FakeProcess process = FakeProcess(); final FakeProcess process = FakeProcess();
@override @override
bool canRun(dynamic executable, {String workingDirectory}) { bool canRun(dynamic executable, {String? workingDirectory}) {
return true; return true;
} }
@override @override
Future<Process> start(List<Object> command, {String workingDirectory, Map<String, String> environment, bool includeParentEnvironment = true, bool runInShell = false, ProcessStartMode mode = ProcessStartMode.normal}) async { Future<Process> start(List<Object> command, {String? workingDirectory, Map<String, String>? environment, bool includeParentEnvironment = true, bool runInShell = false, ProcessStartMode mode = ProcessStartMode.normal}) async {
return process; return process;
} }
} }
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
...@@ -21,13 +19,13 @@ import '../src/fake_process_manager.dart'; ...@@ -21,13 +19,13 @@ import '../src/fake_process_manager.dart';
import '../src/fakes.dart'; import '../src/fakes.dart';
void main() { void main() {
ResidentCompiler generator; late ResidentCompiler generator;
ResidentCompiler generatorWithScheme; late ResidentCompiler generatorWithScheme;
MemoryIOSink frontendServerStdIn; late MemoryIOSink frontendServerStdIn;
BufferLogger testLogger; late BufferLogger testLogger;
StdoutHandler generatorStdoutHandler; late StdoutHandler generatorStdoutHandler;
StdoutHandler generatorWithSchemeStdoutHandler; late StdoutHandler generatorWithSchemeStdoutHandler;
FakeProcessManager fakeProcessManager; late FakeProcessManager fakeProcessManager;
const List<String> frontendServerCommand = <String>[ const List<String> frontendServerCommand = <String>[
'HostArtifact.engineDartBinary', 'HostArtifact.engineDartBinary',
...@@ -87,7 +85,7 @@ void main() { ...@@ -87,7 +85,7 @@ void main() {
stdin: frontendServerStdIn, stdin: frontendServerStdIn,
)); ));
final CompilerOutput output = await generator.recompile( final CompilerOutput? output = await generator.recompile(
Uri.parse('/path/to/main.dart'), Uri.parse('/path/to/main.dart'),
null /* invalidatedFiles */, null /* invalidatedFiles */,
outputPath: '/build/', outputPath: '/build/',
...@@ -97,7 +95,7 @@ void main() { ...@@ -97,7 +95,7 @@ void main() {
); );
expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n'); expect(frontendServerStdIn.getAndClear(), 'compile /path/to/main.dart\n');
expect(testLogger.errorText, equals('line1\nline2\n')); expect(testLogger.errorText, equals('line1\nline2\n'));
expect(output.outputFilename, equals('/path/to/main.dart.dill')); expect(output?.outputFilename, equals('/path/to/main.dart.dill'));
expect(fakeProcessManager, hasNoRemainingExpectations); expect(fakeProcessManager, hasNoRemainingExpectations);
}); });
...@@ -114,7 +112,7 @@ void main() { ...@@ -114,7 +112,7 @@ void main() {
stdin: frontendServerStdIn, stdin: frontendServerStdIn,
)); ));
final CompilerOutput output = await generatorWithScheme.recompile( final CompilerOutput? output = await generatorWithScheme.recompile(
Uri.parse('file:///foo/bar/fizz/main.dart'), Uri.parse('file:///foo/bar/fizz/main.dart'),
null /* invalidatedFiles */, null /* invalidatedFiles */,
outputPath: '/build/', outputPath: '/build/',
...@@ -124,7 +122,7 @@ void main() { ...@@ -124,7 +122,7 @@ void main() {
); );
expect(frontendServerStdIn.getAndClear(), 'compile scheme:///main.dart\n'); expect(frontendServerStdIn.getAndClear(), 'compile scheme:///main.dart\n');
expect(testLogger.errorText, equals('line1\nline2\n')); expect(testLogger.errorText, equals('line1\nline2\n'));
expect(output.outputFilename, equals('/path/to/main.dart.dill')); expect(output?.outputFilename, equals('/path/to/main.dart.dill'));
expect(fakeProcessManager, hasNoRemainingExpectations); expect(fakeProcessManager, hasNoRemainingExpectations);
}); });
...@@ -401,16 +399,16 @@ Future<void> _recompile( ...@@ -401,16 +399,16 @@ Future<void> _recompile(
MemoryIOSink frontendServerStdIn, MemoryIOSink frontendServerStdIn,
String mockCompilerOutput, { String mockCompilerOutput, {
bool suppressErrors = false, bool suppressErrors = false,
Uri mainUri, Uri? mainUri,
String expectedMainUri = '/path/to/main.dart', String expectedMainUri = '/path/to/main.dart',
List<Uri> updatedUris, List<Uri>? updatedUris,
List<String> expectedUpdatedUris, List<String>? expectedUpdatedUris,
}) async { }) async {
mainUri ??= Uri.parse('/path/to/main.dart'); mainUri ??= Uri.parse('/path/to/main.dart');
updatedUris ??= <Uri>[mainUri]; updatedUris ??= <Uri>[mainUri];
expectedUpdatedUris ??= <String>[expectedMainUri]; expectedUpdatedUris ??= <String>[expectedMainUri];
final Future<CompilerOutput> recompileFuture = generator.recompile( final Future<CompilerOutput?> recompileFuture = generator.recompile(
mainUri, mainUri,
updatedUris, updatedUris,
outputPath: '/build/', outputPath: '/build/',
...@@ -425,8 +423,8 @@ Future<void> _recompile( ...@@ -425,8 +423,8 @@ Future<void> _recompile(
scheduleMicrotask(() { scheduleMicrotask(() {
LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler); LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler);
}); });
final CompilerOutput output = await recompileFuture; final CompilerOutput? output = await recompileFuture;
expect(output.outputFilename, equals('/path/to/main.dart.dill')); expect(output?.outputFilename, equals('/path/to/main.dart.dill'));
final String commands = frontendServerStdIn.getAndClear(); final String commands = frontendServerStdIn.getAndClear();
final RegExp whitespace = RegExp(r'\s+'); final RegExp whitespace = RegExp(r'\s+');
final List<String> parts = commands.split(whitespace); final List<String> parts = commands.split(whitespace);
...@@ -459,11 +457,11 @@ Future<void> _reject( ...@@ -459,11 +457,11 @@ Future<void> _reject(
) async { ) async {
// Put content into the output stream after generator.recompile gets // Put content into the output stream after generator.recompile gets
// going few lines below, resets completer. // going few lines below, resets completer.
final Future<CompilerOutput> rejectFuture = generator.reject(); final Future<CompilerOutput?> rejectFuture = generator.reject();
scheduleMicrotask(() { scheduleMicrotask(() {
LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler); LineSplitter.split(mockCompilerOutput).forEach(stdoutHandler.handler);
}); });
final CompilerOutput output = await rejectFuture; final CompilerOutput? output = await rejectFuture;
expect(output, isNull); expect(output, isNull);
final String commands = frontendServerStdIn.getAndClear(); final String commands = frontendServerStdIn.getAndClear();
......
...@@ -2,8 +2,6 @@ ...@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'package:file/file.dart'; import 'package:file/file.dart';
import 'package:file/memory.dart'; import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
...@@ -19,10 +17,10 @@ void main() { ...@@ -19,10 +17,10 @@ void main() {
expect(stdoutHandler.boundaryKey, '12345'); expect(stdoutHandler.boundaryKey, '12345');
stdoutHandler.handler('12345'); stdoutHandler.handler('12345');
stdoutHandler.handler('12345 message 0'); stdoutHandler.handler('12345 message 0');
final CompilerOutput output = await stdoutHandler.compilerOutput.future; final CompilerOutput? output = await stdoutHandler.compilerOutput?.future;
expect(output.errorCount, 0); expect(output?.errorCount, 0);
expect(output.outputFilename, 'message'); expect(output?.outputFilename, 'message');
expect(output.expressionData, null); expect(output?.expressionData, null);
}); });
testWithoutContext('StdoutHandler can read output bytes', () async { testWithoutContext('StdoutHandler can read output bytes', () async {
...@@ -35,11 +33,11 @@ void main() { ...@@ -35,11 +33,11 @@ void main() {
expect(stdoutHandler.boundaryKey, '12345'); expect(stdoutHandler.boundaryKey, '12345');
stdoutHandler.handler('12345'); stdoutHandler.handler('12345');
stdoutHandler.handler('12345 message 0'); stdoutHandler.handler('12345 message 0');
final CompilerOutput output = await stdoutHandler.compilerOutput.future; final CompilerOutput? output = await stdoutHandler.compilerOutput?.future;
expect(output.errorCount, 0); expect(output?.errorCount, 0);
expect(output.outputFilename, 'message'); expect(output?.outputFilename, 'message');
expect(output.expressionData, <int>[1, 2, 3, 4]); expect(output?.expressionData, <int>[1, 2, 3, 4]);
}); });
testWithoutContext('StdoutHandler reads output bytes if errorCount > 0', () async { testWithoutContext('StdoutHandler reads output bytes if errorCount > 0', () async {
...@@ -52,11 +50,11 @@ void main() { ...@@ -52,11 +50,11 @@ void main() {
expect(stdoutHandler.boundaryKey, '12345'); expect(stdoutHandler.boundaryKey, '12345');
stdoutHandler.handler('12345'); stdoutHandler.handler('12345');
stdoutHandler.handler('12345 message 1'); stdoutHandler.handler('12345 message 1');
final CompilerOutput output = await stdoutHandler.compilerOutput.future; final CompilerOutput? output = await stdoutHandler.compilerOutput?.future;
expect(output.errorCount, 1); expect(output?.errorCount, 1);
expect(output.outputFilename, 'message'); expect(output?.outputFilename, 'message');
expect(output.expressionData, <int>[1, 2, 3, 4]); expect(output?.expressionData, <int>[1, 2, 3, 4]);
}); });
testWithoutContext('TargetModel values', () { testWithoutContext('TargetModel values', () {
...@@ -72,7 +70,7 @@ void main() { ...@@ -72,7 +70,7 @@ void main() {
expect(TargetModel('dartdevc'), TargetModel.dartdevc); expect(TargetModel('dartdevc'), TargetModel.dartdevc);
expect(TargetModel.dartdevc.toString(), 'dartdevc'); expect(TargetModel.dartdevc.toString(), 'dartdevc');
expect(() => TargetModel('foobar'), throwsAssertionError); expect(() => TargetModel('foobar'), throwsException);
}); });
testWithoutContext('toMultiRootPath maps different URIs', () async { testWithoutContext('toMultiRootPath maps different URIs', () async {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment