Skip to content

Commit

Permalink
feat(map): Extend supported Key Types for C# codegen (#71)
Browse files Browse the repository at this point in the history
* feat(*): extend supported key types

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): extend test coverage

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): update snapshot

Signed-off-by: Jonathan Casey <[email protected]>

* feat(*): add type defs

Signed-off-by: Jonathan Casey <[email protected]>

* feat(*): removes unreachable code

Signed-off-by: Jonathan Casey <[email protected]>

* feat(*): cleanup

Signed-off-by: Jonathan Casey <[email protected]>

* test(*): snapshot update

Signed-off-by: Jonathan Casey <[email protected]>

* feat(*): update type def

Signed-off-by: Jonathan Casey <[email protected]>

* feat(*): handles type concerto.scalar.UUID

Signed-off-by: Jonathan Casey <[email protected]>

---------

Signed-off-by: Jonathan Casey <[email protected]>
  • Loading branch information
jonathan-casey authored Jan 25, 2024
1 parent d6d30b3 commit a9e4c3b
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 9 deletions.
38 changes: 34 additions & 4 deletions lib/codegen/fromcto/csharp/csharpvisitor.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-unreachable */
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -312,11 +313,40 @@ class CSharpVisitor {
* @private
*/
writeField(field, parameters, externalFieldType, isOptional = false) {

// write Map field
if (Object.keys(field).length > 0 && ModelUtil.isMap?.(field)) {
const decl = field.getModelFile().getType(field.getType());
parameters.fileWriter.writeLine(1, `public Dictionary<string, ${this.toCSharpType(decl.getValue().getType())}> ${field.getName()} { get; set; }`);
if (ModelUtil.isMap?.(field)) {
const mapDeclaration = field.getModelFile().getType(field.getType());
const mapKeyType = mapDeclaration.getKey().getType();
const mapValueType = mapDeclaration.getValue().getType();

let keyType;
let valueType;

// Map Key
if (ModelUtil.isPrimitiveType(mapKeyType)) {
keyType = this.toCSharpType(mapKeyType);
}
else if (ModelUtil.isScalar(mapDeclaration.getKey())) {
const scalarDeclaration = mapDeclaration.getModelFile().getType(mapDeclaration.getKey().getType());
const keyFQN = ModelUtil.removeNamespaceVersionFromFullyQualifiedName(scalarDeclaration.getFullyQualifiedName());
const scalarType = keyFQN === 'concerto.scalar.UUID' ? keyFQN : scalarDeclaration.getType();
keyType = this.toCSharpType(scalarType);
}

// Map Value
if (ModelUtil.isPrimitiveType(mapValueType)) {
valueType = this.toCSharpType(mapValueType);
}
else if (ModelUtil.isScalar(mapDeclaration.getValue())) {
const scalarDeclaration = mapDeclaration.getModelFile().getType(mapDeclaration.getValue().getType());
const keyFQN = ModelUtil.removeNamespaceVersionFromFullyQualifiedName(scalarDeclaration.getFullyQualifiedName());
const scalarType = keyFQN === 'concerto.scalar.UUID' ? keyFQN : scalarDeclaration.getType();
valueType = this.toCSharpType(scalarType);
} else {
valueType = mapValueType;
}

parameters.fileWriter.writeLine(1, `public Dictionary<${keyType}, ${valueType}> ${field.getName()} { get; set; }`);
return null;
}

Expand Down
8 changes: 4 additions & 4 deletions test/codegen/__snapshots__/codegen.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ public class Company : Concept {
public Dictionary<string, Employee> employeeDirectory { get; set; }
public Dictionary<string, TShirtSizeType> employeeTShirtSizes { get; set; }
public Dictionary<string, Concept> employeeProfiles { get; set; }
public Dictionary<string, SSN> employeeSocialSecurityNumbers { get; set; }
public Dictionary<string, string> employeeSocialSecurityNumbers { get; set; }
}
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
public enum Department {
Expand Down Expand Up @@ -429,7 +429,7 @@ public abstract class Person : Participant {
public string ssn { get; set; }
public float height { get; set; }
public System.DateTime dob { get; set; }
public Dictionary<string, KinTelephone> nextOfKin { get; set; }
public Dictionary<string, string> nextOfKin { get; set; }
}
[AccordProject.Concerto.Type(Namespace = "org.acme.hr", Version = null, Name = "Employee")]
[System.Text.Json.Serialization.JsonConverter(typeof(AccordProject.Concerto.ConcertoConverterFactorySystem))]
Expand Down Expand Up @@ -6499,7 +6499,7 @@ public class Company : Concept {
public Dictionary<string, Employee> employeeDirectory { get; set; }
public Dictionary<string, TShirtSizeType> employeeTShirtSizes { get; set; }
public Dictionary<string, Concept> employeeProfiles { get; set; }
public Dictionary<string, SSN> employeeSocialSecurityNumbers { get; set; }
public Dictionary<string, string> employeeSocialSecurityNumbers { get; set; }
}
[System.Text.Json.Serialization.JsonConverter(typeof(System.Text.Json.Serialization.JsonStringEnumConverter))]
public enum Department {
Expand Down Expand Up @@ -6545,7 +6545,7 @@ public abstract class Person : Participant {
public string ssn { get; set; }
public float height { get; set; }
public System.DateTime dob { get; set; }
public Dictionary<string, KinTelephone> nextOfKin { get; set; }
public Dictionary<string, string> nextOfKin { get; set; }
}
[AccordProject.Concerto.Type(Namespace = "org.acme.hr", Version = "1.0.0", Name = "Employee")]
[System.Text.Json.Serialization.JsonConverter(typeof(AccordProject.Concerto.ConcertoConverterFactorySystem))]
Expand Down
52 changes: 51 additions & 1 deletion test/codegen/fromcto/csharp/csharpvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1445,7 +1445,7 @@ public class SampleModel : Concept {
};
sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
return false;
});

});
Expand Down Expand Up @@ -1509,6 +1509,11 @@ public class SampleModel : Concept {
mockField.dummy = 'Dummy Value';
mockField.getModelFile.returns({ getType: getType });

sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});

const mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
const getKeyType = sinon.stub();
const getValueType = sinon.stub();
Expand All @@ -1533,11 +1538,22 @@ public class SampleModel : Concept {
mockField.dummy = 'Dummy Value';
mockField.getModelFile.returns({ getType: getType });

sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});
sandbox.stub(ModelUtil, 'isScalar').callsFake(() => {
return false;
});

let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
let modelFile = sinon.createStubInstance(ModelFile);
const getKeyType = sinon.stub();
const getValueType = sinon.stub();

mockField.getModelFile.returns(modelFile);
modelFile.getType.returns(mockMapDeclaration);

getType.returns(mockMapDeclaration);
getKeyType.returns('String');
getValueType.returns('Concept');
Expand All @@ -1558,6 +1574,40 @@ public class SampleModel : Concept {
mockField.dummy = 'Dummy Value';
mockField.getModelFile.returns({ getType: getType });

sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});

let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
const getKeyType = sinon.stub();
const getValueType = sinon.stub();

getType.returns(mockMapDeclaration);
getKeyType.returns('String');
getValueType.returns('DateTime');
mockField.getName.returns('Map1');
mockMapDeclaration.getName.returns('Map1');
mockMapDeclaration.isMapDeclaration.returns(true);
mockMapDeclaration.getKey.returns({ getType: getKeyType });
mockMapDeclaration.getValue.returns({ getType: getValueType });

csharpVisitor.visitField(mockField, param);
param.fileWriter.writeLine.withArgs(1, 'public Dictionary<string, System.DateTime> Map1 { get; set; }').calledOnce.should.be.ok;
});

it('should write a line for field name and type thats a map of <SSN, DateTime>', () => {
const mockField = sinon.createStubInstance(Field);
const getType = sinon.stub();

mockField.dummy = 'Dummy Value';
mockField.getModelFile.returns({ getType: getType });

sandbox.restore();
sandbox.stub(ModelUtil, 'isMap').callsFake(() => {
return true;
});

let mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
const getKeyType = sinon.stub();
const getValueType = sinon.stub();
Expand Down

0 comments on commit a9e4c3b

Please sign in to comment.