Skip to content

Commit eecde42

Browse files
xaionaro@dx.centerxaionaro@dx.center
authored andcommitted
feat: generate TransactionReceiver stubs for AIDL interfaces
1 parent c0e6a3e commit eecde42

2 files changed

Lines changed: 486 additions & 2 deletions

File tree

tools/pkg/codegen/codegen_test.go

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,19 @@ func TestGenerateInterface_Simple(t *testing.T) {
100100
// Check proxy methods use parcel operations.
101101
assert.Contains(t, srcStr, "WriteInterfaceToken(DescriptorIServiceManager)")
102102
assert.Contains(t, srcStr, "binder.ReadStatus(_reply)")
103+
104+
// Check stub struct.
105+
assert.Contains(t, srcStr, "type ServiceManagerStub struct")
106+
assert.Contains(t, srcStr, "Impl IServiceManager")
107+
assert.Contains(t, srcStr, "var _ binder.TransactionReceiver = (*ServiceManagerStub)(nil)")
108+
109+
// Check stub OnTransaction method.
110+
assert.Contains(t, srcStr, "func (s *ServiceManagerStub) OnTransaction(")
111+
assert.Contains(t, srcStr, "case TransactionIServiceManagerGetService:")
112+
assert.Contains(t, srcStr, "case TransactionIServiceManagerIsDeclared:")
113+
assert.Contains(t, srcStr, "s.Impl.IsDeclared(ctx, _arg_name)")
114+
assert.Contains(t, srcStr, "binder.WriteStatus(_reply, _err)")
115+
assert.Contains(t, srcStr, "binder.WriteStatus(_reply, nil)")
103116
}
104117

105118
func TestGenerateInterface_Oneway(t *testing.T) {
@@ -919,3 +932,130 @@ func TestElementTypeSpec(t *testing.T) {
919932
assert.Equal(t, "int", elem.Name)
920933
})
921934
}
935+
936+
func TestDeriveStubName(t *testing.T) {
937+
tests := []struct {
938+
input string
939+
expected string
940+
}{
941+
{"IServiceManager", "ServiceManagerStub"},
942+
{"IFoo", "FooStub"},
943+
{"Foo", "FooStub"},
944+
{"I", "IStub"},
945+
}
946+
947+
for _, tt := range tests {
948+
t.Run(tt.input, func(t *testing.T) {
949+
assert.Equal(t, tt.expected, deriveStubName(tt.input))
950+
})
951+
}
952+
}
953+
954+
func TestGenerateInterface_StubPrimitiveReturn(t *testing.T) {
955+
doc := parseAIDL(t, `
956+
package test;
957+
interface ICounter {
958+
int getCount();
959+
void setCount(int count);
960+
}
961+
`)
962+
963+
require.Len(t, doc.Definitions, 1)
964+
decl := doc.Definitions[0].(*aidlparser.InterfaceDecl)
965+
966+
src, err := GenerateInterface(decl, "test", "test.ICounter")
967+
require.NoError(t, err)
968+
969+
assertValidGo(t, src)
970+
assertFormattedGo(t, src)
971+
972+
srcStr := string(src)
973+
974+
// Stub struct and compliance.
975+
assert.Contains(t, srcStr, "type CounterStub struct")
976+
assert.Contains(t, srcStr, "Impl ICounter")
977+
assert.Contains(t, srcStr, "var _ binder.TransactionReceiver = (*CounterStub)(nil)")
978+
979+
// OnTransaction dispatcher.
980+
assert.Contains(t, srcStr, "func (s *CounterStub) OnTransaction(")
981+
assert.Contains(t, srcStr, "case TransactionICounterGetCount:")
982+
assert.Contains(t, srcStr, "case TransactionICounterSetCount:")
983+
984+
// GetCount: calls impl and writes result.
985+
assert.Contains(t, srcStr, "s.Impl.GetCount(ctx)")
986+
assert.Contains(t, srcStr, "_reply.WriteInt32(_result)")
987+
988+
// SetCount: reads param from data, calls impl.
989+
assert.Contains(t, srcStr, "s.Impl.SetCount(ctx, _arg_count)")
990+
}
991+
992+
func TestGenerateInterface_StubOneway(t *testing.T) {
993+
doc := parseAIDL(t, `
994+
package test;
995+
oneway interface INotify {
996+
void onEvent(int eventId, String detail);
997+
}
998+
`)
999+
1000+
require.Len(t, doc.Definitions, 1)
1001+
decl := doc.Definitions[0].(*aidlparser.InterfaceDecl)
1002+
1003+
src, err := GenerateInterface(decl, "test", "test.INotify")
1004+
require.NoError(t, err)
1005+
1006+
assertValidGo(t, src)
1007+
assertFormattedGo(t, src)
1008+
1009+
srcStr := string(src)
1010+
1011+
// Oneway stubs return nil, nil (no reply).
1012+
assert.Contains(t, srcStr, "type NotifyStub struct")
1013+
assert.Contains(t, srcStr, "return nil, nil")
1014+
assert.Contains(t, srcStr, "s.Impl.OnEvent(ctx, _arg_eventId, _arg_detail)")
1015+
}
1016+
1017+
func TestGenerateInterface_StubNoMethods(t *testing.T) {
1018+
doc := parseAIDL(t, `
1019+
package test;
1020+
interface IEmpty {
1021+
}
1022+
`)
1023+
1024+
require.Len(t, doc.Definitions, 1)
1025+
decl := doc.Definitions[0].(*aidlparser.InterfaceDecl)
1026+
1027+
src, err := GenerateInterface(decl, "test", "test.IEmpty")
1028+
require.NoError(t, err)
1029+
1030+
assertValidGo(t, src)
1031+
1032+
srcStr := string(src)
1033+
1034+
// Stub is still generated for empty interfaces.
1035+
assert.Contains(t, srcStr, "type EmptyStub struct")
1036+
assert.Contains(t, srcStr, "Impl IEmpty")
1037+
}
1038+
1039+
func TestGenerateInterface_StubVoidNoParams(t *testing.T) {
1040+
doc := parseAIDL(t, `
1041+
package test;
1042+
interface IPing {
1043+
void ping();
1044+
}
1045+
`)
1046+
1047+
require.Len(t, doc.Definitions, 1)
1048+
decl := doc.Definitions[0].(*aidlparser.InterfaceDecl)
1049+
1050+
src, err := GenerateInterface(decl, "test", "test.IPing")
1051+
require.NoError(t, err)
1052+
1053+
assertValidGo(t, src)
1054+
assertFormattedGo(t, src)
1055+
1056+
srcStr := string(src)
1057+
1058+
assert.Contains(t, srcStr, "type PingStub struct")
1059+
// void + no params: should use := for _err since it's the first declaration.
1060+
assert.Contains(t, srcStr, "s.Impl.Ping(ctx)")
1061+
}

0 commit comments

Comments
 (0)