Skip to content

Commit 60ed64f

Browse files
authored
[pigeon] allow gen of unused classes (#7529)
changes pigeon_lib to allow generation of classes that aren't referenced in any API.
1 parent 06f38ba commit 60ed64f

31 files changed

Lines changed: 640 additions & 131 deletions

File tree

packages/pigeon/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 22.1.0
2+
3+
* Allows generation of classes that aren't referenced in an API.
4+
15
## 22.0.0
26

37
* [dart] Changes codec to send int64 instead of int32.

packages/pigeon/lib/ast.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,7 @@ class Class extends Node {
652652
Class({
653653
required this.name,
654654
required this.fields,
655+
this.isReferenced = true,
655656
this.isSwiftClass = false,
656657
this.documentationComments = const <String>[],
657658
});
@@ -662,6 +663,9 @@ class Class extends Node {
662663
/// All the fields contained in the class.
663664
List<NamedType> fields;
664665

666+
/// Whether the class is referenced in any API.
667+
bool isReferenced;
668+
665669
/// Determines whether the defined class should be represented as a struct or
666670
/// a class in Swift generation.
667671
///

packages/pigeon/lib/generator_tools.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'ast.dart';
1313
/// The current version of pigeon.
1414
///
1515
/// This must match the version in pubspec.yaml.
16-
const String pigeonVersion = '22.0.0';
16+
const String pigeonVersion = '22.1.0';
1717

1818
/// Read all the content from [stdin] to a String.
1919
String readStdin() {

packages/pigeon/lib/pigeon_lib.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,23 +1393,24 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
13931393
getReferencedTypes(_apis, _classes);
13941394
final Set<String> referencedTypeNames =
13951395
referencedTypes.keys.map((TypeDeclaration e) => e.baseName).toSet();
1396-
final List<Class> referencedClasses = List<Class>.from(_classes);
1397-
referencedClasses
1398-
.removeWhere((Class x) => !referencedTypeNames.contains(x.name));
1396+
final List<Class> nonReferencedClasses = List<Class>.from(_classes);
1397+
nonReferencedClasses
1398+
.removeWhere((Class x) => referencedTypeNames.contains(x.name));
1399+
for (final Class x in nonReferencedClasses) {
1400+
x.isReferenced = false;
1401+
}
13991402

14001403
final List<Enum> referencedEnums = List<Enum>.from(_enums);
14011404
final Root completeRoot =
1402-
Root(apis: _apis, classes: referencedClasses, enums: referencedEnums);
1405+
Root(apis: _apis, classes: _classes, enums: referencedEnums);
14031406

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

14081411
for (final MapEntry<TypeDeclaration, List<int>> element
14091412
in referencedTypes.entries) {
1410-
if (!referencedClasses
1411-
.map((Class e) => e.name)
1412-
.contains(element.key.baseName) &&
1413+
if (!_classes.map((Class e) => e.name).contains(element.key.baseName) &&
14131414
!referencedEnums
14141415
.map((Enum e) => e.name)
14151416
.contains(element.key.baseName) &&
@@ -1430,7 +1431,7 @@ class _RootBuilder extends dart_ast_visitor.RecursiveAstVisitor<Object?> {
14301431
lineNumber: lineNumber));
14311432
}
14321433
}
1433-
for (final Class classDefinition in referencedClasses) {
1434+
for (final Class classDefinition in _classes) {
14341435
classDefinition.fields = _attachAssociatedDefinitions(
14351436
classDefinition.fields,
14361437
);

packages/pigeon/pigeons/core_tests.dart

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,11 @@ enum AnotherEnum {
1818
justInCase,
1919
}
2020

21-
class SimpleClass {
22-
SimpleClass({
23-
this.aString,
24-
this.aBool = true,
25-
});
21+
// This exists to show that unused data classes still generate.
22+
class UnusedClass {
23+
UnusedClass({this.aField});
2624

27-
String? aString;
28-
bool aBool;
25+
Object? aField;
2926
}
3027

3128
/// A class containing all supported types.

packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/AlternateLanguageTestPlugin.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,10 @@ public void error(Throwable error) {
688688
};
689689
flutterSmallApiOne.echoString(aString, resultCallbackOne);
690690
}
691+
692+
public @NonNull CoreTests.UnusedClass testIfUnusedClassIsGenerated() {
693+
return new CoreTests.UnusedClass();
694+
}
691695
}
692696

693697
class TestPluginWithSuffix implements CoreTests.HostSmallApi {

packages/pigeon/platform_tests/alternate_language_test_plugin/android/src/main/java/com/example/alternate_language_test_plugin/CoreTests.java

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,67 @@ public enum AnotherEnum {
9999
}
100100
}
101101

102+
/** Generated class from Pigeon that represents data sent in messages. */
103+
public static final class UnusedClass {
104+
private @Nullable Object aField;
105+
106+
public @Nullable Object getAField() {
107+
return aField;
108+
}
109+
110+
public void setAField(@Nullable Object setterArg) {
111+
this.aField = setterArg;
112+
}
113+
114+
@Override
115+
public boolean equals(Object o) {
116+
if (this == o) {
117+
return true;
118+
}
119+
if (o == null || getClass() != o.getClass()) {
120+
return false;
121+
}
122+
UnusedClass that = (UnusedClass) o;
123+
return Objects.equals(aField, that.aField);
124+
}
125+
126+
@Override
127+
public int hashCode() {
128+
return Objects.hash(aField);
129+
}
130+
131+
public static final class Builder {
132+
133+
private @Nullable Object aField;
134+
135+
@CanIgnoreReturnValue
136+
public @NonNull Builder setAField(@Nullable Object setterArg) {
137+
this.aField = setterArg;
138+
return this;
139+
}
140+
141+
public @NonNull UnusedClass build() {
142+
UnusedClass pigeonReturn = new UnusedClass();
143+
pigeonReturn.setAField(aField);
144+
return pigeonReturn;
145+
}
146+
}
147+
148+
@NonNull
149+
ArrayList<Object> toList() {
150+
ArrayList<Object> toListResult = new ArrayList<>(1);
151+
toListResult.add(aField);
152+
return toListResult;
153+
}
154+
155+
static @NonNull UnusedClass fromList(@NonNull ArrayList<Object> pigeonVar_list) {
156+
UnusedClass pigeonResult = new UnusedClass();
157+
Object aField = pigeonVar_list.get(0);
158+
pigeonResult.setAField(aField);
159+
return pigeonResult;
160+
}
161+
}
162+
102163
/**
103164
* A class containing all supported types.
104165
*
@@ -2043,14 +2104,16 @@ protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) {
20432104
return value == null ? null : AnotherEnum.values()[((Long) value).intValue()];
20442105
}
20452106
case (byte) 131:
2046-
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
2107+
return UnusedClass.fromList((ArrayList<Object>) readValue(buffer));
20472108
case (byte) 132:
2048-
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
2109+
return AllTypes.fromList((ArrayList<Object>) readValue(buffer));
20492110
case (byte) 133:
2050-
return AllNullableTypesWithoutRecursion.fromList((ArrayList<Object>) readValue(buffer));
2111+
return AllNullableTypes.fromList((ArrayList<Object>) readValue(buffer));
20512112
case (byte) 134:
2052-
return AllClassesWrapper.fromList((ArrayList<Object>) readValue(buffer));
2113+
return AllNullableTypesWithoutRecursion.fromList((ArrayList<Object>) readValue(buffer));
20532114
case (byte) 135:
2115+
return AllClassesWrapper.fromList((ArrayList<Object>) readValue(buffer));
2116+
case (byte) 136:
20542117
return TestMessage.fromList((ArrayList<Object>) readValue(buffer));
20552118
default:
20562119
return super.readValueOfType(type, buffer);
@@ -2065,20 +2128,23 @@ protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) {
20652128
} else if (value instanceof AnotherEnum) {
20662129
stream.write(130);
20672130
writeValue(stream, value == null ? null : ((AnotherEnum) value).index);
2068-
} else if (value instanceof AllTypes) {
2131+
} else if (value instanceof UnusedClass) {
20692132
stream.write(131);
2133+
writeValue(stream, ((UnusedClass) value).toList());
2134+
} else if (value instanceof AllTypes) {
2135+
stream.write(132);
20702136
writeValue(stream, ((AllTypes) value).toList());
20712137
} else if (value instanceof AllNullableTypes) {
2072-
stream.write(132);
2138+
stream.write(133);
20732139
writeValue(stream, ((AllNullableTypes) value).toList());
20742140
} else if (value instanceof AllNullableTypesWithoutRecursion) {
2075-
stream.write(133);
2141+
stream.write(134);
20762142
writeValue(stream, ((AllNullableTypesWithoutRecursion) value).toList());
20772143
} else if (value instanceof AllClassesWrapper) {
2078-
stream.write(134);
2144+
stream.write(135);
20792145
writeValue(stream, ((AllClassesWrapper) value).toList());
20802146
} else if (value instanceof TestMessage) {
2081-
stream.write(135);
2147+
stream.write(136);
20822148
writeValue(stream, ((TestMessage) value).toList());
20832149
} else {
20842150
super.writeValue(stream, value);

packages/pigeon/platform_tests/alternate_language_test_plugin/example/ios/RunnerTests/AllDatatypesTest.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,8 @@ - (void)testAllEquals {
100100
[self waitForExpectations:@[ expectation ] timeout:1.0];
101101
}
102102

103+
- (void)unusedClassesExist {
104+
XCTAssert([[FLTUnusedClass alloc] init] != nil);
105+
}
106+
103107
@end

packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/AlternateLanguageTestPlugin.m

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,10 @@ - (void)callFlutterSmallApiEchoString:(nonnull NSString *)aString
733733
}];
734734
}
735735

736+
- (FLTUnusedClass *)checkIfUnusedClassGenerated {
737+
return [[FLTUnusedClass alloc] init];
738+
}
739+
736740
@end
737741

738742
@interface AlternateLanguageTestAPIWithSuffix ()

packages/pigeon/platform_tests/alternate_language_test_plugin/ios/Classes/CoreTests.gen.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ typedef NS_ENUM(NSUInteger, FLTAnotherEnum) {
3838
- (instancetype)initWithValue:(FLTAnotherEnum)value;
3939
@end
4040

41+
@class FLTUnusedClass;
4142
@class FLTAllTypes;
4243
@class FLTAllNullableTypes;
4344
@class FLTAllNullableTypesWithoutRecursion;
4445
@class FLTAllClassesWrapper;
4546
@class FLTTestMessage;
4647

48+
@interface FLTUnusedClass : NSObject
49+
+ (instancetype)makeWithAField:(nullable id)aField;
50+
@property(nonatomic, strong, nullable) id aField;
51+
@end
52+
4753
/// A class containing all supported types.
4854
@interface FLTAllTypes : NSObject
4955
/// `init` unavailable to enforce nonnull fields, see the `make` class method.

0 commit comments

Comments
 (0)