-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(typescript):alias import for codegen (#124)
* feat(i114): updated the property type-resolution Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(csharp-alias-import): minor bug fixed - Earlier non-imported types gave error. Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(i114): test cases added and minor bug fixed Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(i114): Java visitor updated for aliased import Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import):updating changes Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): Test cases for java-visitor added Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(import-alias): concerto-core version updated and minor changes Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import):Minor bug fixed Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): Pr suggestions Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): visit function updated visitModelFile and visitClassDeclaration updated for the typescriptvisitor.js Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): fixing code Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): Typescript Codegen fixed Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import): test-cases Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(import-alias):Test case updated Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(import-alias): Code refactored Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import):Pr refactoring Signed-off-by: Jaskeerat Singh Saluja <[email protected]> * feat(alias-import):Test cases added Signed-off-by: Jaskeerat Singh Saluja <[email protected]> --------- Signed-off-by: Jaskeerat Singh Saluja <[email protected]> Signed-off-by: Jaskeerat Singh Saluja <[email protected]> Co-authored-by: Jaskeerat Singh Saluja <[email protected]>
- Loading branch information
1 parent
e4968a6
commit b1122fe
Showing
2 changed files
with
131 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -89,6 +89,15 @@ class TypescriptVisitor { | |
// Compute the types we need to import (based on all the types of the properites | ||
// as well as all the super types) for all the classes in this model file | ||
parameters.fileWriter.writeLine(0, '\n// imports'); | ||
const aliasedTypesMap = new Map(); | ||
modelFile.imports.forEach((imp) => { | ||
if (imp.$class === '[email protected]' && imp.aliasedTypes) { | ||
imp.aliasedTypes.forEach(type => { | ||
aliasedTypesMap.set(`${imp.namespace}.I${type.name}`, `I${type.aliasedName}`); | ||
}); | ||
} | ||
}); | ||
|
||
const properties = new Map(); | ||
modelFile.getAllDeclarations() | ||
.filter(declaration => !declaration.isScalarDeclaration?.()) | ||
|
@@ -138,17 +147,25 @@ class TypescriptVisitor { | |
|
||
}); | ||
|
||
modelFile.getImports().map(importString => ModelUtil.getNamespace(importString)).filter(namespace => namespace !== modelFile.getNamespace()) // Skip own namespace. | ||
.filter((v, i, a) => a.indexOf(v) === i) // Remove any duplicates from direct imports | ||
.forEach(namespace => { | ||
const propertyTypeNames = properties.get(namespace); | ||
if (propertyTypeNames) { | ||
const csvPropertyTypeNames = Array.from(propertyTypeNames).join(); | ||
parameters.fileWriter.writeLine(0, `import {${csvPropertyTypeNames}} from './${namespace}';`); | ||
} | ||
}); | ||
const uniqueNamespaces = new Set( | ||
modelFile.getImports() | ||
.map(importString => ModelUtil.getNamespace(importString)) | ||
.filter(namespace => namespace !== modelFile.getNamespace()) | ||
); | ||
uniqueNamespaces.forEach(namespace => { | ||
const propertyTypeNames = properties.get(namespace); | ||
if (propertyTypeNames) { | ||
const csvPropertyTypeNames = Array.from(propertyTypeNames).map(type => { | ||
const fqnType = `${namespace}.${type}`; | ||
return aliasedTypesMap.has(fqnType) ? `${type} as ${aliasedTypesMap.get(fqnType)}` : type; | ||
}).join(','); | ||
|
||
parameters.fileWriter.writeLine(0, `import {${csvPropertyTypeNames}} from './${namespace}';`); | ||
} | ||
}); | ||
|
||
parameters.fileWriter.writeLine(0, '\n// interfaces'); | ||
parameters.aliasedTypesMap = aliasedTypesMap; | ||
modelFile.getAllDeclarations() | ||
.filter(declaration => !declaration.isScalarDeclaration?.()).forEach((decl) => { | ||
decl.accept(this, parameters); | ||
|
@@ -187,13 +204,15 @@ class TypescriptVisitor { | |
*/ | ||
visitClassDeclaration(classDeclaration, parameters) { | ||
|
||
let superType = ' '; | ||
if (classDeclaration.getSuperType()) { | ||
superType = ` extends I${ModelUtil.getShortName(classDeclaration.getSuperType())} `; | ||
let superType = ''; | ||
const type = classDeclaration.getSuperType(); | ||
if (type) { | ||
const namespace = ModelUtil.getNamespace(type); | ||
const shortName = `I${ModelUtil.getShortName(type)}`; | ||
const fullType = `${namespace}.${shortName}`; | ||
superType = ` extends ${parameters.aliasedTypesMap.get(fullType) || shortName}`; | ||
} | ||
|
||
parameters.fileWriter.writeLine(0, 'export interface I' + classDeclaration.getName() + superType + '{'); | ||
|
||
parameters.fileWriter.writeLine(0, `export interface I${classDeclaration.getName()}${superType} {`); | ||
if(!classDeclaration.getSuperType()) { | ||
parameters.fileWriter.writeLine(1, '$class: string;'); | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -232,6 +232,7 @@ describe('TypescriptVisitor', function () { | |
'super.Property3', | ||
'super.Parent' | ||
]); | ||
mockModelFile.imports= []; | ||
|
||
typescriptVisitor.visitModelFile(mockModelFile, param); | ||
|
||
|
@@ -302,7 +303,7 @@ describe('TypescriptVisitor', function () { | |
'org.org2.Import1' | ||
]); | ||
mockModelFile.getModelManager.returns(mockModelManager); | ||
|
||
mockModelFile.imports= []; | ||
typescriptVisitor.visitModelFile(mockModelFile, param); | ||
|
||
param.fileWriter.openFile.withArgs('org.acme.ts').calledOnce.should.be.ok; | ||
|
@@ -358,7 +359,7 @@ describe('TypescriptVisitor', function () { | |
]); | ||
mockModelFile.getImports.returns([]); | ||
mockModelFile.getModelManager.returns(mockModelManager); | ||
|
||
mockModelFile.imports = []; | ||
typescriptVisitor.visitModelFile(mockModelFile, param); | ||
|
||
param.fileWriter.openFile.withArgs('org.acme.ts').calledOnce.should.be.ok; | ||
|
@@ -373,6 +374,71 @@ describe('TypescriptVisitor', function () { | |
|
||
acceptSpy.withArgs(typescriptVisitor, param).calledOnce.should.be.ok; | ||
}); | ||
|
||
it('should write lines for the aliased imports from other namespace ', () => { | ||
|
||
let property1 = { | ||
isPrimitive: () => { | ||
return false; | ||
}, | ||
getFullyQualifiedTypeName: () => { | ||
return 'org.test.basic.file'; | ||
} | ||
}; | ||
|
||
let property2 = { | ||
isPrimitive: () => { | ||
return false; | ||
}, | ||
getFullyQualifiedTypeName: () => { | ||
return 'org.test.complex.file'; | ||
} | ||
}; | ||
|
||
let mockClassDeclaration = sinon.createStubInstance(ClassDeclaration); | ||
|
||
mockClassDeclaration.isClassDeclaration.returns(true); | ||
mockClassDeclaration.getProperties.returns([property1, property2]); | ||
mockClassDeclaration.getNamespace.returns('org.test.collection'); | ||
mockClassDeclaration.getName.returns('folder'); | ||
|
||
mockClassDeclaration.getDirectSubclasses.returns([]); | ||
|
||
let mockModelFile = sinon.createStubInstance(ModelFile); | ||
mockModelFile.getNamespace.returns('org.test.collection'); | ||
mockModelFile.imports = [ | ||
{ | ||
'$class': '[email protected]', | ||
types: ['document', 'file'], | ||
namespace: 'org.test.basic', | ||
aliasedTypes: [ | ||
{ | ||
name: 'file', | ||
aliasedName: 'f' | ||
} | ||
] | ||
}, | ||
{ | ||
'$class': '[email protected]', | ||
types: ['file'], | ||
namespace: 'org.test.complex', | ||
} | ||
]; | ||
|
||
mockModelFile.getAllDeclarations.returns([mockClassDeclaration]); | ||
mockModelFile.getImports.returns(['org.test.basic.file', 'org.test.basic.document', 'org.test.complex.file']); | ||
typescriptVisitor.visitModelFile(mockModelFile,param); | ||
|
||
param.fileWriter.writeLine.callCount.should.deep.equal(6); | ||
param.fileWriter.writeLine.getCall(0).args.should.deep.equal([0, '/* eslint-disable @typescript-eslint/no-empty-interface */']); | ||
param.fileWriter.writeLine.getCall(1).args.should.deep.equal([0, '// Generated code for namespace: org.test.collection']); | ||
param.fileWriter.writeLine.getCall(2).args.should.deep.equal([0, '\n// imports']); | ||
param.fileWriter.writeLine.getCall(3).args.should.deep.equal([0, 'import {Ifile as If} from \'./org.test.basic\';']); | ||
param.fileWriter.writeLine.getCall(4).args.should.deep.equal([0, 'import {Ifile} from \'./org.test.complex\';']); | ||
param.fileWriter.writeLine.getCall(5).args.should.deep.equal([0, '\n// interfaces']); | ||
param.fileWriter.closeFile.calledOnce.should.be.ok; | ||
|
||
}); | ||
}); | ||
|
||
describe('visitEnumDeclaration', () => { | ||
|
@@ -444,7 +510,7 @@ describe('TypescriptVisitor', function () { | |
mockClassDeclaration.getName.returns('Bob'); | ||
mockClassDeclaration.isAbstract.returns(true); | ||
mockClassDeclaration.getSuperType.returns('org.acme.Person'); | ||
|
||
param.aliasedTypesMap=new Map(); | ||
typescriptVisitor.visitClassDeclaration(mockClassDeclaration, param); | ||
|
||
param.fileWriter.writeLine.callCount.should.deep.equal(2); | ||
|
@@ -512,6 +578,34 @@ describe('TypescriptVisitor', function () { | |
param.fileWriter.writeLine.getCall(1).args.should.deep.equal([1, '$class: string;']); | ||
param.fileWriter.writeLine.getCall(2).args.should.deep.equal([0, '}\n']); | ||
}); | ||
|
||
it('should write lines for the extending class declaration using aliased types ', () => { | ||
|
||
let property = { | ||
isPrimitive: () => { | ||
return false; | ||
}, | ||
getFullyQualifiedTypeName: () => { | ||
return 'org.test.basic.file'; | ||
} | ||
}; | ||
|
||
let mockClassDeclaration = sinon.createStubInstance(ClassDeclaration); | ||
|
||
mockClassDeclaration.isClassDeclaration.returns(true); | ||
mockClassDeclaration.getProperties.returns([property]); | ||
mockClassDeclaration.getNamespace.returns('org.test.collection'); | ||
mockClassDeclaration.getName.returns('bigFile'); | ||
mockClassDeclaration.getSuperType.returns('org.basic.file'); | ||
mockClassDeclaration.isScalarDeclaration.returns(false); | ||
mockClassDeclaration.getDirectSubclasses.returns([]); | ||
mockClassDeclaration.getOwnProperties.returns([]); | ||
param.aliasedTypesMap = new Map([['org.basic.Ifile', 'If']]); | ||
typescriptVisitor.visitClassDeclaration(mockClassDeclaration,param); | ||
|
||
param.fileWriter.writeLine.callCount.should.deep.equal(2); | ||
param.fileWriter.writeLine.getCall(0).args.should.deep.equal([0, 'export interface IbigFile extends If {']); | ||
}); | ||
}); | ||
|
||
describe('visitField', () => { | ||
|