Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions packages/pigeon/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ class TypeDeclaration {
TypeDeclaration({
required this.baseName,
required this.isNullable,
this.typeArguments,
this.typeArguments = const <TypeDeclaration>[],
});

/// The base name of the [TypeDeclaration] (ex 'Foo' to 'Foo<Bar>?').
final String baseName;

/// The type arguments to the entity (ex 'Bar' to 'Foo<Bar>?').
final List<TypeDeclaration>? typeArguments;
final List<TypeDeclaration> typeArguments;

/// True if the type is nullable.
final bool isNullable;
Expand Down
20 changes: 10 additions & 10 deletions packages/pigeon/lib/dart_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ void _writeCodec(Indent indent, String codecName, Api api) {

/// Creates a Dart type where all type arguments are [Objects].
String _makeGenericTypeArguments(TypeDeclaration type, String nullTag) {
return type.typeArguments != null
? '${type.baseName}<${type.typeArguments!.map<String>((TypeDeclaration e) => 'Object$nullTag').join(', ')}>'
return type.typeArguments.isNotEmpty
? '${type.baseName}<${type.typeArguments.map<String>((TypeDeclaration e) => 'Object$nullTag').join(', ')}>'
: _addGenericTypes(type, nullTag);
}

/// Creates a `.cast<>` call for an type. Returns an empty string if the
/// type has no type arguments.
String _makeGenericCastCall(TypeDeclaration type, String nullTag) {
return type.typeArguments != null
? '.cast<${_flattenTypeArguments(type.typeArguments!, nullTag)}>()'
return type.typeArguments.isNotEmpty
? '.cast<${_flattenTypeArguments(type.typeArguments, nullTag)}>()'
: '';
}

Expand Down Expand Up @@ -293,23 +293,23 @@ void _writeFlutterApi(
/// used in Dart code.
String _flattenTypeArguments(List<TypeDeclaration> args, String nullTag) {
return args
.map<String>((TypeDeclaration arg) => arg.typeArguments == null
.map<String>((TypeDeclaration arg) => arg.typeArguments.isEmpty
? '${arg.baseName}$nullTag'
: '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments!, nullTag)}>$nullTag')
: '${arg.baseName}<${_flattenTypeArguments(arg.typeArguments, nullTag)}>$nullTag')
.join(', ');
}

/// Creates the type declaration for use in Dart code from a [NamedType] making sure
/// that type arguments are used for primitive generic types.
String _addGenericTypes(TypeDeclaration type, String nullTag) {
final List<TypeDeclaration>? typeArguments = type.typeArguments;
final List<TypeDeclaration> typeArguments = type.typeArguments;
switch (type.baseName) {
case 'List':
return (typeArguments == null)
return (typeArguments.isEmpty)
? 'List<Object$nullTag>'
: 'List<${_flattenTypeArguments(typeArguments, nullTag)}>';
case 'Map':
return (typeArguments == null)
return (typeArguments.isEmpty)
? 'Map<Object$nullTag, Object$nullTag>'
: 'Map<${_flattenTypeArguments(typeArguments, nullTag)}>';
default:
Expand Down Expand Up @@ -412,7 +412,7 @@ pigeonMap['${field.name}'] != null
pigeonMap['${field.name}'] != null
\t\t? ${field.type.baseName}.values[pigeonMap['${field.name}']$unwrapOperator as int]
\t\t: null''', leadingSpace: false, trailingNewline: false);
} else if (field.type.typeArguments != null) {
} else if (field.type.typeArguments.isNotEmpty) {
final String genericType =
_makeGenericTypeArguments(field.type, nullTag);
final String castCall = _makeGenericCastCall(field.type, nullTag);
Expand Down
4 changes: 2 additions & 2 deletions packages/pigeon/lib/java_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -305,10 +305,10 @@ String? _javaTypeForBuiltinDartType(TypeDeclaration type) {
if (javaTypeForDartTypeMap.containsKey(type.baseName)) {
return javaTypeForDartTypeMap[type.baseName];
} else if (type.baseName == 'List') {
if (type.typeArguments == null) {
if (type.typeArguments.isEmpty) {
return 'List<Object>';
} else {
return 'List<${_flattenTypeArguments(type.typeArguments!)}>';
return 'List<${_flattenTypeArguments(type.typeArguments)}>';
}
} else {
return null;
Expand Down
4 changes: 2 additions & 2 deletions packages/pigeon/lib/objc_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,9 @@ String? _objcTypePtrForPrimitiveDartType(String? classPrefix, NamedType field) {
/// _objcTypeForDartType(null, 'int') => 'NSNumber'.
String _objcTypeForDartType(String? classPrefix, TypeDeclaration field) {
return _objcTypeForDartTypeMap.containsKey(field.baseName)
? field.typeArguments == null
? field.typeArguments.isEmpty
? _objcTypeForDartTypeMap[field.baseName]!
: '${_objcTypeForDartTypeMap[field.baseName]}<${_flattenTypeArguments(classPrefix, field.typeArguments!)}>'
: '${_objcTypeForDartTypeMap[field.baseName]}<${_flattenTypeArguments(classPrefix, field.typeArguments)}>'
: _className(classPrefix, field.baseName);
}

Expand Down
50 changes: 32 additions & 18 deletions packages/pigeon/lib/pigeon_lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ List<Error> _validateAst(Root root, String source) {
for (final Class klass in root.classes) {
for (final NamedType field in klass.fields) {
if (field.type.typeArguments != null) {
for (final TypeDeclaration typeArgument in field.type.typeArguments!) {
for (final TypeDeclaration typeArgument in field.type.typeArguments) {
if (!typeArgument.isNullable) {
result.add(Error(
message:
Expand Down Expand Up @@ -443,6 +443,14 @@ List<Error> _validateAst(Root root, String source) {
lineNumber: _calculateLineNumberNullable(source, method.offset),
));
}
for (final NamedType unnamedType in method.arguments
.where((NamedType element) => element.type.baseName.isEmpty)) {
result.add(Error(
message:
'Arguments must specify their type in method "${method.name}" in API: "${api.name}"',
lineNumber: _calculateLineNumberNullable(source, unnamedType.offset),
));
}
}
}

Expand Down Expand Up @@ -648,20 +656,27 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
}

NamedType formalParameterToField(dart_ast.FormalParameter parameter) {
final dart_ast.TypeName typeName = parameter.childEntities.firstWhere(
(dart_ast_syntactic_entity.SyntacticEntity e) =>
e is dart_ast.TypeName) as dart_ast.TypeName;
final String argTypeBaseName = typeName.name.name;
final bool isNullable = typeName.question != null;
final List<TypeDeclaration>? argTypeArguments =
typeAnnotationsToTypeArguments(typeName.typeArguments);
return NamedType(
type: TypeDeclaration(
baseName: argTypeBaseName,
isNullable: isNullable,
typeArguments: argTypeArguments),
name: parameter.identifier?.name ?? '',
offset: null);
final dart_ast.TypeName? typeName =
getFirstChildOfType<dart_ast.TypeName>(parameter);
if (typeName != null) {
final String argTypeBaseName = typeName.name.name;
final bool isNullable = typeName.question != null;
final List<TypeDeclaration> argTypeArguments =
typeAnnotationsToTypeArguments(typeName.typeArguments);
return NamedType(
type: TypeDeclaration(
baseName: argTypeBaseName,
isNullable: isNullable,
typeArguments: argTypeArguments),
name: parameter.identifier?.name ?? '',
offset: parameter.offset);
} else {
return NamedType(
name: '',
type: TypeDeclaration(baseName: '', isNullable: false),
offset: parameter.offset,
);
}
}

static T? getFirstChildOfType<T>(dart_ast.AstNode entity) {
Expand Down Expand Up @@ -716,13 +731,12 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
return null;
}

List<TypeDeclaration>? typeAnnotationsToTypeArguments(
List<TypeDeclaration> typeAnnotationsToTypeArguments(
dart_ast.TypeArgumentList? typeArguments) {
List<TypeDeclaration>? result;
final List<TypeDeclaration> result = <TypeDeclaration>[];
if (typeArguments != null) {
for (final Object x in typeArguments.childEntities) {
if (x is dart_ast.TypeName) {
result ??= <TypeDeclaration>[];
result.add(TypeDeclaration(
baseName: x.name.name,
isNullable: x.question != null,
Expand Down
Loading