mirror of
https://github.com/flutter/packages.git
synced 2025-07-02 08:34:31 +08:00
[pigeon] 0.2.0 Made null-safe generation the default, updated documentation (#315)
- fix for niladic java functions - tweak to runCommandLine
This commit is contained in:
@ -1,3 +1,30 @@
|
||||
## 0.2.0
|
||||
|
||||
* **BREAKING CHANGE** - Pigeon files must be null-safe now. That means the
|
||||
fields inside of the classes must be declared nullable (
|
||||
[non-null fields](https://github.com/flutter/flutter/issues/59118) arent't yet
|
||||
supported). Migration example:
|
||||
|
||||
```dart
|
||||
// Version 0.1.x
|
||||
class Foo {
|
||||
int bar;
|
||||
String baz;
|
||||
}
|
||||
|
||||
// Version 0.2.x
|
||||
class Foo {
|
||||
int? bar;
|
||||
String? baz;
|
||||
}
|
||||
```
|
||||
|
||||
* **BREAKING CHANGE** - The default output from Pigeon is now null-safe. If you
|
||||
want non-null-safe code you must provide the `--no-dart_null_safety` flag.
|
||||
* The Pigeon source code is now null-safe.
|
||||
* Fixed niladic non-value returning async functions in the Java generator.
|
||||
* Made `runCommandLine` return an the status code.
|
||||
|
||||
## 0.1.24
|
||||
|
||||
* Moved logic from bin/ to lib/ to help customers wrap up the behavior.
|
||||
|
@ -8,8 +8,9 @@ host platform type-safe and easier.
|
||||
## Supported Platforms
|
||||
|
||||
Currently Pigeon only supports generating Objective-C code for usage on iOS and
|
||||
Java code for Android. The Objective-C code is [accessible to Swift](https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_objective-c_into_swift) and the Java
|
||||
code is accessible to Kotlin.
|
||||
Java code for Android. The Objective-C code is
|
||||
[accessible to Swift](https://developer.apple.com/documentation/swift/imported_c_and_objective-c_apis/importing_objective-c_into_swift)
|
||||
and the Java code is accessible to Kotlin.
|
||||
|
||||
## Runtime Requirements
|
||||
|
||||
@ -64,7 +65,8 @@ See the "Example" tab. A full working example can also be found in the
|
||||
|
||||
Pigeon uses the `StandardMessageCodec` so it supports any data-type platform
|
||||
channels supports
|
||||
[[documentation](https://flutter.dev/docs/development/platform-integration/platform-channels#codec)]. Nested data-types are supported, too.
|
||||
[[documentation](https://flutter.dev/docs/development/platform-integration/platform-channels#codec)].
|
||||
Nested data-types are supported, too.
|
||||
|
||||
Note: Generics for List and Map aren't supported yet.
|
||||
|
||||
@ -112,9 +114,12 @@ public interface Api2Host {
|
||||
|
||||
## Null Safety (NNBD)
|
||||
|
||||
In order to generate null-safe code run the command line with the extra argument
|
||||
`--dart_null_safety`. For example:
|
||||
`flutter pub run pigeon --input ./pigeons/messages.dart --dart_null_safety`.
|
||||
Right now Pigeon supports generating null-safe code, but it doesn't yet support
|
||||
[non-null fields](https://github.com/flutter/flutter/issues/59118).
|
||||
|
||||
The default is to generate null-safe code but in order to generate non-null-safe
|
||||
code run Pigeon with the extra argument `--no-dart_null_safety`. For example:
|
||||
`flutter pub run pigeon --input ./pigeons/messages.dart --no-dart_null_safety --dart_out stdout`.
|
||||
|
||||
## Feedback
|
||||
|
||||
|
@ -4,8 +4,10 @@
|
||||
|
||||
// @dart = 2.2
|
||||
|
||||
import 'dart:io' show exit;
|
||||
|
||||
import 'package:pigeon/pigeon_cl.dart';
|
||||
|
||||
Future<void> main(List<String> args) async {
|
||||
await runCommandLine(args);
|
||||
exit(await runCommandLine(args));
|
||||
}
|
||||
|
@ -7,8 +7,11 @@ import 'generator_tools.dart';
|
||||
|
||||
/// Options that control how Dart code will be generated.
|
||||
class DartOptions {
|
||||
/// Constructor for DartOptions.
|
||||
DartOptions({this.isNullSafe = true});
|
||||
|
||||
/// Determines if the generated code has null safety annotations (Dart >=2.12 required).
|
||||
bool isNullSafe = false;
|
||||
bool isNullSafe;
|
||||
}
|
||||
|
||||
String _escapeForDartSingleQuotedString(String raw) {
|
||||
|
@ -27,7 +27,7 @@ String _posixRelative(String input, {required String from}) {
|
||||
/// This is the main entrypoint for the command-line tool. [args] are the
|
||||
/// commmand line arguments and there is an optional [packageConfig] to
|
||||
/// accomodate users that want to integrate pigeon with other build systems.
|
||||
Future<void> runCommandLine(List<String> args, {Uri? packageConfig}) async {
|
||||
Future<int> runCommandLine(List<String> args, {Uri? packageConfig}) async {
|
||||
final PigeonOptions opts = Pigeon.parseArgs(args);
|
||||
final Directory tempDir = Directory.systemTemp.createTempSync(
|
||||
'flutter_pigeon.',
|
||||
@ -71,5 +71,5 @@ void main(List<String> args, SendPort sendPort) async {
|
||||
});
|
||||
final int exitCode = await completer.future;
|
||||
tempDir.deleteSync(recursive: true);
|
||||
exit(exitCode);
|
||||
return exitCode;
|
||||
}
|
||||
|
@ -313,7 +313,8 @@ options:
|
||||
..addOption('java_package',
|
||||
help: 'The package that generated Java code will be in.')
|
||||
..addFlag('dart_null_safety',
|
||||
help: 'Makes generated Dart code have null safety annotations')
|
||||
help: 'Makes generated Dart code have null safety annotations',
|
||||
defaultsTo: true)
|
||||
..addOption('objc_header_out',
|
||||
help: 'Path to generated Objective-C header file (.h).')
|
||||
..addOption('objc_prefix',
|
||||
@ -321,6 +322,10 @@ options:
|
||||
|
||||
/// Convert command-line arguments to [PigeonOptions].
|
||||
static PigeonOptions parseArgs(List<String> args) {
|
||||
// Note: This function shouldn't perform any logic, just translate the args
|
||||
// to PigeonOptions. Synthesized values inside of the PigeonOption should
|
||||
// get set in the `run` function to accomodate users that are using the
|
||||
// `configurePigeon` function.
|
||||
final ArgResults results = _argParser.parse(args);
|
||||
|
||||
final PigeonOptions opts = PigeonOptions();
|
||||
@ -334,9 +339,6 @@ options:
|
||||
);
|
||||
opts.javaOut = results['java_out'];
|
||||
opts.javaOptions = JavaOptions(
|
||||
className: (opts.javaOut == null)
|
||||
? null
|
||||
: path.basenameWithoutExtension(opts.javaOut!),
|
||||
package: results['java_package'],
|
||||
);
|
||||
opts.dartOptions = DartOptions()..isNullSafe = results['dart_null_safety'];
|
||||
@ -480,6 +482,10 @@ options:
|
||||
options.objcOptions ?? ObjcOptions(), parseResults.root, sink));
|
||||
}
|
||||
if (options.javaOut != null) {
|
||||
if (options.javaOptions!.className == null) {
|
||||
options.javaOptions!.className =
|
||||
path.basenameWithoutExtension(options.javaOut!);
|
||||
}
|
||||
await _runGenerator(
|
||||
options.javaOut!,
|
||||
(StringSink sink) => generateJava(
|
||||
|
@ -54,6 +54,7 @@ test_pigeon_ios() {
|
||||
temp_dir=$(mktmpdir)
|
||||
|
||||
pub run pigeon \
|
||||
--no-dart_null_safety \
|
||||
--input $1 \
|
||||
--dart_out $temp_dir/pigeon.dart \
|
||||
--objc_header_out $temp_dir/pigeon.h \
|
||||
@ -80,7 +81,6 @@ test_pigeon_android() {
|
||||
|
||||
pub run pigeon \
|
||||
--input $1 \
|
||||
--dart_null_safety \
|
||||
--dart_out $temp_dir/pigeon.dart \
|
||||
--java_out $temp_dir/Pigeon.java \
|
||||
--java_package foo
|
||||
@ -113,7 +113,6 @@ test_null_safe_dart() {
|
||||
|
||||
pub run pigeon \
|
||||
--input $1 \
|
||||
--dart_null_safety \
|
||||
--dart_out $temp_dir/pigeon.dart
|
||||
|
||||
dartanalyzer $temp_dir/pigeon.dart --fatal-infos --fatal-warnings --packages ./e2e_tests/test_objc/.packages
|
||||
@ -165,7 +164,6 @@ pub run pigeon 1> /dev/null
|
||||
pushd $PWD
|
||||
pub run pigeon \
|
||||
--input pigeons/message.dart \
|
||||
--dart_null_safety \
|
||||
--dart_out platform_tests/flutter_null_safe_unit_tests/lib/null_safe_pigeon.dart
|
||||
cd platform_tests/flutter_null_safe_unit_tests
|
||||
flutter pub get
|
||||
@ -178,7 +176,6 @@ popd
|
||||
pushd $PWD
|
||||
pub run pigeon \
|
||||
--input pigeons/message.dart \
|
||||
--dart_null_safety \
|
||||
--dart_out mock_handler_tester/test/message.dart \
|
||||
--dart_test_out mock_handler_tester/test/test.dart
|
||||
dartfmt -w mock_handler_tester/test/message.dart
|
||||
@ -221,11 +218,13 @@ test_pigeon_ios ./pigeons/all_datatypes.dart
|
||||
# iOS unit tests on generated code.
|
||||
###############################################################################
|
||||
pub run pigeon \
|
||||
--no-dart_null_safety \
|
||||
--input pigeons/message.dart \
|
||||
--dart_out /dev/null \
|
||||
--objc_header_out platform_tests/ios_unit_tests/ios/Runner/messages.h \
|
||||
--objc_source_out platform_tests/ios_unit_tests/ios/Runner/messages.m
|
||||
pub run pigeon \
|
||||
--no-dart_null_safety \
|
||||
--input pigeons/async_handlers.dart \
|
||||
--dart_out /dev/null \
|
||||
--objc_header_out platform_tests/ios_unit_tests/ios/Runner/async_handlers.h \
|
||||
@ -255,7 +254,6 @@ DARTLE_DART="e2e_tests/test_objc/lib/dartle.dart"
|
||||
PIGEON_JAVA="e2e_tests/test_objc/android/app/src/main/java/io/flutter/plugins/Pigeon.java"
|
||||
pub run pigeon \
|
||||
--input pigeons/message.dart \
|
||||
--dart_null_safety \
|
||||
--dart_out $DARTLE_DART \
|
||||
--objc_header_out $DARTLE_H \
|
||||
--objc_source_out $DARTLE_M \
|
||||
|
@ -23,7 +23,7 @@ void main() {
|
||||
classes: <Class>[klass],
|
||||
);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('class Foobar'));
|
||||
expect(code, contains(' dataType1 field1;'));
|
||||
@ -48,7 +48,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')])
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('class Api'));
|
||||
expect(code, matches('Output.*doSomething.*Input'));
|
||||
@ -66,7 +66,7 @@ void main() {
|
||||
)
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(
|
||||
code,
|
||||
@ -101,7 +101,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')])
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('abstract class Api'));
|
||||
expect(code, contains('static void setup(Api'));
|
||||
@ -123,7 +123,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'input', dataType: 'String')]),
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('Future<void> doSomething'));
|
||||
expect(code, contains('// noop'));
|
||||
@ -145,7 +145,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'input', dataType: 'String')]),
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
// The next line verifies that we're not setting a variable to the value of "doSomething", but
|
||||
// ignores the line where we assert the value of the argument isn't null, since on that line
|
||||
@ -171,7 +171,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')]),
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, matches('output.*=.*doSomething[(][)]'));
|
||||
expect(code, contains('Output doSomething();'));
|
||||
@ -193,7 +193,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')]),
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, matches('channel.send[(]null[)]'));
|
||||
});
|
||||
@ -228,7 +228,7 @@ void main() {
|
||||
]);
|
||||
final StringBuffer mainCodeSink = StringBuffer();
|
||||
final StringBuffer testCodeSink = StringBuffer();
|
||||
generateDart(DartOptions(), root, mainCodeSink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, mainCodeSink);
|
||||
final String mainCode = mainCodeSink.toString();
|
||||
expect(mainCode, isNot(contains('import \'fo\\\'o.dart\';')));
|
||||
expect(mainCode, contains('class Api {'));
|
||||
@ -236,7 +236,8 @@ void main() {
|
||||
expect(mainCode, isNot(contains('.ApiMock.doSomething')));
|
||||
expect(mainCode, isNot(contains('\'${Keys.result}\': output.encode()')));
|
||||
expect(mainCode, isNot(contains('return <Object, Object>{};')));
|
||||
generateTestDart(DartOptions(), root, testCodeSink, "fo'o.dart");
|
||||
generateTestDart(
|
||||
DartOptions(isNullSafe: false), root, testCodeSink, "fo'o.dart");
|
||||
final String testCode = testCodeSink.toString();
|
||||
expect(testCode, contains('import \'fo\\\'o.dart\';'));
|
||||
expect(testCode, isNot(contains('class Api {')));
|
||||
@ -261,7 +262,7 @@ void main() {
|
||||
classes: <Class>[klass],
|
||||
);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('// @dart = 2.8'));
|
||||
});
|
||||
@ -285,7 +286,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')])
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('abstract class Api'));
|
||||
expect(code, contains('Future<Output> doSomething(Input arg);'));
|
||||
@ -312,7 +313,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')])
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, isNot(matches('=.s*doSomething')));
|
||||
expect(code, contains('await api.doSomething('));
|
||||
@ -338,7 +339,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')])
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, contains('class Api'));
|
||||
expect(code, matches('Output.*doSomething.*Input'));
|
||||
@ -360,7 +361,7 @@ void main() {
|
||||
fields: <Field>[Field(name: 'output', dataType: 'String')]),
|
||||
]);
|
||||
final StringBuffer sink = StringBuffer();
|
||||
generateDart(DartOptions(), root, sink);
|
||||
generateDart(DartOptions(isNullSafe: false), root, sink);
|
||||
final String code = sink.toString();
|
||||
expect(code, matches('channel.send[(]null[)]'));
|
||||
});
|
||||
|
Reference in New Issue
Block a user