From 306bc50006f8717bb605b3481e5636f10f352ff0 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Fri, 25 Sep 2020 16:02:15 -0700 Subject: [PATCH] [pigeon] switched to using isolates instead of subprocesses to run pigeon_lib (#210) --- packages/pigeon/CHANGELOG.md | 6 ++++ packages/pigeon/bin/pigeon.dart | 40 ++++++++++++++++-------- packages/pigeon/lib/generator_tools.dart | 2 +- packages/pigeon/pubspec.yaml | 2 +- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/packages/pigeon/CHANGELOG.md b/packages/pigeon/CHANGELOG.md index 7aaf8f9d78..4d0ef22ebb 100644 --- a/packages/pigeon/CHANGELOG.md +++ b/packages/pigeon/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.1.8 + +* Started spawning pigeon_lib in an isolate instead of a subprocess. The + subprocess could have lead to errors if the dart version on $PATH didn't match + the one that comes with flutter. + ## 0.1.7 * Fixed Dart compilation for later versions that support null safety, opting out diff --git a/packages/pigeon/bin/pigeon.dart b/packages/pigeon/bin/pigeon.dart index e203bf26ae..72497a87cd 100644 --- a/packages/pigeon/bin/pigeon.dart +++ b/packages/pigeon/bin/pigeon.dart @@ -2,31 +2,45 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'dart:convert'; +import 'dart:async'; import 'dart:io'; +import 'dart:isolate'; +import 'package:path/path.dart' as path; import 'package:pigeon/pigeon_lib.dart'; Future main(List args) async { final PigeonOptions opts = Pigeon.parseArgs(args); assert(opts.input != null); + final String rawInputPath = opts.input; + final Directory tempDir = Directory.systemTemp.createTempSync(); + final String absInputPath = File(rawInputPath).absolute.path; + final String relInputPath = path.relative(absInputPath, from: tempDir.path); + final String importLine = - (opts.input != null) ? 'import \'${opts.input}\';\n' : ''; + (opts.input != null) ? 'import \'$relInputPath\';\n' : ''; final String code = """$importLine import 'dart:io'; +import 'dart:isolate'; import 'package:pigeon/pigeon_lib.dart'; -void main(List args) async { - exit(await Pigeon.run(args)); +void main(List args, SendPort sendPort) async { + sendPort.send(await Pigeon.run(args)); } """; - // TODO(aaclarke): Start using a system temp file. - const String tempFilename = '_pigeon_temp_.dart'; - final File tempFile = await File(tempFilename).writeAsString(code); - final Process process = - await Process.start('dart', [tempFilename] + args); - process.stdout.transform(utf8.decoder).listen((String data) => print(data)); - process.stderr.transform(utf8.decoder).listen((String data) => print(data)); - final int exitCode = await process.exitCode; - tempFile.deleteSync(); + final String tempFilename = path.join(tempDir.path, '_pigeon_temp_.dart'); + await File(tempFilename).writeAsString(code); + final ReceivePort receivePort = ReceivePort(); + Isolate.spawnUri(Uri.parse(tempFilename), args, receivePort.sendPort); + final Completer completer = Completer(); + receivePort.listen((dynamic message) { + try { + // ignore: avoid_as + completer.complete(message as int); + } catch (exception) { + completer.completeError(exception); + } + }); + final int exitCode = await completer.future; + tempDir.deleteSync(recursive: true); exit(exitCode); } diff --git a/packages/pigeon/lib/generator_tools.dart b/packages/pigeon/lib/generator_tools.dart index f828ac2773..940fa19d00 100644 --- a/packages/pigeon/lib/generator_tools.dart +++ b/packages/pigeon/lib/generator_tools.dart @@ -8,7 +8,7 @@ import 'dart:mirrors'; import 'ast.dart'; /// The current version of pigeon. -const String pigeonVersion = '0.1.7'; +const String pigeonVersion = '0.1.8'; /// Read all the content from [stdin] to a String. String readStdin() { diff --git a/packages/pigeon/pubspec.yaml b/packages/pigeon/pubspec.yaml index 6fe39a89f4..d2ff73ccc3 100644 --- a/packages/pigeon/pubspec.yaml +++ b/packages/pigeon/pubspec.yaml @@ -1,5 +1,5 @@ name: pigeon -version: 0.1.7 +version: 0.1.8 description: Code generator tool to make communication between Flutter and the host platform type-safe and easier. homepage: https://github.com/flutter/packages/tree/master/packages/pigeon dependencies: