1
1
import astToCode from 'babel-generator' ;
2
+ import * as chalk from 'chalk' ;
2
3
import * as dom from 'dts-dom' ;
4
+ import { IOptions } from './index' ;
3
5
import { propTypeQueryExpression , AstQuery } from './typings' ;
4
6
5
7
export interface TypeDeclaration {
@@ -14,22 +16,22 @@ function getTypeDeclaration(type: any, optional: boolean): TypeDeclaration {
14
16
} ;
15
17
}
16
18
17
- export function get ( ast : AstQuery , propertyAst : any , propTypesName : string | undefined ) : TypeDeclaration {
19
+ export function get ( ast : AstQuery , propertyAst : any , propTypesName : string | undefined ,
20
+ options : IOptions ) : TypeDeclaration {
18
21
try {
19
22
const simpleType = getSimpleType ( ast , propertyAst , propTypesName ) ;
20
23
if ( simpleType ) {
21
24
return simpleType ;
22
25
}
23
- const complexType = getComplexType ( ast , propertyAst , propTypesName ) ;
26
+ const complexType = getComplexType ( ast , propertyAst , propTypesName , options ) ;
24
27
if ( complexType ) {
25
28
return complexType ;
26
29
}
27
30
} catch ( e ) {
28
- console . error ( 'Failed to infer PropType; Fallback to any' ) ;
29
31
if ( e . loc ) {
30
- const src = astToCode ( ast . ast ) . code ;
31
- console . error ( `Line ${ e . loc . start . line } : ${ src . split ( '\n' ) [ e . loc . start . line - 1 ] } ` ) ;
32
+ printErrorWithContext ( e , ast . ast , options ) ;
32
33
} else {
34
+ console . error ( 'Failed to infer PropType; Fallback to any' ) ;
33
35
console . error ( e . stack ) ;
34
36
}
35
37
}
@@ -73,18 +75,18 @@ function getSimpleType(ast: AstQuery, propertyAst: any,
73
75
}
74
76
75
77
function getComplexType ( ast : AstQuery , propertyAst : any ,
76
- propTypesName : string | undefined ) : TypeDeclaration | undefined {
78
+ propTypesName : string | undefined , options : IOptions ) : TypeDeclaration | undefined {
77
79
const [ required , complexTypeName , typeAst ] = getComplexTypeName ( ast , propertyAst , propTypesName ) ;
78
80
switch ( complexTypeName ) {
79
81
case 'instanceOf' :
80
82
return getTypeDeclaration ( dom . create . typeof (
81
83
dom . create . namedTypeReference ( typeAst . arguments [ 0 ] . name ) ) , ! required ) ;
82
84
case 'oneOfType' :
83
85
const typeDecls = typeAst . arguments [ 0 ] . elements
84
- . map ( ( subtree : any ) => get ( ast , subtree , propTypesName ) ) as TypeDeclaration [ ] ;
86
+ . map ( ( subtree : any ) => get ( ast , subtree , propTypesName , options ) ) as TypeDeclaration [ ] ;
85
87
return getTypeDeclaration ( dom . create . union ( typeDecls . map ( type => type . type ) ) , ! required ) ;
86
88
case 'arrayOf' :
87
- const typeDecl = get ( ast , typeAst . arguments [ 0 ] , propTypesName ) ;
89
+ const typeDecl = get ( ast , typeAst . arguments [ 0 ] , propTypesName , options ) ;
88
90
return getTypeDeclaration ( dom . create . array ( typeDecl . type ) , ! required ) ;
89
91
case 'oneOf' :
90
92
// tslint:disable:next-line comment-format
@@ -93,7 +95,7 @@ function getComplexType(ast: AstQuery, propertyAst: any,
93
95
return getTypeDeclaration ( dom . create . union ( enumEntries as dom . Type [ ] ) , ! required ) ;
94
96
case 'shape' :
95
97
const entries = getShapeProperties ( ast , typeAst . arguments [ 0 ] ) . map ( ( entry : any ) => {
96
- const typeDecl = get ( ast , entry . value , propTypesName ) ;
98
+ const typeDecl = get ( ast , entry . value , propTypesName , options ) ;
97
99
return dom . create . property ( entry . key . name , typeDecl . type ,
98
100
typeDecl . optional ? dom . DeclarationFlags . Optional : dom . DeclarationFlags . None ) ;
99
101
} ) ;
@@ -144,16 +146,12 @@ function getEnumValues(ast: AstQuery, oneOfTypes: any): any[] {
144
146
/:init *
145
147
` ) ;
146
148
if ( ! res [ 0 ] ) {
147
- const error = new Error ( 'Failed to lookup enum values' ) ;
148
- ( error as any ) . loc = oneOfTypes . loc ;
149
- throw error ;
149
+ throwWithLocation ( 'Failed to lookup enum values' , oneOfTypes ) ;
150
150
}
151
151
oneOfTypes = res [ 0 ] ;
152
152
}
153
153
if ( ! oneOfTypes . elements ) {
154
- const error = new Error ( 'Failed to lookup enum values' ) ;
155
- ( error as any ) . loc = oneOfTypes . loc ;
156
- throw error ;
154
+ throwWithLocation ( 'Failed to lookup enum values' , oneOfTypes ) ;
157
155
}
158
156
return ( oneOfTypes . elements as any [ ] ) . map ( ( element : any ) => {
159
157
// fixme: This are not named references!
@@ -178,14 +176,33 @@ function getShapeProperties(ast: AstQuery, input: any): any[] {
178
176
if ( res [ 0 ] ) {
179
177
return res [ 0 ] . properties ;
180
178
}
181
- const error = new Error ( 'Failed to lookup shape properties' ) ;
182
- ( error as any ) . loc = input . loc ;
183
- throw error ;
179
+ throwWithLocation ( 'Failed to lookup shape properties' , input ) ;
184
180
}
185
181
if ( ! input . properties ) {
186
- const error = new Error ( 'Failed to lookup shape properties' ) ;
187
- ( error as any ) . loc = input . loc ;
188
- throw error ;
182
+ throwWithLocation ( 'Failed to lookup shape properties' , input ) ;
189
183
}
190
184
return input . properties ;
191
185
}
186
+
187
+ function throwWithLocation ( message : string , ast : any ) : never {
188
+ const error = new Error ( message ) ;
189
+ ( error as any ) . loc = ast . loc ;
190
+ ( error as any ) . start = ast . start ;
191
+ ( error as any ) . end = ast . end ;
192
+ throw error ;
193
+ }
194
+
195
+ function printErrorWithContext ( e : any , ast : any , options : IOptions ) : void {
196
+ console . error ( `${ ( options . filename || '' ) } ${ e . message } ` ) ;
197
+ const src = options . source || astToCode ( ast . ast ) . code ;
198
+ // console.log(src.substring(e.start, e.end));
199
+ const lines = src . split ( '\n' ) ;
200
+ const errorLine = lines [ e . loc . start . line - 1 ] ;
201
+
202
+ console . error ( `Line ${ e . loc . start . line - 1 } : ${ lines [ e . loc . start . line - 2 ] } ` ) ;
203
+ console . error ( `Line ${ e . loc . start . line } : ` + errorLine . substring ( 0 , e . loc . start . column )
204
+ + chalk . red ( errorLine . substring ( e . loc . start . column , e . loc . end . column ) )
205
+ + errorLine . substring ( e . loc . end . column ) ) ;
206
+ console . error ( `Line ${ e . loc . start . line + 1 } : ${ lines [ e . loc . start . line ] } ` ) ;
207
+ console . error ( ) ;
208
+ }
0 commit comments