Skip to content

Commit 686ddbe

Browse files
authored
Merge pull request #309 from hypfvieh/codegen2
Codegen2
2 parents e15e061 + 11adcd0 commit 686ddbe

12 files changed

Lines changed: 671 additions & 45 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ The library will remain open source and MIT licensed and can still be used, fork
9090
- Fixed possible NullPointerException in SASL auth ([#294](https://github.com/hypfvieh/dbus-java/issues/294))
9191
- Fixed SASL authentication issue when running in server mode in combination with unix sockets ([#298](https://github.com/hypfvieh/dbus-java/issues/298))
9292
- Fixed various issues with `InterfaceCodeGenerator` ([#302](https://github.com/hypfvieh/dbus-java/issues/302), [#303](https://github.com/hypfvieh/dbus-java/issues/303), [#304], (https://github.com/hypfvieh/dbus-java/issues/304), [#306](https://github.com/hypfvieh/dbus-java/issues/306)
93+
- Refactoring and overhaul of `InterfaceCodeGenerator` to improve code, reduce duplications and allow easier fixing/extending
9394

9495
##### Changes in 5.2.0 (2025-12-21):
9596
- removed properties from dbus-java.version which causes issues with reproducable builds ([PR#279](https://github.com/hypfvieh/dbus-java/issues/279))

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/InterfaceCodeGenerator.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ private List<ClassBuilderInfo> extractSignals(Element _signalElement, ClassBuild
270270

271271
}
272272

273-
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, className);
273+
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, 0, className);
274274

275275
classConstructor.getArguments().addAll(argsList);
276276
classConstructor.getThrowArguments().add(DBusException.class.getSimpleName());
@@ -487,7 +487,7 @@ private List<ClassBuilderInfo> extractProperties(Element _propertyElement, Class
487487
if (DBusProperty.Access.WRITE.getAccessName().equals(attrAccess)
488488
|| DBusProperty.Access.READ_WRITE.getAccessName().equals(attrAccess)) {
489489

490-
ClassMethod classMethod = new SetterMethod(_clzBldr, attrName, rtnType);
490+
ClassMethod classMethod = new SetterMethod(_clzBldr, 0, attrName, rtnType);
491491
classMethod.getArguments().add(new MemberOrArgument(_clzBldr, attrName.substring(0, 1).toLowerCase()
492492
+ attrName.substring(1), clzzName));
493493
_clzBldr.getMethods().add(classMethod);
@@ -544,10 +544,10 @@ private String createTuple(List<MemberOrArgument> _outputArgs, String _className
544544
genericTypes.put(genericName, entry.getType());
545545
entry.getAnnotations().add(new AnnotationInfo(Position.class, AnnotArgs.create().add(position++)));
546546
entry.setType(genericName);
547-
cnstrctArgs.add(new MemberOrArgument(_parentClzBldr, entry.getName(), genericName));
547+
cnstrctArgs.add(new MemberOrArgument(info, entry.getName(), genericName));
548548
}
549549

550-
ClassConstructor cnstrct = new ClassConstructor(_parentClzBldr, _className);
550+
ClassConstructor cnstrct = new ClassConstructor(info, 0, _className);
551551
cnstrct.getArguments().addAll(cnstrctArgs);
552552

553553
info.getConstructors().add(cnstrct);
@@ -609,7 +609,7 @@ private String buildStructClass(List<DuoData> _dbusTypeStr, String _structName,
609609
root.setExtendClass(Struct.class.getName());
610610
root.setClassType(ClassType.CLASS);
611611

612-
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, className);
612+
ClassConstructor classConstructor = new ClassConstructor(_clzBldr, 0, className);
613613
root.getConstructors().add(classConstructor);
614614

615615
String structFqcn = _clzBldr.getPackageName() + "." + Util.upperCaseFirstChar(_structName);

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/StructTreeBuilder.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ public String buildStructClasses(String _dbusSig, String _structBaseFqcn, ClassB
9393
}
9494

9595
if (!treeItem.getSubType().isEmpty()) {
96-
createNested(treeItem.getSubType(), _structBaseFqcn, root, _generatedClasses);
96+
createNested(1, treeItem.getSubType(), _structBaseFqcn, root, _generatedClasses);
9797
}
9898
}
9999

@@ -123,19 +123,20 @@ static String findNextStructFqcn(String _structFqcn, Set<String> _generatedStruc
123123
/**
124124
* Create nested Struct class.
125125
*
126+
* @param _nestedLevel nested depth level
126127
* @param _list List of struct tree elements
127128
* @param _structFqcnBase base classname of created struct class
128129
* @param _root root class of this struct (maybe other struct)
129130
* @param _classes a list, this will contain additional struct classes created, if any. Should never be null!
130131
*
131132
* @return last created struct or null
132133
*/
133-
private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcnBase, ClassBuilderInfo _root, List<ClassBuilderInfo> _classes) {
134+
private ClassBuilderInfo createNested(int _nestedLevel, List<StructTree> _list, String _structFqcnBase, ClassBuilderInfo _root, List<ClassBuilderInfo> _classes) {
134135
int position = 0;
135136

136137
ClassBuilderInfo root = _root;
137138
ClassBuilderInfo retval = null;
138-
ClassConstructor classConstructor = new ClassConstructor(_root, root.getClassName());
139+
ClassConstructor classConstructor = new ClassConstructor(_root, _nestedLevel, root.getClassName());
139140

140141
for (StructTree inTree : _list) {
141142

@@ -158,7 +159,7 @@ private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcn
158159
temp.setClassType(ClassType.CLASS);
159160
classConstructor.getArguments().add(new MemberOrArgument(_root, constructorArg, temp.getClassName()));
160161
member.setType(temp.getClassName());
161-
createNested(inTree.getSubType(), _structFqcnBase, temp, _classes);
162+
createNested(_nestedLevel + 1, inTree.getSubType(), _structFqcnBase, temp, _classes);
162163

163164
_classes.add(temp);
164165
retval = temp;
@@ -167,7 +168,7 @@ private ClassBuilderInfo createNested(List<StructTree> _list, String _structFqcn
167168

168169
temp.setClassName(root.getClassName());
169170
temp.setPackageName(root.getPackageName());
170-
ClassBuilderInfo x = createNested(inTree.getSubType(), _structFqcnBase, temp, _classes);
171+
ClassBuilderInfo x = createNested(_nestedLevel + 1, inTree.getSubType(), _structFqcnBase, temp, _classes);
171172
if (x != null) {
172173
member.getGenerics().add(x.getClassName());
173174
} else {

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/ClassBuilderInfo.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,13 +253,12 @@ private List<String> createClassFileContent(boolean _staticClass, Set<String> _o
253253
}
254254
}
255255

256+
List<ClassMethod> allMethods = new ArrayList<>(getMethods());
257+
256258
// add getter and setter
257-
for (MemberOrArgument member : members) {
258-
addEmptyLineIfNeeded(content);
259-
content.addAll(member.generate(memberIndentCnt));
260-
}
259+
getMembers().stream().map(e -> e.generateMethods(memberIndentCnt)).forEach(allMethods::addAll);
261260

262-
for (ClassMethod mth : getMethods()) {
261+
for (ClassMethod mth : allMethods) {
263262
addEmptyLineIfNeeded(content);
264263
content.addAll(mth.generate(memberIndentCnt));
265264
}

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/ClassConstructor.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ public class ClassConstructor implements ICodeGenerator {
2929
private final ClassBuilderInfo classBuilderInfo;
3030

3131
private final String className;
32+
private final int indentLevel;
3233

33-
public ClassConstructor(ClassBuilderInfo _bldr, String _className) {
34+
public ClassConstructor(ClassBuilderInfo _bldr, int _indentLevel, String _className) {
3435
classBuilderInfo = _bldr;
3536
className = _className;
37+
indentLevel = _indentLevel;
3638
}
3739

3840
public List<String> getThrowArguments() {
@@ -58,7 +60,7 @@ public ClassBuilderInfo getClassBuilderInfo() {
5860

5961
@Override
6062
public List<String> generate(int _indentLevel) {
61-
63+
int indent = Math.max(indentLevel, _indentLevel);
6264
List<MemberOrArgument> filteredSuperArguments = new ArrayList<>(getSuperArguments());
6365
filteredSuperArguments.removeIf(e -> getArguments().contains(e));
6466
String constructorArgs = "";
@@ -81,22 +83,22 @@ public List<String> generate(int _indentLevel) {
8183
String prefix = getClassBuilderInfo().getArgumentPrefix();
8284

8385
if (!getSuperArguments().isEmpty()) {
84-
assignments = getIndent(_indentLevel / 2) + "super(" + getSuperArguments().stream()
86+
assignments = getIndent(indent / 2) + "super(" + getSuperArguments().stream()
8587
.map(e -> ClassBuilderInfo.maybePrefix(e.getName(), prefix))
8688
.collect(Collectors.joining(", ")) + ");" + System.lineSeparator();
8789
}
8890

8991
if (!getArguments().isEmpty()) {
9092
List<String> assigns = new ArrayList<>();
91-
String innerIndent = getIndent(_indentLevel / 2);
93+
String innerIndent = getIndent(indent);
9294
for (MemberOrArgument e : getArguments()) {
9395
assigns.add(innerIndent + "this." + e.getName() + " = " + ClassBuilderInfo.maybePrefix(e.getName(), prefix) + ";");
9496
}
9597
assignments += String.join(System.lineSeparator(), assigns);
9698
}
9799

98100
return CONSTRUCTOR_TEMPL.formatted(getClassName(), constructorArgs, throwArgs, assignments)
99-
.lines().map(l -> getIndent(_indentLevel) + l).toList();
101+
.lines().map(l -> getIndent(indent) + l).toList();
100102
}
101103

102104
public String argumentsAsString() {

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/ClassMethod.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,9 @@ public List<String> generate(int _indentLevel) {
111111

112112
// add "name" definition if original name differs from reformatted name
113113
// e.g. some-name != someName
114-
if (!reformatName().equals(getName())) {
114+
String reformattedMethodName = reformatName();
115+
if (!reformattedMethodName.equals(getName())
116+
|| !Util.upperCaseFirstChar(getName()).equals(reformattedMethodName)) {
115117
currentAnnotations.stream().filter(e -> e.getAnnotationClass() == DBusBoundProperty.class)
116118
.forEach(e -> e.getAnnotationParams().put("name", getName()));
117119

@@ -126,7 +128,7 @@ public List<String> generate(int _indentLevel) {
126128
result.addAll(currentAnnotations.stream().map(a -> getIndent(_indentLevel) + a.getAnnotationString()).toList());
127129
}
128130

129-
String publicModifier = getClassBuilderInfo().getClassType() != ClassType.INTERFACE ? "public " : "";
131+
String publicModifier = getClassBuilderInfo().getClassType() != ClassType.INTERFACE ? "public" : "";
130132
String mthReturnType = getReturnType() == null ? "void"
131133
: TypeConverter.getProperJavaClass(getReturnType(), getClassBuilderInfo().getImports());
132134
String args = "";
@@ -143,7 +145,7 @@ public List<String> generate(int _indentLevel) {
143145
}
144146

145147
protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {
146-
return METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args)
148+
return METHOD_TEMPL.formatted(Util.isBlank(_modifier) ? "" : " " + _modifier, _returnType, _methodName, _args)
147149
.lines().map(l -> getIndent(_indentLvl) + l).toList();
148150
}
149151

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/GetterMethod.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,30 @@ public class GetterMethod extends ClassMethod {
1111
""";
1212
private final MemberOrArgument argument;
1313

14+
private final int indentLevel;
15+
1416
public GetterMethod(ClassBuilderInfo _bldr, String _name, String _returnType) {
15-
this(_bldr, _name, _returnType, null);
17+
this(_bldr, 0, _name, _returnType, null);
1618
}
1719

18-
public GetterMethod(ClassBuilderInfo _bldr, String _name, String _returnType, MemberOrArgument _arguments) {
20+
public GetterMethod(ClassBuilderInfo _bldr, int _indentLevel, String _name, String _returnType, MemberOrArgument _arguments) {
1921
super(_bldr, _name, _returnType, "boolean".equalsIgnoreCase(_returnType) ? "is" : "get", false);
2022
this.argument = _arguments;
23+
this.indentLevel = _indentLevel;
2124
}
2225

2326
@Override
2427
protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {
25-
28+
int indent = Math.max(_indentLvl, indentLevel);
2629
if (argument == null) {
27-
return super.formatMethod(_indentLvl, _modifier, _returnType, _methodName, _args);
30+
return super.formatMethod(indent, _modifier, _returnType, _methodName, _args);
2831
}
2932

3033
String content = String.format("return %s;", argument.getName());
3134

32-
return GETTER_METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args,
33-
getIndent(Math.min(1, _indentLvl - 1)), content)
34-
.lines().map(l -> getIndent(_indentLvl) + l).toList();
35+
return GETTER_METHOD_TEMPL.formatted("public ", _returnType, _methodName, _args,
36+
getIndent(indent), content)
37+
.lines().map(l -> getIndent(indent) + l).toList();
3538
}
3639

3740
}

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/MemberOrArgument.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* @author hypfvieh
1515
* @since v3.0.1 - 2018-12-20
1616
*/
17-
public class MemberOrArgument implements ICodeGenerator {
17+
public class MemberOrArgument {
1818

1919
/** Name of member/field. */
2020
private final String name;
@@ -78,25 +78,25 @@ public String getFullType(Set<String> _allImports) {
7878
return sb.toString();
7979
}
8080

81-
@Override
8281
public ClassBuilderInfo getClassBuilderInfo() {
8382
return classBuilderInfo;
8483
}
8584

86-
@Override
87-
public List<String> generate(int _indentLevel) {
88-
List<String> result = new ArrayList<>();
85+
public List<ClassMethod> generateMethods(int _indentLevel) {
86+
List<ClassMethod> result = new ArrayList<>();
8987
String memberType = TypeConverter.getProperJavaClass(getType(), getClassBuilderInfo().getImports());
9088

9189
if (!getGenerics().isEmpty()) {
92-
memberType += "<" + getGenerics().stream().map(c -> TypeConverter.convertJavaType(c, false)).collect(Collectors.joining(", ")) + ">";
90+
memberType += "<" + getGenerics().stream()
91+
.map(c -> TypeConverter.convertJavaType(c, false))
92+
.collect(Collectors.joining(", ")) + ">";
9393
}
9494

95-
GetterMethod getterMethod = new GetterMethod(getClassBuilderInfo(), getName(), memberType, this);
95+
GetterMethod getterMethod = new GetterMethod(getClassBuilderInfo(), _indentLevel, getName(), memberType, this);
96+
result.add(getterMethod);
9697

97-
getClassBuilderInfo().getMethods().add(getterMethod);
9898
if (!isFinalArg()) {
99-
getClassBuilderInfo().getMethods().add(new SetterMethod(getClassBuilderInfo(), getName(), memberType));
99+
result.add(new SetterMethod(getClassBuilderInfo(), _indentLevel, getName(), memberType));
100100
}
101101

102102
return result;

dbus-java-utils/src/main/java/org/freedesktop/dbus/utils/generator/type/SetterMethod.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,26 @@ public class SetterMethod extends ClassMethod {
99
%s%s
1010
}
1111
""";
12+
private final int indentLevel;
1213

13-
public SetterMethod(ClassBuilderInfo _bldr, String _name, String _setterType) {
14+
public SetterMethod(ClassBuilderInfo _bldr, int _indentLevel, String _name, String _setterType) {
1415
super(_bldr, _name, "void", "set", false);
16+
indentLevel = _indentLevel;
1517
getArguments().add(new MemberOrArgument(_bldr, _name, _setterType));
1618
}
1719

1820
@Override
1921
protected List<String> formatMethod(int _indentLvl, String _modifier, String _returnType, String _methodName, String _args) {
22+
int indent = Math.max(indentLevel, _indentLvl);
2023

2124
if (getArguments() == null || getArguments().isEmpty()) {
22-
return super.formatMethod(_indentLvl, _modifier, _returnType, _methodName, _args);
25+
return super.formatMethod(indent, _modifier, _returnType, _methodName, _args);
2326
}
2427

2528
String content = String.format("this.%s = %s;", getArguments().getFirst().getName(), getArguments().getFirst().getName());
2629

27-
return SETTER_METHOD_TEMPL.formatted(_modifier, _returnType, _methodName, _args,
28-
getIndent(Math.min(1, _indentLvl - 1)), content)
29-
.lines().map(l -> getIndent(_indentLvl) + l).toList();
30+
return SETTER_METHOD_TEMPL.formatted("public ", _returnType, _methodName, _args,
31+
getIndent(indent), content)
32+
.lines().map(l -> getIndent(indent) + l).toList();
3033
}
3134
}

dbus-java-utils/src/test/java/org/freedesktop/dbus/utils/generator/InterfaceCodeGeneratorTest.java

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void testHandleKebabCase() throws Exception {
8787
assertLineEquals(12, clzContent, " @DBusBoundProperty(name = \"power-saver-enabled\")");
8888
assertLineEquals(13, clzContent, " boolean isPowerSaverEnabled();");
8989

90-
assertLineEquals(15, clzContent, " @DBusBoundProperty");
90+
assertLineEquals(15, clzContent, " @DBusBoundProperty(name = \"version\")");
9191
assertLineEquals(16, clzContent, " UInt32 getVersion();");
9292
}
9393

@@ -168,6 +168,65 @@ void testIssue306() throws Exception {
168168
assertLineEquals(22, clzContent, " @DBusBoundProperty(type = PropertySupportedOptionsType.class)");
169169
}
170170

171+
@Test
172+
void testStructFormatting() throws Exception {
173+
InterfaceCodeGenerator ci2 = loadDBusXmlFile(true,
174+
new File("src/test/resources/CreateInterface/xdg-desktop/org.freedesktop.portal.Usb.xml"),
175+
"/", "org.freedesktop.portal.Usb");
176+
Map<File, String> analyze = ci2.analyze(true);
177+
178+
assertEquals(6, analyze.size());
179+
180+
String clzContent = analyze.entrySet().stream()
181+
.filter(e -> e.getKey().getName().equals("AcquireDevicesDevicesStruct.java"))
182+
.findFirst()
183+
.map(e -> e.getValue())
184+
.orElseThrow();
185+
186+
assertLineEquals(16, clzContent, " public AcquireDevicesDevicesStruct(String member0, Map<String, Variant<?>> member1) {");
187+
assertLineEquals(17, clzContent, " this.member0 = member0;");
188+
assertLineEquals(18, clzContent, " this.member1 = member1;");
189+
190+
assertLineEquals(21, clzContent, " public String getMember0() {");
191+
assertLineEquals(22, clzContent, " return member0;");
192+
193+
assertLineEquals(25, clzContent, " public Map<String, Variant<?>> getMember1() {");
194+
assertLineEquals(26, clzContent, " return member1;");
195+
}
196+
197+
@Test
198+
void testTupleFormatting() throws Exception {
199+
InterfaceCodeGenerator ci2 = loadDBusXmlFile(true,
200+
new File("src/test/resources/CreateInterface/xdg-desktop/org.freedesktop.portal.Documents.xml"),
201+
"/", "org.freedesktop.portal.Documents");
202+
Map<File, String> analyze = ci2.analyze(true);
203+
204+
assertEquals(4, analyze.size());
205+
206+
String clzContent = analyze.entrySet().stream()
207+
.filter(e -> e.getKey().getName().equals("AddFullTuple.java"))
208+
.findFirst()
209+
.map(e -> e.getValue())
210+
.orElseThrow();
211+
212+
assertLineEquals(14, clzContent, " public AddFullTuple(A docIds, B extraOut) {");
213+
assertLineEquals(15, clzContent, " this.docIds = docIds;");
214+
assertLineEquals(16, clzContent, " this.extraOut = extraOut;");
215+
216+
assertLineEquals(19, clzContent, " public A getDocIds() {");
217+
assertLineEquals(20, clzContent, " return docIds;");
218+
219+
assertLineEquals(23, clzContent, " public void setDocIds(A docIds) {");
220+
assertLineEquals(24, clzContent, " this.docIds = docIds;");
221+
222+
assertLineEquals(27, clzContent, " public B getExtraOut() {");
223+
assertLineEquals(28, clzContent, " return extraOut;");
224+
225+
assertLineEquals(31, clzContent, " public void setExtraOut(B extraOut) {");
226+
assertLineEquals(32, clzContent, " this.extraOut = extraOut;");
227+
228+
}
229+
171230
@Test
172231
void testCreateSampleStructArgs() throws Exception {
173232
InterfaceCodeGenerator ci2 = loadDBusXmlFile(

0 commit comments

Comments
 (0)