Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
new prefix, rename codec, add tests bump version
  • Loading branch information
tarrinneal committed Nov 15, 2023
commit dee2d8f2e05df47cb2e6af200c0cd2cc73c05afb
5 changes: 4 additions & 1 deletion packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
## 13.2.0
## 14.0.0

* **Breaking change** [dart] Renames locally defined host API variables.
* Host api static field `codec ` changed to `pigeonChannelCodec`.
* Adds named parameters to host API methods.
* Adds optional parameters to host API methods.
* Adds default values for class constructors and host API methods.
* Adds `isEnum` and `isClass` to `TypeDeclaration`s.


## 13.1.0

* [swift] Fixes Flutter Api void return error handling.
Expand Down
113 changes: 59 additions & 54 deletions packages/pigeon/example/app/lib/src/messages.g.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// found in the LICENSE file.
// Autogenerated from Pigeon, do not edit directly.
// See also: https://pub.dev/packages/pigeon
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import
// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers

import 'dart:async';
import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
Expand Down Expand Up @@ -98,113 +98,118 @@ class ExampleHostApi {
/// available for dependency injection. If it is left null, the default
/// BinaryMessenger will be used which routes to the host platform.
ExampleHostApi({BinaryMessenger? binaryMessenger})
: $_binaryMessenger = binaryMessenger;
final BinaryMessenger? $_binaryMessenger;
: __pigeon_binaryMessenger = binaryMessenger;
final BinaryMessenger? __pigeon_binaryMessenger;

static const MessageCodec<Object?> $_codec = _ExampleHostApiCodec();
static const MessageCodec<Object?> pigeonChannelCodec =
_ExampleHostApiCodec();

Future<String> getHostLanguage() async {
const String $_channelName =
const String __pigeon_channelName =
'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.getHostLanguage';
final BasicMessageChannel<Object?> $_channel = BasicMessageChannel<Object?>(
$_channelName,
$_codec,
binaryMessenger: $_binaryMessenger,
final BasicMessageChannel<Object?> __pigeon_channel =
BasicMessageChannel<Object?>(
__pigeon_channelName,
pigeonChannelCodec,
binaryMessenger: __pigeon_binaryMessenger,
);
final List<Object?>? $_replyList =
await $_channel.send(null) as List<Object?>?;
if ($_replyList == null) {
throw _createConnectionError($_channelName);
} else if ($_replyList.length > 1) {
final List<Object?>? __pigeon_replyList =
await __pigeon_channel.send(null) as List<Object?>?;
if (__pigeon_replyList == null) {
throw _createConnectionError(__pigeon_channelName);
} else if (__pigeon_replyList.length > 1) {
throw PlatformException(
code: $_replyList[0]! as String,
message: $_replyList[1] as String?,
details: $_replyList[2],
code: __pigeon_replyList[0]! as String,
message: __pigeon_replyList[1] as String?,
details: __pigeon_replyList[2],
);
} else if ($_replyList[0] == null) {
} else if (__pigeon_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return ($_replyList[0] as String?)!;
return (__pigeon_replyList[0] as String?)!;
}
}

Future<int> add(int a, int b) async {
const String $_channelName =
const String __pigeon_channelName =
'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.add';
final BasicMessageChannel<Object?> $_channel = BasicMessageChannel<Object?>(
$_channelName,
$_codec,
binaryMessenger: $_binaryMessenger,
final BasicMessageChannel<Object?> __pigeon_channel =
BasicMessageChannel<Object?>(
__pigeon_channelName,
pigeonChannelCodec,
binaryMessenger: __pigeon_binaryMessenger,
);
final List<Object?>? $_replyList =
await $_channel.send(<Object?>[a, b]) as List<Object?>?;
if ($_replyList == null) {
throw _createConnectionError($_channelName);
} else if ($_replyList.length > 1) {
final List<Object?>? __pigeon_replyList =
await __pigeon_channel.send(<Object?>[a, b]) as List<Object?>?;
if (__pigeon_replyList == null) {
throw _createConnectionError(__pigeon_channelName);
} else if (__pigeon_replyList.length > 1) {
throw PlatformException(
code: $_replyList[0]! as String,
message: $_replyList[1] as String?,
details: $_replyList[2],
code: __pigeon_replyList[0]! as String,
message: __pigeon_replyList[1] as String?,
details: __pigeon_replyList[2],
);
} else if ($_replyList[0] == null) {
} else if (__pigeon_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return ($_replyList[0] as int?)!;
return (__pigeon_replyList[0] as int?)!;
}
}

Future<bool> sendMessage(MessageData message) async {
const String $_channelName =
const String __pigeon_channelName =
'dev.flutter.pigeon.pigeon_example_package.ExampleHostApi.sendMessage';
final BasicMessageChannel<Object?> $_channel = BasicMessageChannel<Object?>(
$_channelName,
$_codec,
binaryMessenger: $_binaryMessenger,
final BasicMessageChannel<Object?> __pigeon_channel =
BasicMessageChannel<Object?>(
__pigeon_channelName,
pigeonChannelCodec,
binaryMessenger: __pigeon_binaryMessenger,
);
final List<Object?>? $_replyList =
await $_channel.send(<Object?>[message]) as List<Object?>?;
if ($_replyList == null) {
throw _createConnectionError($_channelName);
} else if ($_replyList.length > 1) {
final List<Object?>? __pigeon_replyList =
await __pigeon_channel.send(<Object?>[message]) as List<Object?>?;
if (__pigeon_replyList == null) {
throw _createConnectionError(__pigeon_channelName);
} else if (__pigeon_replyList.length > 1) {
throw PlatformException(
code: $_replyList[0]! as String,
message: $_replyList[1] as String?,
details: $_replyList[2],
code: __pigeon_replyList[0]! as String,
message: __pigeon_replyList[1] as String?,
details: __pigeon_replyList[2],
);
} else if ($_replyList[0] == null) {
} else if (__pigeon_replyList[0] == null) {
throw PlatformException(
code: 'null-error',
message: 'Host platform returned null value for non-null return value.',
);
} else {
return ($_replyList[0] as bool?)!;
return (__pigeon_replyList[0] as bool?)!;
}
}
}

abstract class MessageFlutterApi {
static const MessageCodec<Object?> $_codec = StandardMessageCodec();
static const MessageCodec<Object?> pigeonChannelCodec =
StandardMessageCodec();

String flutterMethod(String? aString);

static void setup(MessageFlutterApi? api,
{BinaryMessenger? binaryMessenger}) {
{
final BasicMessageChannel<Object?> $_channel = BasicMessageChannel<
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<
Object?>(
'dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod',
$_codec,
pigeonChannelCodec,
binaryMessenger: binaryMessenger);
if (api == null) {
$_channel.setMessageHandler(null);
__pigeon_channel.setMessageHandler(null);
} else {
$_channel.setMessageHandler((Object? message) async {
__pigeon_channel.setMessageHandler((Object? message) async {
assert(message != null,
'Argument for dev.flutter.pigeon.pigeon_example_package.MessageFlutterApi.flutterMethod was null.');
final List<Object?> args = (message as List<Object?>?)!;
Expand Down
93 changes: 48 additions & 45 deletions packages/pigeon/lib/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import 'generator_tools.dart';
/// Documentation comment open symbol.
const String _docCommentPrefix = '///';

const String _varNamePrefix = r'$_';
const String _varNamePrefix = '__pigeon_';

/// Documentation comment spec.
const DocumentCommentSpecification _docCommentSpec =
Expand Down Expand Up @@ -87,7 +87,7 @@ class DartGenerator extends StructuredGenerator<DartOptions> {
indent.writeln('// ${getGeneratedCodeWarning()}');
indent.writeln('// $seeAlsoWarning');
indent.writeln(
'// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import',
'// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers',
);
indent.newln();
}
Expand Down Expand Up @@ -327,7 +327,7 @@ $resultAt != null
'static TestDefaultBinaryMessengerBinding? get _testBinaryMessengerBinding => TestDefaultBinaryMessengerBinding.instance;');
}
indent.writeln(
'static const MessageCodec<Object?> ${_varNamePrefix}codec = $codecName();');
'static const MessageCodec<Object?> pigeonChannelCodec = $codecName();');
indent.newln();
for (final Method func in api.methods) {
addDocumentationComments(
Expand All @@ -354,7 +354,7 @@ $resultAt != null
? makeChannelName(api, func, dartPackageName)
: channelNameFunc(func);
indent.nest(2, () {
indent.writeln("'$channelName', ${_varNamePrefix}codec,");
indent.writeln("'$channelName', pigeonChannelCodec,");
indent.writeln(
'binaryMessenger: binaryMessenger);',
);
Expand Down Expand Up @@ -506,7 +506,7 @@ final BinaryMessenger? ${_varNamePrefix}binaryMessenger;
''');

indent.writeln(
'static const MessageCodec<Object?> ${_varNamePrefix}codec = $codecName();');
'static const MessageCodec<Object?> pigeonChannelCodec = $codecName();');
indent.newln();
for (final Method func in api.methods) {
if (!first) {
Expand Down Expand Up @@ -541,7 +541,7 @@ final BinaryMessenger? ${_varNamePrefix}binaryMessenger;
'final BasicMessageChannel<Object?> ${_varNamePrefix}channel = BasicMessageChannel<Object?>(',
');', () {
indent.writeln('${_varNamePrefix}channelName,');
indent.writeln('${_varNamePrefix}codec,');
indent.writeln('pigeonChannelCodec,');
indent
.writeln('binaryMessenger: ${_varNamePrefix}binaryMessenger,');
});
Expand Down Expand Up @@ -664,7 +664,7 @@ if (${_varNamePrefix}replyList == null) {
indent.writeln('// ${getGeneratedCodeWarning()}');
indent.writeln('// $seeAlsoWarning');
indent.writeln(
'// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import',
'// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, unnecessary_import, no_leading_underscores_for_local_identifiers',
);
indent.writeln('// ignore_for_file: avoid_relative_lib_imports');
}
Expand Down Expand Up @@ -818,53 +818,56 @@ String _getParameterName(int count, NamedType field) =>
/// Generates the arguments code for [func]
/// Example: (func, getArgumentName) -> 'String? foo, int bar'
String _getMethodParameterSignature(Method func) {
String signature = '';
if (func.parameters.isEmpty) {
return '';
return signature;
}
bool firstNonPositionalParameter = true;
bool firstOptionalPositional = true;

final List<String> stringArgs = <String>[];

int index = 0;
for (final Parameter arg in func.parameters) {
String preArgSymbol = '';
if (!arg.isPositional && firstNonPositionalParameter) {
firstNonPositionalParameter = false;
preArgSymbol = '{';
} else if (arg.isPositional && arg.isOptional && firstOptionalPositional) {
firstOptionalPositional = false;
preArgSymbol = '[';
}

final String required =
arg.isRequired && !arg.isPositional ? 'required ' : '';
final List<Parameter> requiredPositionalParams = func.parameters
.where((Parameter p) => p.isPositional && !p.isOptional)
.toList();
final List<Parameter> optionalPositionalParams = func.parameters
.where((Parameter p) => p.isPositional && p.isOptional)
.toList();
final List<Parameter> namedParams =
func.parameters.where((Parameter p) => !p.isPositional).toList();

final String type = _addGenericTypesNullable(arg.type);
String getParameterString(Parameter p) {
final String required = p.isRequired && !p.isPositional ? 'required ' : '';

final String argName = _getParameterName(index, arg);
final String type = _addGenericTypesNullable(p.type);

final String defaultValue =
arg.defaultValue == null ? '' : ' = ${arg.defaultValue}';

String postArgSymbol = '';
if (!arg.isPositional &&
!firstNonPositionalParameter &&
func.parameters.length - 1 == index) {
postArgSymbol = '}';
} else if (arg.isPositional &&
!firstOptionalPositional &&
(func.parameters.length - 1 == index ||
func.parameters[index + 1].defaultValue == null ||
!func.parameters[index + 1].isPositional)) {
postArgSymbol = ']';
}
stringArgs
.add('$preArgSymbol$required$type $argName$defaultValue$postArgSymbol');
index++;
p.defaultValue == null ? '' : ' = ${p.defaultValue}';
return '$required$type ${p.name}$defaultValue';
}

return stringArgs.join(', ');
final String baseParameterString = requiredPositionalParams
.map((Parameter p) => getParameterString(p))
.join(', ');
final String optionalParameterString = optionalPositionalParams
.map((Parameter p) => getParameterString(p))
.join(', ');
final String namedParameterString =
namedParams.map((Parameter p) => getParameterString(p)).join(', ');
// Parameter lists can end with either named or optional positional parameters, but not both.
if (baseParameterString.isNotEmpty) {
final String trailingComma = getTrailingComma(baseParameterString,
<String>[namedParameterString, optionalParameterString]);
signature = '$baseParameterString$trailingComma';
}
final String baseParams = signature.isNotEmpty ? '$signature ' : '';
if (namedParameterString.isNotEmpty) {
final String trailingComma =
getTrailingComma(baseParams, <String>[namedParameterString]);
return '$baseParams{$namedParameterString$trailingComma}';
}
if (optionalParameterString.isNotEmpty) {
final String trailingComma =
getTrailingComma(baseParams, <String>[optionalParameterString]);
return '$baseParams[$optionalParameterString$trailingComma]';
}
return signature;
}

/// Converts a [List] of [TypeDeclaration]s to a comma separated [String] to be
Expand Down
8 changes: 7 additions & 1 deletion packages/pigeon/lib/generator_tools.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import 'ast.dart';
/// The current version of pigeon.
///
/// This must match the version in pubspec.yaml.
const String pigeonVersion = '13.2.0';
const String pigeonVersion = '14.0.0';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down Expand Up @@ -622,3 +622,9 @@ class OutputFileOptions<T> {
/// Options for specified language across all file types.
T languageOptions;
}

/// Provides a trailing comma for strings that are greater than 75 len
String getTrailingComma(String string,
[List<String> moreStrings = const <String>[]]) {
return '$string${moreStrings.join()}'.length > 75 ? ',' : '';
}
Loading