1
1
import React , { useCallback , useEffect , useState } from 'react' ;
2
2
3
3
import ASTViewer from './ast/ASTViewer' ;
4
- import { isRecord } from './ast/utils' ;
5
- import type {
6
- ASTViewerBaseProps ,
7
- SelectedRange ,
8
- SelectedPosition ,
9
- } from './ast/types' ;
10
- import type { Node , SourceFile } from 'typescript' ;
4
+ import type { ASTViewerBaseProps , ASTViewerModelMap } from './ast/types' ;
5
+ import type { SourceFile } from 'typescript' ;
6
+ import { serialize } from './ast/serializer/serializer' ;
7
+ import { createTsSerializer } from './ast/serializer/serializerTS' ;
11
8
12
9
export interface ASTTsViewerProps extends ASTViewerBaseProps {
13
- readonly version : string ;
10
+ readonly value : SourceFile | string ;
14
11
}
15
12
16
13
function extractEnum (
@@ -28,10 +25,6 @@ function extractEnum(
28
25
return result ;
29
26
}
30
27
31
- function isTsNode ( value : unknown ) : value is Node {
32
- return isRecord ( value ) && typeof value . kind === 'number' ;
33
- }
34
-
35
28
function getFlagNamesFromEnum (
36
29
allFlags : Record < number , string > ,
37
30
flags : number ,
@@ -42,108 +35,64 @@ function getFlagNamesFromEnum(
42
35
. map ( ( [ _ , name ] ) => `${ prefix } .${ name } ` ) ;
43
36
}
44
37
45
- export function getLineAndCharacterFor (
46
- pos : number ,
47
- ast : SourceFile ,
48
- ) : SelectedPosition {
49
- const loc = ast . getLineAndCharacterOfPosition ( pos ) ;
50
- return {
51
- line : loc . line + 1 ,
52
- column : loc . character ,
53
- } ;
54
- }
55
-
56
- export function getLocFor (
57
- start : number ,
58
- end : number ,
59
- ast : SourceFile ,
60
- ) : SelectedRange {
61
- return {
62
- start : getLineAndCharacterFor ( start , ast ) ,
63
- end : getLineAndCharacterFor ( end , ast ) ,
64
- } ;
65
- }
66
-
67
- export const propsToFilter = [
68
- 'parent' ,
69
- 'jsDoc' ,
70
- 'lineMap' ,
71
- 'externalModuleIndicator' ,
72
- 'bindDiagnostics' ,
73
- 'transformFlags' ,
74
- 'resolvedModules' ,
75
- 'imports' ,
76
- ] ;
77
-
78
- export default function ASTViewerTS ( props : ASTTsViewerProps ) : JSX . Element {
79
- const [ syntaxKind , setSyntaxKind ] = useState < Record < number , string > > ( { } ) ;
80
- const [ nodeFlags , setNodeFlags ] = useState < Record < number , string > > ( { } ) ;
81
- const [ tokenFlags , setTokenFlags ] = useState < Record < number , string > > ( { } ) ;
82
- const [ modifierFlags , setModifierFlags ] = useState < Record < number , string > > (
83
- { } ,
84
- ) ;
38
+ export default function ASTViewerTS ( {
39
+ value,
40
+ position,
41
+ onSelectNode,
42
+ } : ASTTsViewerProps ) : JSX . Element {
43
+ const [ model , setModel ] = useState < string | ASTViewerModelMap > ( '' ) ;
44
+ const [ syntaxKind ] = useState ( ( ) => extractEnum ( window . ts . SyntaxKind ) ) ;
45
+ const [ nodeFlags ] = useState ( ( ) => extractEnum ( window . ts . NodeFlags ) ) ;
46
+ const [ tokenFlags ] = useState ( ( ) => extractEnum ( window . ts . TokenFlags ) ) ;
47
+ const [ modifierFlags ] = useState ( ( ) => extractEnum ( window . ts . ModifierFlags ) ) ;
85
48
86
49
useEffect ( ( ) => {
87
- setSyntaxKind ( extractEnum ( window . ts . SyntaxKind ) ) ;
88
- setNodeFlags ( extractEnum ( window . ts . NodeFlags ) ) ;
89
- setTokenFlags ( extractEnum ( window . ts . TokenFlags ) ) ;
90
- setModifierFlags ( extractEnum ( window . ts . ModifierFlags ) ) ;
91
- } , [ props . version ] ) ;
50
+ if ( typeof value === 'string' ) {
51
+ setModel ( value ) ;
52
+ } else {
53
+ const scopeSerializer = createTsSerializer ( value , syntaxKind ) ;
54
+ setModel ( serialize ( value , scopeSerializer ) ) ;
55
+ }
56
+ } , [ value , syntaxKind ] ) ;
92
57
58
+ // TODO: move this to serializer
93
59
const getTooltip = useCallback (
94
- ( key : string , value : unknown ) : string | undefined => {
95
- if ( key === 'flags' && typeof value === 'number' ) {
96
- return getFlagNamesFromEnum ( nodeFlags , value , 'NodeFlags' ) . join ( '\n' ) ;
97
- } else if ( key === 'numericLiteralFlags' && typeof value === 'number' ) {
98
- return getFlagNamesFromEnum ( tokenFlags , value , 'TokenFlags' ) . join ( '\n' ) ;
99
- } else if ( key === 'modifierFlagsCache' && typeof value === 'number' ) {
100
- return getFlagNamesFromEnum ( modifierFlags , value , 'ModifierFlags' ) . join (
101
- '\n' ,
102
- ) ;
103
- } else if ( key === 'kind' && typeof value === 'number' ) {
104
- return `SyntaxKind.${ syntaxKind [ value ] } ` ;
60
+ ( data : ASTViewerModelMap ) : string | undefined => {
61
+ if ( data . model . type === 'number' ) {
62
+ switch ( data . key ) {
63
+ case 'flags' :
64
+ return getFlagNamesFromEnum (
65
+ nodeFlags ,
66
+ Number ( data . model . value ) ,
67
+ 'NodeFlags' ,
68
+ ) . join ( '\n' ) ;
69
+ case 'numericLiteralFlags' :
70
+ return getFlagNamesFromEnum (
71
+ tokenFlags ,
72
+ Number ( data . model . value ) ,
73
+ 'TokenFlags' ,
74
+ ) . join ( '\n' ) ;
75
+ case 'modifierFlagsCache' :
76
+ return getFlagNamesFromEnum (
77
+ modifierFlags ,
78
+ Number ( data . model . value ) ,
79
+ 'ModifierFlags' ,
80
+ ) . join ( '\n' ) ;
81
+ case 'kind' :
82
+ return `SyntaxKind.${ syntaxKind [ Number ( data . model . value ) ] } ` ;
83
+ }
105
84
}
106
85
return undefined ;
107
86
} ,
108
87
[ nodeFlags , tokenFlags , syntaxKind ] ,
109
88
) ;
110
89
111
- const getNodeName = useCallback (
112
- ( value : unknown ) : string | undefined =>
113
- isTsNode ( value ) ? syntaxKind [ value . kind ] : undefined ,
114
- [ syntaxKind ] ,
115
- ) ;
116
-
117
- const filterProps = useCallback (
118
- ( item : [ string , unknown ] ) : boolean =>
119
- ! propsToFilter . includes ( item [ 0 ] ) &&
120
- ! item [ 0 ] . startsWith ( '_' ) &&
121
- item [ 1 ] !== undefined ,
122
- [ ] ,
123
- ) ;
124
-
125
- const getRange = useCallback (
126
- ( value : unknown ) : SelectedRange | undefined => {
127
- if ( props . value && isTsNode ( value ) ) {
128
- return getLocFor (
129
- value . pos ,
130
- value . end ,
131
- // @ts -expect-error: unsafe cast
132
- props . value as SourceFile ,
133
- ) ;
134
- }
135
- return undefined ;
136
- } ,
137
- [ props . value ] ,
138
- ) ;
139
-
140
90
return (
141
91
< ASTViewer
142
- filterProps = { filterProps }
143
- getRange = { getRange }
144
92
getTooltip = { getTooltip }
145
- getNodeName = { getNodeName }
146
- { ...props }
93
+ position = { position }
94
+ onSelectNode = { onSelectNode }
95
+ value = { model }
147
96
/>
148
97
) ;
149
98
}
0 commit comments