@@ -2,18 +2,19 @@ import {RestSpecMapping, RestSpecName, TypeName} from "./rest-spec-mapping";
2
2
import _ from "lodash" ;
3
3
import * as ts from "byots" ;
4
4
import Domain = require( "../domain" ) ;
5
+ import path from "path" ;
5
6
6
7
class Visitor {
7
8
constructor ( protected checker : ts . TypeChecker ) { }
8
9
protected symbolName = ( node : ts . Node ) : string => this . checker . getSymbolAtLocation ( node ) . getName ( ) ;
9
10
}
10
11
11
12
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 ) ; }
13
14
14
15
visit ( ) : Domain . Enum {
15
16
const name = this . symbolName ( this . enumNode . name ) ;
16
- const domainEnum = new Domain . Enum ( name ) ;
17
+ const domainEnum = new Domain . Enum ( name , this . namespace ) ;
17
18
for ( const child of this . enumNode . getChildren ( ) )
18
19
this . visitMember ( child as ts . EnumMember , domainEnum ) ;
19
20
return domainEnum ;
@@ -30,21 +31,25 @@ class EnumVisitor extends Visitor {
30
31
if ( ! this . isMember ( member , e ) ) return ;
31
32
32
33
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 ) ) ;
34
37
}
35
38
}
36
39
37
40
class InterfaceVisitor extends Visitor {
38
41
name : TypeName ;
39
42
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 ) ; }
43
48
44
49
visit ( ) : Domain . Interface {
45
50
const n = this . symbolName ( this . interfaceNode . name ) ;
46
51
this . name = n ;
47
- const domainInterface = new Domain . Interface ( n ) ;
52
+ const domainInterface = new Domain . Interface ( n , this . namespace ) ;
48
53
49
54
const decorator = _ ( this . interfaceNode . decorators || [ ] )
50
55
. map ( d => d . expression . getText ( ) )
@@ -136,7 +141,11 @@ class InterfaceVisitor extends Visitor {
136
141
const typeName = t . typeName . getText ( ) ;
137
142
if ( typeName . startsWith ( "Dictionary" ) ) return this . createDictionary ( t , typeName ) ;
138
143
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 ;
140
149
}
141
150
142
151
private createUnion ( t : ts . TypeReferenceNode , typeName ) {
@@ -187,30 +196,34 @@ export class TypeReader {
187
196
this . restSpecMapping = { } ;
188
197
this . checker = program . getTypeChecker ( ) ;
189
198
for ( const f of this . program . getSourceFiles ( ) ) {
190
- if ( ! f . path . match ( / s p e c i f i c a t i o n \/ s p e c s / ) ) continue ;
191
- this . visit ( f ) ;
199
+ if ( ! f . path . match ( / s p e c i f i c a t i o n [ \/ \\ ] s p e c s / ) ) continue ;
200
+ let ns = path . dirname ( f . path )
201
+ . replace ( / .* s p e c i f i c a t i o n [ \/ \\ ] s p e c s [ \/ \\ ] ? / , "" )
202
+ . replace ( / [ \/ \\ ] / g, "." ) ;
203
+ if ( ns === "" ) ns = "internal" ;
204
+ this . visit ( f , ns ) ;
192
205
}
193
206
}
194
207
195
- private visit ( node : ts . Node ) {
208
+ private visit ( node : ts . Node , namespace : string ) {
196
209
switch ( node . kind ) {
197
210
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 ) ;
199
212
const c = cv . visit ( ) ;
200
213
if ( cv . specMapping ) this . restSpecMapping [ cv . specMapping . spec ] = cv . specMapping ;
201
214
this . interfaces . push ( c ) ;
202
215
break ;
203
216
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 ) ;
205
218
const i = iv . visit ( ) ;
206
219
this . interfaces . push ( i ) ;
207
220
break ;
208
221
209
222
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 ) ;
211
224
this . enums . push ( ev . visit ( ) ) ;
212
225
break ;
213
226
}
214
- ts . forEachChild ( node , c => this . visit ( c ) ) ;
227
+ ts . forEachChild ( node , c => this . visit ( c , namespace ) ) ;
215
228
}
216
229
}
0 commit comments