Skip to content

Commit 4a31cc0

Browse files
committed
[C#] respect the package override option for C# codecs and DTOs
1 parent b385e9c commit 4a31cc0

File tree

7 files changed

+146
-43
lines changed

7 files changed

+146
-43
lines changed

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharp.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import uk.co.real_logic.sbe.generation.TargetCodeGeneratorLoader;
2222
import uk.co.real_logic.sbe.ir.Ir;
2323

24+
import static uk.co.real_logic.sbe.SbeTool.TYPES_PACKAGE_OVERRIDE;
25+
2426
/**
2527
* {@link CodeGenerator} factory for the CSharp target programming language.
2628
*/
@@ -33,15 +35,19 @@ public class CSharp implements TargetCodeGenerator
3335
*/
3436
public CodeGenerator newInstance(final Ir ir, final String outputDir)
3537
{
38+
final boolean shouldSupportTypesPackageNames = Boolean.getBoolean(TYPES_PACKAGE_OVERRIDE);
3639
final CSharpGenerator flyweightGenerator = new CSharpGenerator(
3740
ir,
3841
TargetCodeGeneratorLoader.precedenceChecks(),
42+
shouldSupportTypesPackageNames,
3943
new CSharpNamespaceOutputManager(outputDir, ir.applicableNamespace()));
4044

4145
if (GENERATE_DTOS)
4246
{
43-
final CSharpDtoGenerator dtoGenerator =
44-
new CSharpDtoGenerator(ir, new CSharpNamespaceOutputManager(outputDir, ir.applicableNamespace()));
47+
final CSharpDtoGenerator dtoGenerator = new CSharpDtoGenerator(
48+
ir,
49+
shouldSupportTypesPackageNames,
50+
new CSharpNamespaceOutputManager(outputDir, ir.applicableNamespace()));
4551

4652
return () ->
4753
{

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpDtoGenerator.java

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import java.io.IOException;
3131
import java.io.Writer;
3232
import java.util.ArrayList;
33+
import java.util.HashSet;
3334
import java.util.List;
35+
import java.util.Set;
3436
import java.util.function.Predicate;
3537

3638
import static uk.co.real_logic.sbe.generation.csharp.CSharpUtil.*;
@@ -49,27 +51,65 @@ public class CSharpDtoGenerator implements CodeGenerator
4951

5052
private final Ir ir;
5153
private final OutputManager outputManager;
54+
private final boolean shouldSupportTypesPackageNames;
55+
private final Set<String> packageNameByTypes = new HashSet<>();
5256

5357
/**
5458
* Create a new C# DTO {@link CodeGenerator}.
5559
*
5660
* @param ir for the messages and types.
61+
* @param shouldSupportTypesPackageNames generator support for types in their own package.
5762
* @param outputManager for generating the DTOs to.
5863
*/
59-
public CSharpDtoGenerator(final Ir ir, final OutputManager outputManager)
64+
public CSharpDtoGenerator(
65+
final Ir ir,
66+
final boolean shouldSupportTypesPackageNames,
67+
final OutputManager outputManager)
6068
{
6169
Verify.notNull(ir, "ir");
6270
Verify.notNull(outputManager, "outputManager");
6371

6472
this.ir = ir;
73+
this.shouldSupportTypesPackageNames = shouldSupportTypesPackageNames;
6574
this.outputManager = outputManager;
6675
}
6776

77+
private String fetchTypesPackageName(final Token token, final Ir ir)
78+
{
79+
if (!shouldSupportTypesPackageNames)
80+
{
81+
return ir.applicableNamespace();
82+
}
83+
84+
if (token.packageName() != null)
85+
{
86+
return token.packageName();
87+
}
88+
89+
return ir.applicableNamespace();
90+
}
91+
6892
/**
6993
* {@inheritDoc}
7094
*/
7195
public void generate() throws IOException
7296
{
97+
packageNameByTypes.clear();
98+
99+
if (shouldSupportTypesPackageNames)
100+
{
101+
for (final List<Token> tokens : ir.types())
102+
{
103+
final Token token = tokens.get(0);
104+
final String packageName = token.packageName();
105+
106+
if (packageName != null)
107+
{
108+
packageNameByTypes.add(packageName);
109+
}
110+
}
111+
}
112+
73113
generateDtosForTypes();
74114

75115
for (final List<Token> tokens : ir.messages())
@@ -110,7 +150,8 @@ public void generate() throws IOException
110150
try (Writer out = outputManager.createOutput(dtoClassName))
111151
{
112152
out.append(generateFileHeader(
113-
ir.applicableNamespace(),
153+
fetchTypesPackageName(msgToken, ir),
154+
packageNameByTypes,
114155
"#nullable enable\n\n",
115156
"using System.Collections.Generic;\n",
116157
"using System.Linq;\n"));
@@ -1360,13 +1401,16 @@ private void generateDtosForTypes() throws IOException
13601401

13611402
private void generateComposite(final List<Token> tokens) throws IOException
13621403
{
1363-
final String name = tokens.get(0).applicableTypeName();
1404+
final Token token = tokens.get(0);
1405+
final String name = token.applicableTypeName();
13641406
final String className = formatDtoClassName(name);
13651407
final String codecClassName = formatClassName(name);
13661408

13671409
try (Writer out = outputManager.createOutput(className))
13681410
{
1369-
out.append(generateFileHeader(ir.applicableNamespace(),
1411+
out.append(generateFileHeader(
1412+
fetchTypesPackageName(token, ir),
1413+
packageNameByTypes,
13701414
"#nullable enable\n",
13711415
"using System.Collections.Generic;\n",
13721416
"using System.Linq;\n"));

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpDtos.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,6 @@ public class CSharpDtos implements TargetCodeGenerator
3030
*/
3131
public CodeGenerator newInstance(final Ir ir, final String outputDir)
3232
{
33-
return new CSharpDtoGenerator(ir, new CSharpNamespaceOutputManager(outputDir, ir.applicableNamespace()));
33+
return new CSharpDtoGenerator(ir, false, new CSharpNamespaceOutputManager(outputDir, ir.applicableNamespace()));
3434
}
3535
}

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpGenerator.java

Lines changed: 49 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public class CSharpGenerator implements CodeGenerator
6060
private final OutputManager outputManager;
6161
private final PrecedenceChecks precedenceChecks;
6262
private final String precedenceChecksFlagName;
63+
private final boolean shouldSupportTypesPackageNames;
64+
private final Set<String> packageNameByTypes = new HashSet<>();
6365

6466
/**
6567
* Create a new C# language {@link CodeGenerator}.
@@ -72,20 +74,23 @@ public CSharpGenerator(final Ir ir, final OutputManager outputManager)
7274
this(
7375
ir,
7476
PrecedenceChecks.newInstance(new PrecedenceChecks.Context()),
77+
false,
7578
outputManager
7679
);
7780
}
7881

7982
/**
8083
* Create a new C# language {@link CodeGenerator}.
8184
*
82-
* @param ir for the messages and types.
83-
* @param precedenceChecks whether and how to perform field precedence checks.
84-
* @param outputManager for generating the codecs to.
85+
* @param ir for the messages and types.
86+
* @param precedenceChecks whether and how to perform field precedence checks.
87+
* @param shouldSupportTypesPackageNames generator support for types in their own package.
88+
* @param outputManager for generating the codecs to.
8589
*/
8690
public CSharpGenerator(
8791
final Ir ir,
8892
final PrecedenceChecks precedenceChecks,
93+
final boolean shouldSupportTypesPackageNames,
8994
final OutputManager outputManager)
9095
{
9196
Verify.notNull(ir, "ir");
@@ -94,6 +99,7 @@ public CSharpGenerator(
9499
this.ir = ir;
95100
this.precedenceChecks = precedenceChecks;
96101
this.precedenceChecksFlagName = precedenceChecks.context().precedenceChecksFlagName();
102+
this.shouldSupportTypesPackageNames = shouldSupportTypesPackageNames;
97103
this.outputManager = outputManager;
98104
}
99105

@@ -138,11 +144,42 @@ public void generateTypeStubs() throws IOException
138144
}
139145
}
140146

147+
private String fetchTypesPackageName(final Token token, final Ir ir)
148+
{
149+
if (!shouldSupportTypesPackageNames)
150+
{
151+
return ir.applicableNamespace();
152+
}
153+
154+
if (token.packageName() != null)
155+
{
156+
return token.packageName();
157+
}
158+
159+
return ir.applicableNamespace();
160+
}
161+
141162
/**
142163
* {@inheritDoc}
143164
*/
144165
public void generate() throws IOException
145166
{
167+
packageNameByTypes.clear();
168+
169+
if (shouldSupportTypesPackageNames)
170+
{
171+
for (final List<Token> tokens : ir.types())
172+
{
173+
final Token token = tokens.get(0);
174+
final String packageName = token.packageName();
175+
176+
if (packageName != null)
177+
{
178+
packageNameByTypes.add(packageName);
179+
}
180+
}
181+
}
182+
146183
generateMessageHeaderStub();
147184
generateTypeStubs();
148185

@@ -164,7 +201,7 @@ public void generate() throws IOException
164201
final List<Token> varData = new ArrayList<>();
165202
collectVarData(messageBody, offset, varData);
166203

167-
out.append(generateFileHeader(ir.applicableNamespace()));
204+
out.append(generateFileHeader(fetchTypesPackageName(msgToken, ir), packageNameByTypes));
168205
out.append(generateDocumentation(BASE_INDENT, msgToken));
169206
out.append(generateClassDeclaration(className));
170207
out.append(generateMessageFlyweightCode(className, msgToken, fieldPrecedenceModel, BASE_INDENT));
@@ -662,7 +699,7 @@ private void generateBitSet(final List<Token> tokens) throws IOException
662699

663700
try (Writer out = outputManager.createOutput(enumName))
664701
{
665-
out.append(generateFileHeader(ir.applicableNamespace()));
702+
out.append(generateFileHeader(fetchTypesPackageName(enumToken, ir), packageNameByTypes));
666703
out.append(generateDocumentation(INDENT, enumToken));
667704
final String enumPrimitiveType = cSharpTypeName(enumToken.encoding().primitiveType());
668705
out.append(generateEnumDeclaration(enumName, enumPrimitiveType, true));
@@ -682,7 +719,7 @@ private void generateEnum(final List<Token> tokens) throws IOException
682719

683720
try (Writer out = outputManager.createOutput(enumName))
684721
{
685-
out.append(generateFileHeader(ir.applicableNamespace()));
722+
out.append(generateFileHeader(fetchTypesPackageName(enumToken, ir), packageNameByTypes));
686723
out.append(generateDocumentation(INDENT, enumToken));
687724
final String enumPrimitiveType = cSharpTypeName(enumToken.encoding().primitiveType());
688725
out.append(generateEnumDeclaration(enumName, enumPrimitiveType, false));
@@ -696,14 +733,15 @@ private void generateEnum(final List<Token> tokens) throws IOException
696733

697734
private void generateComposite(final List<Token> tokens) throws IOException
698735
{
699-
final String compositeName = CSharpUtil.formatClassName(tokens.get(0).applicableTypeName());
736+
final Token token = tokens.get(0);
737+
final String compositeName = CSharpUtil.formatClassName(token.applicableTypeName());
700738

701739
try (Writer out = outputManager.createOutput(compositeName))
702740
{
703-
out.append(generateFileHeader(ir.applicableNamespace()));
704-
out.append(generateDocumentation(INDENT, tokens.get(0)));
741+
out.append(generateFileHeader(fetchTypesPackageName(token, ir), packageNameByTypes));
742+
out.append(generateDocumentation(INDENT, token));
705743
out.append(generateClassDeclaration(compositeName));
706-
out.append(generateFixedFlyweightCode(tokens.get(0).encodedLength()));
744+
out.append(generateFixedFlyweightCode(token.encodedLength()));
707745
out.append(generateCompositePropertyElements(tokens.subList(1, tokens.size() - 1), BASE_INDENT));
708746

709747
out.append(generateCompositeDisplay(tokens));
@@ -798,7 +836,7 @@ private void generateMetaAttributeEnum() throws IOException
798836
{
799837
try (Writer out = outputManager.createOutput(META_ATTRIBUTE_ENUM))
800838
{
801-
out.append(generateFileHeader(ir.applicableNamespace()));
839+
out.append(generateFileHeader(ir.applicableNamespace(), null));
802840

803841
out.append(
804842
INDENT + "public enum MetaAttribute\n" +

sbe-tool/src/main/java/uk/co/real_logic/sbe/generation/csharp/CSharpUtil.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import java.util.EnumMap;
2626
import java.util.Map;
27+
import java.util.Set;
2728

2829
/**
2930
* Utilities for mapping between IR and the C# language.
@@ -87,8 +88,26 @@ static String generateLiteral(final PrimitiveType type, final String value)
8788
return literal;
8889
}
8990

90-
static CharSequence generateFileHeader(final String packageName, final String... topLevelStatements)
91+
static CharSequence generateFileHeader(
92+
final String packageName,
93+
final Set<String> packageNamesByTypes,
94+
final String... topLevelStatements)
9195
{
96+
final StringBuilder additionalUsingBuilder = new StringBuilder();
97+
if (packageNamesByTypes != null && !packageNamesByTypes.isEmpty())
98+
{
99+
packageNamesByTypes
100+
.stream()
101+
.filter(p -> !packageName.equals(p))
102+
.forEach(p ->
103+
additionalUsingBuilder
104+
.append("using ")
105+
.append(formatNamespace(p))
106+
.append(";\n"));
107+
108+
additionalUsingBuilder.append("\n");
109+
}
110+
92111
return String.format(
93112
"// <auto-generated>\n" +
94113
"// Generated SBE (Simple Binary Encoding) message codec\n" +
@@ -98,9 +117,11 @@ static CharSequence generateFileHeader(final String packageName, final String...
98117
"using System;\n" +
99118
"using System.Text;\n" +
100119
"using Org.SbeTool.Sbe.Dll;\n\n" +
101-
"namespace %2$s\n" +
120+
"%2$s" +
121+
"namespace %3$s\n" +
102122
"{\n",
103123
String.join("", topLevelStatements),
124+
additionalUsingBuilder,
104125
formatNamespace(packageName));
105126
}
106127

sbe-tool/src/propertyTest/java/uk/co/real_logic/sbe/properties/DtosPropertyTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void csharpDtoEncodeShouldBeTheInverseOfDtoDecode(
152152
{
153153
new CSharpGenerator(encodedMessage.ir(), outputManager)
154154
.generate();
155-
new CSharpDtoGenerator(encodedMessage.ir(), outputManager)
155+
new CSharpDtoGenerator(encodedMessage.ir(), false, outputManager)
156156
.generate();
157157
}
158158
catch (final Exception generationException)

0 commit comments

Comments
 (0)