Skip to content

Commit 277963e

Browse files
committed
update package
1 parent afa5005 commit 277963e

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

specification/src/api-specification.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ export class Specification {
3737
const specVisitor = new TypeReader(this.program)
3838
const types = [].concat(specVisitor.interfaces).concat(specVisitor.enums)
3939
// resolve inherits by creating the proper pointers to instances, pretty hairy but it works
40-
const dictTypes = types.reduce((o, p) => ({ ...o, [p.name]: p }), {}) as TypeDictionary
41-
const stringType = new Domain.Interface('string')
42-
const lookup = (key: string) => key === 'string' ? stringType : (dictTypes[key] as Domain.Interface)
40+
const dictTypes = types.reduce((o, p) => ({...o, [p.name]: p}), {}) as TypeDictionary;
41+
const stringType = new Domain.Interface("string" , "internal");
42+
const lookup = (key: string) => key === "string" ? stringType : (dictTypes[key] as Domain.Interface);
4343
types.forEach(t => {
4444
if (!(t instanceof Domain.Interface)) return
4545
t.inherits = []

specification/src/domain.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ namespace Domain {
66
export class Type {
77
constructor (public name: string) {}
88
nullable: boolean;
9+
closedGenerics: InstanceOf[] = [];
910
}
1011
export class ArrayOf {
1112
type = new Type('array');
@@ -23,7 +24,7 @@ namespace Domain {
2324
export type InstanceOf = Type|ArrayOf|Dictionary|UnionOf;
2425

2526
export class TypeDeclaration {
26-
constructor (public name: string) {}
27+
constructor(public name: string, public namespace: string) {}
2728
}
2829

2930
export class Interface extends TypeDeclaration {
@@ -45,12 +46,12 @@ namespace Domain {
4546
}
4647

4748
export class Enum extends TypeDeclaration {
48-
constructor (public name: string, public flags: boolean = false) { super(name) }
49+
constructor(public name: string, public namespace: string, public flags: boolean = false) { super(name, namespace); }
4950
members: EnumMember[] = [];
5051
}
5152

5253
export class EnumMember {
53-
constructor (public name: string) {}
54+
constructor(public name: string, public stringRepresentation: string) {}
5455
}
5556

5657
export class BodyDocumentation {

specification/src/specification/type-reader.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@ import {RestSpecMapping, RestSpecName, TypeName} from "./rest-spec-mapping";
22
import _ from "lodash";
33
import * as ts from "byots";
44
import Domain = require("../domain");
5+
import path from "path";
56

67
class Visitor {
78
constructor(protected checker: ts.TypeChecker) {}
89
protected symbolName = (node: ts.Node): string => this.checker.getSymbolAtLocation(node).getName();
910
}
1011

1112
class EnumVisitor extends Visitor {
12-
constructor(private enumNode: ts.EnumDeclaration, checker: ts.TypeChecker) {super(checker); }
13+
constructor(private enumNode: ts.EnumDeclaration, checker: ts.TypeChecker, private namespace: string) {super(checker); }
1314

1415
visit(): Domain.Enum {
1516
const name = this.symbolName(this.enumNode.name);
16-
const domainEnum = new Domain.Enum(name);
17+
const domainEnum = new Domain.Enum(name, this.namespace);
1718
for (const child of this.enumNode.getChildren())
1819
this.visitMember(child as ts.EnumMember, domainEnum);
1920
return domainEnum;
@@ -30,21 +31,25 @@ class EnumVisitor extends Visitor {
3031
if (!this.isMember(member, e)) return;
3132

3233
const name = this.symbolName(member.name);
33-
e.members.push(new Domain.EnumMember(name));
34+
const description = (member.jsDoc || []).map(c => c.comment).join(".").trim();
35+
36+
e.members.push(new Domain.EnumMember(description || name, name));
3437
}
3538
}
3639

3740
class InterfaceVisitor extends Visitor {
3841
name: TypeName;
3942
specMapping: RestSpecMapping;
40-
constructor(private interfaceNode: ts.InterfaceDeclaration | ts.ClassDeclaration, checker: ts.TypeChecker) {
41-
super(checker);
42-
}
43+
44+
constructor(
45+
private interfaceNode: ts.InterfaceDeclaration | ts.ClassDeclaration,
46+
checker: ts.TypeChecker,
47+
private namespace: string) { super(checker); }
4348

4449
visit(): Domain.Interface {
4550
const n = this.symbolName(this.interfaceNode.name);
4651
this.name = n;
47-
const domainInterface = new Domain.Interface(n);
52+
const domainInterface = new Domain.Interface(n, this.namespace);
4853

4954
const decorator = _(this.interfaceNode.decorators || [])
5055
.map(d => d.expression.getText())
@@ -136,7 +141,11 @@ class InterfaceVisitor extends Visitor {
136141
const typeName = t.typeName.getText();
137142
if (typeName.startsWith("Dictionary")) return this.createDictionary(t, typeName);
138143
if (typeName.startsWith("Union")) return this.createUnion(t, typeName);
139-
return new Domain.Type(t.getText());
144+
const typed = new Domain.Type(typeName);
145+
if (!t.typeArguments || t.typeArguments.length === 0)
146+
return typed;
147+
typed.closedGenerics = t.typeArguments.map(gt => this.visitTypeNode(gt));
148+
return typed;
140149
}
141150

142151
private createUnion(t: ts.TypeReferenceNode, typeName) {
@@ -187,30 +196,34 @@ export class TypeReader {
187196
this.restSpecMapping = {};
188197
this.checker = program.getTypeChecker();
189198
for (const f of this.program.getSourceFiles()) {
190-
if (!f.path.match(/specification\/specs/)) continue;
191-
this.visit(f);
199+
if (!f.path.match(/specification[\/\\]specs/)) continue;
200+
let ns = path.dirname(f.path)
201+
.replace(/.*specification[\/\\]specs[\/\\]?/, "")
202+
.replace(/[\/\\]/g, ".");
203+
if (ns === "") ns = "internal";
204+
this.visit(f, ns);
192205
}
193206
}
194207

195-
private visit(node: ts.Node) {
208+
private visit(node: ts.Node, namespace: string) {
196209
switch (node.kind) {
197210
case ts.SyntaxKind.ClassDeclaration:
198-
const cv = new InterfaceVisitor(node as ts.ClassDeclaration, this.checker);
211+
const cv = new InterfaceVisitor(node as ts.ClassDeclaration, this.checker, namespace);
199212
const c = cv.visit();
200213
if (cv.specMapping) this.restSpecMapping[cv.specMapping.spec] = cv.specMapping;
201214
this.interfaces.push(c);
202215
break;
203216
case ts.SyntaxKind.InterfaceDeclaration:
204-
const iv = new InterfaceVisitor(node as ts.InterfaceDeclaration, this.checker);
217+
const iv = new InterfaceVisitor(node as ts.InterfaceDeclaration, this.checker, namespace);
205218
const i = iv.visit();
206219
this.interfaces.push(i);
207220
break;
208221

209222
case ts.SyntaxKind.EnumDeclaration:
210-
const ev = new EnumVisitor(node as ts.EnumDeclaration, this.checker);
223+
const ev = new EnumVisitor(node as ts.EnumDeclaration, this.checker, namespace);
211224
this.enums.push(ev.visit());
212225
break;
213226
}
214-
ts.forEachChild(node, c => this.visit(c));
227+
ts.forEachChild(node, c => this.visit(c, namespace));
215228
}
216229
}

0 commit comments

Comments
 (0)