Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(rust): support for alias import in codegen #122

Draft
wants to merge 11 commits into
base: main
Choose a base branch
from
4 changes: 4 additions & 0 deletions lib/codegen/fromcto/csharp/csharpvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,10 @@ class CSharpVisitor {
}
} else if (!field.isPrimitive()) {
let fqn = this.getDotNetNamespaceOfType(field.getFullyQualifiedTypeName(), field.getParent(), parameters);
const modelFile = field.getModelFile();
if (modelFile?.isImportedType(fieldType)) {
fieldType = modelFile.getImportedType(fieldType);
}
fieldType = `${fqn}${fieldType}`;
}

Expand Down
11 changes: 8 additions & 3 deletions lib/codegen/fromcto/java/javavisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,14 @@ class JavaVisitor {
if(field.isArray()) {
array = '[]';
}

const fieldType = this.toJavaType(field.getType()) + array;

let fieldType = field.getType();
if (!ModelUtil.isPrimitiveType(fieldType)) {
const modelFile = field.getModelFile();
if (modelFile?.isImportedType(fieldType)) {
fieldType = modelFile.getImportedType(fieldType);
}
}
fieldType = this.toJavaType(fieldType) + array;
const fieldName = field.getName();
const getterName = 'get' + this.capitalizeFirstLetter(fieldName);
const setterName = 'set' + this.capitalizeFirstLetter(fieldName);
Expand Down
11 changes: 10 additions & 1 deletion lib/codegen/fromcto/rust/rustvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,16 @@ class RustVisitor {
* @private
*/
visitField(field, parameters) {
let type = this.toRustType(field.type);
let type = field.type;
if (!ModelUtil.isPrimitiveType(field.type)) {
const modelFile = field.getModelFile();
if (modelFile?.isImportedType(type)) {
type = modelFile.getImportedType(type);
}
console.log(type);
}
type = this.toRustType(type);

if (field.isArray?.()) {
type = `Vec<${type}>`;
}
Expand Down
48 changes: 42 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@
"webpack-cli": "4.9.1"
},
"dependencies": {
"@accordproject/concerto-core": "3.18.1",

"@accordproject/concerto-core": "3.19.0",
"@accordproject/concerto-util": "3.18.1",
"@accordproject/concerto-vocabulary": "3.18.1",
"@openapi-contrib/openapi-schema-to-json-schema": "5.1.0",
Expand Down
1 change: 1 addition & 0 deletions test/codegen/codegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ describe('codegen', function () {

before(function() {
process.env.ENABLE_MAP_TYPE = 'true'; // TODO Remove on release of MapType
process.env.IMPORT_ALIASING = 'true';
});

beforeEach(function() {
Expand Down
59 changes: 59 additions & 0 deletions test/codegen/fromcto/csharp/csharpvisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -785,6 +785,65 @@ public class SampleModel : Concept {
file1.should.match(/public System.Guid otherThingId/);
file1.should.match(/public string someOtherThingId/);
});

it('should handle imported field which is aliased in a concept', () => {
const modelManager = new ModelManager({ importAliasing: true });
modelManager.addCTOModel(`
namespace org.example.basic
concept file{
o String name
}
`);
modelManager.addCTOModel(`
namespace org.example.complex
import org.example.basic.{file as f}

concept folder {
o String name
o f[] files
}
`);
csharpVisitor.visit(modelManager, { fileWriter });
const files = fileWriter.getFilesInMemory();
const file1 = files.get('org.example.basic.cs');
file1.should.match(/namespace org.example.basic;/);
file1.should.match(/class file : Concept/);
file1.should.match(/public string name { get; set; }/);

const file2 = files.get('org.example.complex.cs');
file2.should.match(/namespace org.example.complex;/);
file2.should.match(/using org.example.basic;/);
file2.should.match(/class folder : Concept/);
file2.should.match(/org.example.basic.file\[\] files/);
});

it('should handle imported field which extended in concept', () => {
const modelManager = new ModelManager({ importAliasing: true });
modelManager.addCTOModel(`
namespace org.example.basic
concept file{
o String name
}
`);
modelManager.addCTOModel(`
namespace org.example.complex
import org.example.basic.{file as f}

concept bigFile extends f{
}
`);
csharpVisitor.visit(modelManager, { fileWriter });
const files = fileWriter.getFilesInMemory();
const file1 = files.get('org.example.basic.cs');
file1.should.match(/namespace org.example.basic;/);
file1.should.match(/class file : Concept/);
file1.should.match(/public string name { get; set; }/);

const file2 = files.get('org.example.complex.cs');
file2.should.match(/namespace org.example.complex;/);
file2.should.match(/using org.example.basic;/);
file2.should.match(/public class bigFile : org.example.basic.file/);
});
});

describe('visit', () => {
Expand Down
24 changes: 23 additions & 1 deletion test/codegen/fromcto/java/javavisitor.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,9 +467,10 @@ describe('JavaVisitor', function () {

const mockField = sinon.createStubInstance(Field);
const getType = sinon.stub();
const isImportedType = sinon.stub();

mockField.ast = { type: { name: 'Dummy Value'} };
mockField.getModelFile.returns({ getType: getType });
mockField.getModelFile.returns({ getType: getType, isImportedType: isImportedType });

const mockMapDeclaration = sinon.createStubInstance(MapDeclaration);
const getKeyType = sinon.stub();
Expand All @@ -481,6 +482,7 @@ describe('JavaVisitor', function () {
getType.returns(mockMapDeclaration);
getKeyType.returns('String');
getValueType.returns('String');
isImportedType.returns(false);
mockField.getName.returns('Map1');
mockMapDeclaration.getName.returns('Map1');
mockMapDeclaration.isMapDeclaration.returns(true);
Expand Down Expand Up @@ -582,6 +584,26 @@ describe('JavaVisitor', function () {
param.fileWriter.writeLine.getCall(1).args.should.deep.equal([2, 'return this.Bob;']);
param.fileWriter.writeLine.getCall(2).args.should.deep.equal([1, '}']);
});

it('should write a line getting a field of type aliased import', () => {
// Document aliased as Doc
let mockField = sinon.createStubInstance(Field);
let mockModelFile = sinon.createStubInstance(ModelFile);

mockField.isField.returns(true);
mockField.isArray.returns(false);
mockField.getName.returns('Bob');
mockField.getType.returns('Doc');
mockField.getModelFile.returns(mockModelFile);
mockModelFile.isImportedType.returns(true);
mockModelFile.getImportedType.returns('Document');

javaVisit.visitField(mockField, Object.assign({}, param, { mode: 'getter' }));
param.fileWriter.writeLine.callCount.should.deep.equal(3);
param.fileWriter.writeLine.getCall(0).args.should.deep.equal([1, 'public Document getBob() {']);
param.fileWriter.writeLine.getCall(1).args.should.deep.equal([2, 'return this.Bob;']);
param.fileWriter.writeLine.getCall(2).args.should.deep.equal([1, '}']);
});
});

describe('visitEnumValueDeclaration', () => {
Expand Down