Skip to content

Commit

Permalink
[pigeon] allow gen of unused classes (#7529)
Browse files Browse the repository at this point in the history
changes pigeon_lib to allow generation of classes that aren't referenced in any API.
  • Loading branch information
tarrinneal authored Aug 29, 2024
1 parent 06f38ba commit 60ed64f
Show file tree
Hide file tree
Showing 31 changed files with 640 additions and 131 deletions.
4 changes: 4 additions & 0 deletions packages/pigeon/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 22.1.0

* Allows generation of classes that aren't referenced in an API.

## 22.0.0

* [dart] Changes codec to send int64 instead of int32.
Expand Down
4 changes: 4 additions & 0 deletions packages/pigeon/lib/ast.dart
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,7 @@ class Class extends Node {
Class({
required this.name,
required this.fields,
this.isReferenced = true,
this.isSwiftClass = false,
this.documentationComments = const <String>[],
});
Expand All @@ -662,6 +663,9 @@ class Class extends Node {
/// All the fields contained in the class.
List<NamedType> fields;

/// Whether the class is referenced in any API.
bool isReferenced;

/// Determines whether the defined class should be represented as a struct or
/// a class in Swift generation.
///
Expand Down
2 changes: 1 addition & 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 = '22.0.0';
const String pigeonVersion = '22.1.0';

/// Read all the content from [stdin] to a String.
String readStdin() {
Expand Down
17 changes: 9 additions & 8 deletions packages/pigeon/lib/pigeon_lib.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1393,23 +1393,24 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
getReferencedTypes(_apis, _classes);
final Set<String> referencedTypeNames =
referencedTypes.keys.map((TypeDeclaration e) => e.baseName).toSet();
final List<Class> referencedClasses = List<Class>.from(_classes);
referencedClasses
.removeWhere((Class x) => !referencedTypeNames.contains(x.name));
final List<Class> nonReferencedClasses = List<Class>.from(_classes);
nonReferencedClasses
.removeWhere((Class x) => referencedTypeNames.contains(x.name));
for (final Class x in nonReferencedClasses) {
x.isReferenced = false;
}

final List<Enum> referencedEnums = List<Enum>.from(_enums);
final Root completeRoot =
Root(apis: _apis, classes: referencedClasses, enums: referencedEnums);
Root(apis: _apis, classes: _classes, enums: referencedEnums);

final List<Error> validateErrors = _validateAst(completeRoot, source);
final List<Error> totalErrors = List<Error>.from(_errors);
totalErrors.addAll(validateErrors);

for (final MapEntry<TypeDeclaration, List<int>> element
in referencedTypes.entries) {
if (!referencedClasses
.map((Class e) => e.name)
.contains(element.key.baseName) &&
if (!_classes.map((Class e) => e.name).contains(element.key.baseName) &&
!referencedEnums
.map((Enum e) => e.name)
.contains(element.key.baseName) &&
Expand All @@ -1430,7 +1431,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
lineNumber: lineNumber));
}
}
for (final Class classDefinition in referencedClasses) {
for (final Class classDefinition in _classes) {
classDefinition.fields = _attachAssociatedDefinitions(
classDefinition.fields,
);
Expand Down
11 changes: 4 additions & 7 deletions packages/pigeon/pigeons/core_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,11 @@ enum AnotherEnum {
justInCase,
}

class SimpleClass {
SimpleClass({
this.aString,
this.aBool = true,
});
// This exists to show that unused data classes still generate.
class UnusedClass {
UnusedClass({this.aField});

String? aString;
bool aBool;
Object? aField;
}

/// A class containing all supported types.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,10 @@ public void error(Throwable error) {
};
flutterSmallApiOne.echoString(aString, resultCallbackOne);
}

public @NonNull CoreTests.UnusedClass testIfUnusedClassIsGenerated() {
return new CoreTests.UnusedClass();
}
}

class TestPluginWithSuffix implements CoreTests.HostSmallApi {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,67 @@ public enum AnotherEnum {
}
}

/** Generated class from Pigeon that represents data sent in messages. */
public static final class UnusedClass {
private @Nullable Object aField;

public @Nullable Object getAField() {
return aField;
}

public void setAField(@Nullable Object setterArg) {
this.aField = setterArg;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UnusedClass that = (UnusedClass) o;
return Objects.equals(aField, that.aField);
}

@Override
public int hashCode() {
return Objects.hash(aField);
}

public static final class Builder {

private @Nullable Object aField;

@CanIgnoreReturnValue
public @NonNull Builder setAField(@Nullable Object setterArg) {
this.aField = setterArg;
return this;
}

public @NonNull UnusedClass build() {
UnusedClass pigeonReturn = new UnusedClass();
pigeonReturn.setAField(aField);
return pigeonReturn;
}
}

@NonNull
ArrayList<Object> toList() {
ArrayList<Object> toListResult = new ArrayList<>(1);
toListResult.add(aField);
return toListResult;
}

static @NonNull UnusedClass fromList(@NonNull ArrayList<Object> pigeonVar_list) {
UnusedClass pigeonResult = new UnusedClass();
Object aField = pigeonVar_list.get(0);
pigeonResult.setAField(aField);
return pigeonResult;
}
}

/**
* A class containing all supported types.
*
Expand Down Expand Up @@ -2043,14 +2104,16 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
return value == null ? null : AnotherEnum.values()[((Long) value).intValue()];
}
case (byte) 131:
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
return UnusedClass.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 132:
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 133:
return AllNullableTypesWithoutRecursion.fromList((ArrayList<Object>) readValue(buffer));
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 134:
return AllClassesWrapper.fromList((ArrayList<Object>) readValue(buffer));
return AllNullableTypesWithoutRecursion.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 135:
return AllClassesWrapper.fromList((ArrayList<Object>) readValue(buffer));
case (byte) 136:
return TestMessage.fromList((ArrayList<Object>) readValue(buffer));
default:
return super.readValueOfType(type, buffer);
Expand All @@ -2065,20 +2128,23 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
} else if (value instanceof AnotherEnum) {
stream.write(130);
writeValue(stream, value == null ? null : ((AnotherEnum) value).index);
} else if (value instanceof AllTypes) {
} else if (value instanceof UnusedClass) {
stream.write(131);
writeValue(stream, ((UnusedClass) value).toList());
} else if (value instanceof AllTypes) {
stream.write(132);
writeValue(stream, ((AllTypes) value).toList());
} else if (value instanceof AllNullableTypes) {
stream.write(132);
stream.write(133);
writeValue(stream, ((AllNullableTypes) value).toList());
} else if (value instanceof AllNullableTypesWithoutRecursion) {
stream.write(133);
stream.write(134);
writeValue(stream, ((AllNullableTypesWithoutRecursion) value).toList());
} else if (value instanceof AllClassesWrapper) {
stream.write(134);
stream.write(135);
writeValue(stream, ((AllClassesWrapper) value).toList());
} else if (value instanceof TestMessage) {
stream.write(135);
stream.write(136);
writeValue(stream, ((TestMessage) value).toList());
} else {
super.writeValue(stream, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,8 @@ - (void)testAllEquals {
[self waitForExpectations:@[ expectation ] timeout:1.0];
}

- (void)unusedClassesExist {
XCTAssert([[FLTUnusedClass alloc] init] != nil);
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,10 @@ - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString
}];
}

- (FLTUnusedClass *)checkIfUnusedClassGenerated {
return [[FLTUnusedClass alloc] init];
}

@end

@interface AlternateLanguageTestAPIWithSuffix ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ typedef NS_ENUM(NSUInteger, FLTAnotherEnum) {
- (instancetype)initWithValue:(FLTAnotherEnum)value;
@end

@class FLTUnusedClass;
@class FLTAllTypes;
@class FLTAllNullableTypes;
@class FLTAllNullableTypesWithoutRecursion;
@class FLTAllClassesWrapper;
@class FLTTestMessage;

@interface FLTUnusedClass : NSObject
+ (instancetype)makeWithAField:(nullable id)aField;
@property(nonatomic, strong, nullable) id aField;
@end

/// A class containing all supported types.
@interface FLTAllTypes : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ - (instancetype)initWithValue:(FLTAnotherEnum)value {
}
@end

@interface FLTUnusedClass ()
+ (FLTUnusedClass *)fromList:(NSArray<id> *)list;
+ (nullable FLTUnusedClass *)nullableFromList:(NSArray<id> *)list;
- (NSArray<id> *)toList;
@end

@interface FLTAllTypes ()
+ (FLTAllTypes *)fromList:(NSArray<id> *)list;
+ (nullable FLTAllTypes *)nullableFromList:(NSArray<id> *)list;
Expand Down Expand Up @@ -90,6 +96,27 @@ + (nullable FLTTestMessage *)nullableFromList:(NSArray<id> *)list;
- (NSArray<id> *)toList;
@end

@implementation FLTUnusedClass
+ (instancetype)makeWithAField:(nullable id)aField {
FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init];
pigeonResult.aField = aField;
return pigeonResult;
}
+ (FLTUnusedClass *)fromList:(NSArray<id> *)list {
FLTUnusedClass *pigeonResult = [[FLTUnusedClass alloc] init];
pigeonResult.aField = GetNullableObjectAtIndex(list, 0);
return pigeonResult;
}
+ (nullable FLTUnusedClass *)nullableFromList:(NSArray<id> *)list {
return (list) ? [FLTUnusedClass fromList:list] : nil;
}
- (NSArray<id> *)toList {
return @[
self.aField ?: [NSNull null],
];
}
@end

@implementation FLTAllTypes
+ (instancetype)makeWithABool:(BOOL)aBool
anInt:(NSInteger)anInt
Expand Down Expand Up @@ -469,14 +496,16 @@ - (nullable id)readValueOfType:(UInt8)type {
: [[FLTAnotherEnumBox alloc] initWithValue:[enumAsNumber integerValue]];
}
case 131:
return [FLTAllTypes fromList:[self readValue]];
return [FLTUnusedClass fromList:[self readValue]];
case 132:
return [FLTAllNullableTypes fromList:[self readValue]];
return [FLTAllTypes fromList:[self readValue]];
case 133:
return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]];
return [FLTAllNullableTypes fromList:[self readValue]];
case 134:
return [FLTAllClassesWrapper fromList:[self readValue]];
return [FLTAllNullableTypesWithoutRecursion fromList:[self readValue]];
case 135:
return [FLTAllClassesWrapper fromList:[self readValue]];
case 136:
return [FLTTestMessage fromList:[self readValue]];
default:
return [super readValueOfType:type];
Expand All @@ -496,21 +525,24 @@ - (void)writeValue:(id)value {
FLTAnotherEnumBox *box = (FLTAnotherEnumBox *)value;
[self writeByte:130];
[self writeValue:(value == nil ? [NSNull null] : [NSNumber numberWithInteger:box.value])];
} else if ([value isKindOfClass:[FLTAllTypes class]]) {
} else if ([value isKindOfClass:[FLTUnusedClass class]]) {
[self writeByte:131];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[FLTAllNullableTypes class]]) {
} else if ([value isKindOfClass:[FLTAllTypes class]]) {
[self writeByte:132];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) {
} else if ([value isKindOfClass:[FLTAllNullableTypes class]]) {
[self writeByte:133];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[FLTAllClassesWrapper class]]) {
} else if ([value isKindOfClass:[FLTAllNullableTypesWithoutRecursion class]]) {
[self writeByte:134];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[FLTTestMessage class]]) {
} else if ([value isKindOfClass:[FLTAllClassesWrapper class]]) {
[self writeByte:135];
[self writeValue:[value toList]];
} else if ([value isKindOfClass:[FLTTestMessage class]]) {
[self writeByte:136];
[self writeValue:[value toList]];
} else {
[super writeValue:value];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,10 @@ - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString
}];
}

- (UnusedClass *)checkIfUnusedClassGenerated {
return [[UnusedClass alloc] init];
}

@end

@interface AlternateLanguageTestAPIWithSuffix ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ typedef NS_ENUM(NSUInteger, AnotherEnum) {
- (instancetype)initWithValue:(AnotherEnum)value;
@end

@class UnusedClass;
@class AllTypes;
@class AllNullableTypes;
@class AllNullableTypesWithoutRecursion;
@class AllClassesWrapper;
@class TestMessage;

@interface UnusedClass : NSObject
+ (instancetype)makeWithAField:(nullable id)aField;
@property(nonatomic, strong, nullable) id aField;
@end

/// A class containing all supported types.
@interface AllTypes : NSObject
/// `init` unavailable to enforce nonnull fields, see the `make` class method.
Expand Down
Loading

0 comments on commit 60ed64f

Please sign in to comment.