@@ -57,232 +57,12 @@ func (p *Parser) withJSDoc(node *ast.Node, hasJSDoc bool) {
57
57
node .Flags |= ast .NodeFlagsDeprecated
58
58
}
59
59
if p .scriptKind == core .ScriptKindJS || p .scriptKind == core .ScriptKindJSX {
60
- p .attachTagsToHost (node , jsdoc )
60
+ p .reparseTags (node , jsdoc )
61
61
}
62
62
p .jsdocCache [node ] = jsdoc
63
63
}
64
64
}
65
65
66
- // Unhosted tags add synthetic nodes to the reparse list instead of finding and modifying a host
67
- func (p * Parser ) attachTagsToHost (parent * ast.Node , jsDoc []* ast.Node ) {
68
- for _ , j := range jsDoc {
69
- isLast := j == jsDoc [len (jsDoc )- 1 ]
70
- tags := j .AsJSDoc ().Tags
71
- if tags == nil {
72
- continue
73
- }
74
- for _ , tag := range j .AsJSDoc ().Tags .Nodes {
75
- switch tag .Kind {
76
- case ast .KindJSDocTypedefTag :
77
- // !!! Don't mark typedefs as exported if they are not in a module
78
- typeExpression := tag .AsJSDocTypedefTag ().TypeExpression
79
- if typeExpression == nil {
80
- break
81
- }
82
- export := p .factory .NewModifier (ast .KindExportKeyword )
83
- export .Loc = tag .Loc
84
- export .Flags = p .contextFlags | ast .NodeFlagsReparsed
85
- nodes := p .nodeSlicePool .NewSlice (1 )
86
- nodes [0 ] = export
87
- modifiers := p .newModifierList (export .Loc , nodes )
88
-
89
- typeParameters := p .gatherTypeParameters (j )
90
-
91
- var t * ast.Node
92
- switch typeExpression .Kind {
93
- case ast .KindJSDocTypeExpression :
94
- t = typeExpression .Type ()
95
- case ast .KindJSDocTypeLiteral :
96
- members := p .nodeSlicePool .NewSlice (0 )
97
- for _ , member := range typeExpression .AsJSDocTypeLiteral ().JSDocPropertyTags {
98
- prop := p .factory .NewPropertySignatureDeclaration (nil , member .Name (), nil /*postfixToken*/ , member .Type (), nil /*initializer*/ )
99
- prop .Loc = member .Loc
100
- prop .Flags = p .contextFlags | ast .NodeFlagsReparsed
101
- members = append (members , prop )
102
- }
103
- t = p .factory .NewTypeLiteralNode (p .newNodeList (typeExpression .Loc , members ))
104
- t .Loc = typeExpression .Loc
105
- t .Flags = p .contextFlags | ast .NodeFlagsReparsed
106
- default :
107
- panic ("typedef tag type expression should be a name reference or a type expression" + typeExpression .Kind .String ())
108
- }
109
- typeAlias := p .factory .NewJSTypeAliasDeclaration (modifiers , tag .AsJSDocTypedefTag ().Name (), typeParameters , t )
110
- typeAlias .Loc = core .NewTextRange (tag .Pos (), tag .End ())
111
- typeAlias .Flags = p .contextFlags | ast .NodeFlagsReparsed
112
- p .reparseList = append (p .reparseList , typeAlias )
113
- // !!! @overload and other unattached tags (@callback, @import et al) support goes here
114
- }
115
- if ! isLast {
116
- continue
117
- }
118
- switch tag .Kind {
119
- case ast .KindJSDocTypeTag :
120
- if parent .Kind == ast .KindVariableStatement && parent .AsVariableStatement ().DeclarationList != nil {
121
- for _ , declaration := range parent .AsVariableStatement ().DeclarationList .AsVariableDeclarationList ().Declarations .Nodes {
122
- if declaration .AsVariableDeclaration ().Type == nil {
123
- declaration .AsVariableDeclaration ().Type = p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , declaration )
124
- }
125
- }
126
- } else if parent .Kind == ast .KindVariableDeclaration {
127
- if parent .AsVariableDeclaration ().Type == nil {
128
- parent .AsVariableDeclaration ().Type = p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , parent )
129
- }
130
- } else if parent .Kind == ast .KindPropertyDeclaration {
131
- declaration := parent .AsPropertyDeclaration ()
132
- if declaration .Type == nil {
133
- declaration .Type = p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , parent )
134
- }
135
- } else if parent .Kind == ast .KindPropertyAssignment {
136
- prop := parent .AsPropertyAssignment ()
137
- prop .Initializer = p .makeNewTypeAssertion (p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , nil ), prop .Initializer )
138
- } else if parent .Kind == ast .KindExportAssignment {
139
- export := parent .AsExportAssignment ()
140
- export .Expression = p .makeNewTypeAssertion (p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , nil ), export .Expression )
141
- } else if parent .Kind == ast .KindReturnStatement {
142
- ret := parent .AsReturnStatement ()
143
- ret .Expression = p .makeNewTypeAssertion (p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , nil ), ret .Expression )
144
- } else if parent .Kind == ast .KindParenthesizedExpression {
145
- paren := parent .AsParenthesizedExpression ()
146
- paren .Expression = p .makeNewTypeAssertion (p .makeNewType (tag .AsJSDocTypeTag ().TypeExpression , nil ), paren .Expression )
147
- }
148
- case ast .KindJSDocTemplateTag :
149
- if fun , ok := getFunctionLikeHost (parent ); ok {
150
- if fun .TypeParameters () == nil {
151
- fun .FunctionLikeData ().TypeParameters = p .gatherTypeParameters (j )
152
- }
153
- } else if parent .Kind == ast .KindClassDeclaration {
154
- class := parent .AsClassDeclaration ()
155
- if class .TypeParameters == nil {
156
- class .TypeParameters = p .gatherTypeParameters (j )
157
- }
158
- } else if parent .Kind == ast .KindClassExpression {
159
- class := parent .AsClassExpression ()
160
- if class .TypeParameters == nil {
161
- class .TypeParameters = p .gatherTypeParameters (j )
162
- }
163
- }
164
- case ast .KindJSDocParameterTag :
165
- if fun , ok := getFunctionLikeHost (parent ); ok {
166
- jsparam := tag .AsJSDocParameterTag ()
167
- if param , ok := findMatchingParameter (fun , jsparam ); ok {
168
- if param .Type () == nil {
169
- param .AsParameterDeclaration ().Type = p .makeNewType (jsparam .TypeExpression , param )
170
- if param .AsParameterDeclaration ().QuestionToken == nil &&
171
- param .AsParameterDeclaration ().Initializer == nil &&
172
- (jsparam .IsBracketed || jsparam .TypeExpression != nil && jsparam .TypeExpression .Type ().Kind == ast .KindJSDocOptionalType ) {
173
- param .AsParameterDeclaration ().QuestionToken = p .factory .NewToken (ast .KindQuestionToken )
174
- param .AsParameterDeclaration ().QuestionToken .Loc = core .NewTextRange (param .End (), param .End ())
175
- param .AsParameterDeclaration ().QuestionToken .Flags = p .contextFlags | ast .NodeFlagsReparsed
176
- }
177
- }
178
- }
179
- }
180
- case ast .KindJSDocReturnTag :
181
- if fun , ok := getFunctionLikeHost (parent ); ok {
182
- if fun .Type () == nil {
183
- fun .FunctionLikeData ().Type = p .makeNewType (tag .AsJSDocReturnTag ().TypeExpression , fun )
184
- }
185
- }
186
- }
187
- }
188
- }
189
- }
190
-
191
- func findMatchingParameter (fun * ast.Node , tag * ast.JSDocParameterTag ) (* ast.Node , bool ) {
192
- for _ , parameter := range fun .Parameters () {
193
- if parameter .Name ().Kind == ast .KindIdentifier && tag .Name ().Kind == ast .KindIdentifier &&
194
- parameter .Name ().Text () == tag .Name ().Text () {
195
- return parameter , true
196
- }
197
- }
198
- return nil , false
199
- }
200
-
201
- func (p * Parser ) gatherTypeParameters (j * ast.Node ) * ast.NodeList {
202
- typeParameters := p .nodeSlicePool .NewSlice (0 )
203
- pos := - 1
204
- end := - 1
205
- first := true
206
- for _ , tag := range j .AsJSDoc ().Tags .Nodes {
207
- if tag .Kind == ast .KindJSDocTemplateTag {
208
- if first {
209
- pos = tag .Pos ()
210
- first = false
211
- }
212
- end = tag .End ()
213
-
214
- constraint := tag .AsJSDocTemplateTag ().Constraint
215
- for _ , tp := range tag .AsJSDocTemplateTag ().TypeParameters ().Nodes {
216
- typeParameter := tp .AsTypeParameter ()
217
- var reparse * ast.Node
218
- if constraint == nil {
219
- reparse = typeParameter .Clone (& p .factory )
220
- } else {
221
- clone := constraint .Type ().Clone (& p .factory )
222
- clone .Flags |= ast .NodeFlagsReparsed
223
- reparse = p .factory .NewTypeParameterDeclaration (typeParameter .Modifiers (), typeParameter .Name (), clone , typeParameter .DefaultType )
224
- reparse .Loc = typeParameter .Loc
225
- }
226
- reparse .Flags |= ast .NodeFlagsReparsed
227
- typeParameters = append (typeParameters , reparse )
228
- }
229
- }
230
- }
231
- if len (typeParameters ) == 0 {
232
- return nil
233
- } else {
234
- return p .newNodeList (core .NewTextRange (pos , end ), typeParameters )
235
- }
236
- }
237
-
238
- func getFunctionLikeHost (host * ast.Node ) (* ast.Node , bool ) {
239
- fun := host
240
- if host .Kind == ast .KindVariableStatement && host .AsVariableStatement ().DeclarationList != nil {
241
- for _ , declaration := range host .AsVariableStatement ().DeclarationList .AsVariableDeclarationList ().Declarations .Nodes {
242
- if ast .IsFunctionLike (declaration .Initializer ()) {
243
- fun = declaration .Initializer ()
244
- break
245
- }
246
- }
247
- } else if host .Kind == ast .KindPropertyAssignment {
248
- fun = host .AsPropertyAssignment ().Initializer
249
- } else if host .Kind == ast .KindPropertyDeclaration {
250
- fun = host .AsPropertyDeclaration ().Initializer
251
- } else if host .Kind == ast .KindExportAssignment {
252
- fun = host .AsExportAssignment ().Expression
253
- } else if host .Kind == ast .KindReturnStatement {
254
- fun = host .AsReturnStatement ().Expression
255
- }
256
- if ast .IsFunctionLike (fun ) {
257
- return fun , true
258
- }
259
- return nil , false
260
- }
261
-
262
- func (p * Parser ) makeNewTypeAssertion (t * ast.TypeNode , e * ast.Node ) * ast.Node {
263
- assert := p .factory .NewTypeAssertion (t , e )
264
- assert .Flags = p .contextFlags | ast .NodeFlagsReparsed
265
- assert .Loc = core .NewTextRange (e .Pos (), e .End ())
266
- return assert
267
- }
268
-
269
- func (p * Parser ) makeNewType (typeExpression * ast.TypeNode , host * ast.Node ) * ast.Node {
270
- if typeExpression == nil || typeExpression .Type () == nil {
271
- return nil
272
- }
273
- if typeExpression .AsJSDocTypeExpression ().Host == nil {
274
- typeExpression .AsJSDocTypeExpression ().Host = host
275
- } else {
276
- panic ("JSDoc type expression already has a host: " + typeExpression .AsJSDocTypeExpression ().Host .Kind .String ())
277
- }
278
- t := typeExpression .Type ().Clone (& p .factory )
279
- t .Flags |= ast .NodeFlagsReparsed
280
- if host != nil {
281
- t .Parent = host
282
- }
283
- return t
284
- }
285
-
286
66
func (p * Parser ) parseJSDocTypeExpression (mayOmitBraces bool ) * ast.Node {
287
67
pos := p .nodePos ()
288
68
var hasBrace bool
0 commit comments