Skip to content

Commit 655eac4

Browse files
authored
feat(typescript) : generate interfaces and classes #322 (#323)
Signed-off-by: Dan Selman <[email protected]>
1 parent e994ddb commit 655eac4

File tree

2 files changed

+142
-65
lines changed

2 files changed

+142
-65
lines changed

packages/concerto-tools/lib/codegen/fromcto/typescript/typescriptvisitor.js

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,11 @@ class TypescriptVisitor {
8989
visitModelFile(modelFile, parameters) {
9090
parameters.fileWriter.openFile(modelFile.getNamespace() + '.ts');
9191

92+
parameters.fileWriter.writeLine(0, `// Generated code for namespace: ${modelFile.getNamespace()}`);
93+
9294
// Compute the types we need to import (based on all the types of the properites
9395
// as well as all the super types) for all the classes in this model file
96+
parameters.fileWriter.writeLine(0, '\n// imports');
9497
const properties = new Map();
9598
modelFile.getAllDeclarations()
9699
.filter(v => !v.isEnum())
@@ -101,6 +104,7 @@ class TypescriptVisitor {
101104
if (!properties.has(typeNamespace)) {
102105
properties.set(typeNamespace, new Set());
103106
}
107+
properties.get(typeNamespace).add(`I${typeName}`);
104108
properties.get(typeNamespace).add(typeName);
105109
}
106110

@@ -111,6 +115,7 @@ class TypescriptVisitor {
111115
if (!properties.has(typeNamespace)) {
112116
properties.set(typeNamespace, new Set());
113117
}
118+
properties.get(typeNamespace).add(`I${typeName}`);
114119
properties.get(typeNamespace).add(typeName);
115120
}
116121
});
@@ -126,13 +131,11 @@ class TypescriptVisitor {
126131
}
127132
});
128133

129-
parameters.fileWriter.writeLine(0, '// export namespace ' + modelFile.getNamespace() + '{');
130-
134+
parameters.fileWriter.writeLine(0, '\n// types');
131135
modelFile.getAllDeclarations().forEach((decl) => {
132136
decl.accept(this, parameters);
133137
});
134138

135-
parameters.fileWriter.writeLine(0, '// }');
136139
parameters.fileWriter.closeFile();
137140

138141
return null;
@@ -147,13 +150,13 @@ class TypescriptVisitor {
147150
*/
148151
visitEnumDeclaration(enumDeclaration, parameters) {
149152

150-
parameters.fileWriter.writeLine(1, 'export enum ' + enumDeclaration.getName() + ' {');
153+
parameters.fileWriter.writeLine(0, 'export enum ' + enumDeclaration.getName() + ' {');
151154

152155
enumDeclaration.getOwnProperties().forEach((property) => {
153156
property.accept(this, parameters);
154157
});
155158

156-
parameters.fileWriter.writeLine(1, '}');
159+
parameters.fileWriter.writeLine(0, '}\n');
157160
return null;
158161
}
159162

@@ -166,26 +169,42 @@ class TypescriptVisitor {
166169
*/
167170
visitClassDeclaration(classDeclaration, parameters) {
168171

169-
170-
let isAbstract = '';
171-
if (classDeclaration.isAbstract()) {
172-
isAbstract = 'export abstract ';
173-
} else {
174-
isAbstract = 'export ';
172+
let superType = ' ';
173+
if (classDeclaration.getSuperType()) {
174+
superType = ` extends I${ModelUtil.getShortName(classDeclaration.getSuperType())} `;
175175
}
176176

177-
let superType = '';
177+
parameters.fileWriter.writeLine(0, 'export interface I' + classDeclaration.getName() + superType + '{');
178+
179+
classDeclaration.getOwnProperties().forEach((property) => {
180+
property.accept(this, parameters);
181+
});
182+
183+
parameters.fileWriter.writeLine(0, '}\n');
184+
185+
const exportDecl = classDeclaration.isAbstract() ? 'export abstract' : 'export';
186+
178187
if (classDeclaration.getSuperType()) {
179-
superType = ' extends ' + ModelUtil.getShortName(classDeclaration.getSuperType());
188+
superType = ` extends ${ModelUtil.getShortName(classDeclaration.getSuperType())} `;
180189
}
181190

182-
parameters.fileWriter.writeLine(1, isAbstract + 'class ' + classDeclaration.getName() + superType + ' {');
183-
191+
parameters.fileWriter.writeLine(0, `${exportDecl} class ${classDeclaration.getName()}${superType}implements I${classDeclaration.getName()} {`);
192+
parameters.fileWriter.writeLine(1, 'public static $class: string');
193+
parameters.useDefiniteAssignment = true;
184194
classDeclaration.getOwnProperties().forEach((property) => {
185195
property.accept(this, parameters);
186196
});
197+
parameters.useDefiniteAssignment = false;
187198

199+
parameters.fileWriter.writeLine(1,`public constructor(data: I${classDeclaration.getName()}) {`);
200+
if(classDeclaration.getSuperType()) {
201+
parameters.fileWriter.writeLine(2, 'super(data);');
202+
}
203+
parameters.fileWriter.writeLine(2, 'Object.assign(this, data);');
204+
parameters.fileWriter.writeLine(2, `${classDeclaration.getName()}.$class = '${classDeclaration.getFullyQualifiedName()}'`);
188205
parameters.fileWriter.writeLine(1, '}');
206+
parameters.fileWriter.writeLine(0, '}\n');
207+
189208
return null;
190209
}
191210

@@ -203,7 +222,12 @@ class TypescriptVisitor {
203222
array = '[]';
204223
}
205224

206-
parameters.fileWriter.writeLine(2, field.getName() + ': ' + this.toTsType(field.getType()) + array + ';');
225+
const isEnumRef = field.isPrimitive() ? false
226+
: field.getParent().getModelFile().getModelManager().getType(field.getFullyQualifiedTypeName()).isEnum();
227+
228+
const assignment = parameters.useDefiniteAssignment ? '!' : '';
229+
230+
parameters.fileWriter.writeLine(1, field.getName() + assignment + ': ' + this.toTsType(field.getType(), !isEnumRef) + array + ';');
207231
return null;
208232
}
209233

@@ -215,7 +239,7 @@ class TypescriptVisitor {
215239
* @private
216240
*/
217241
visitEnumValueDeclaration(enumValueDeclaration, parameters) {
218-
parameters.fileWriter.writeLine(2, enumValueDeclaration.getName() + ',');
242+
parameters.fileWriter.writeLine(1, enumValueDeclaration.getName() + ',');
219243
return null;
220244
}
221245

@@ -233,19 +257,22 @@ class TypescriptVisitor {
233257
array = '[]';
234258
}
235259

236-
// we export all relationships by capitalizing them
237-
parameters.fileWriter.writeLine(2, relationship.getName() + ': ' + this.toTsType(relationship.getType()) + array + ';');
260+
const assignment = parameters.useDefiniteAssignment ? '!' : '';
261+
262+
// we export all relationships
263+
parameters.fileWriter.writeLine(1, relationship.getName() + assignment + ': ' + this.toTsType(relationship.getType(), true) + array + ';');
238264
return null;
239265
}
240266

241267
/**
242268
* Converts a Concerto type to a Typescript type. Primitive types are converted
243269
* everything else is passed through unchanged.
244270
* @param {string} type - the concerto type
271+
* @param {boolean} useInterface - whether to use an interface type
245272
* @return {string} the corresponding type in Typescript
246273
* @private
247274
*/
248-
toTsType(type) {
275+
toTsType(type, useInterface) {
249276
switch (type) {
250277
case 'DateTime':
251278
return 'Date';
@@ -260,7 +287,7 @@ class TypescriptVisitor {
260287
case 'Integer':
261288
return 'number';
262289
default:
263-
return type;
290+
return useInterface ? `I${type}` : type;
264291
}
265292
}
266293
}

0 commit comments

Comments
 (0)