Skip to content

Commit 1318a34

Browse files
authored
Add the 5 modifier jsdoc tags (#927)
1 parent 61ebc5a commit 1318a34

29 files changed

+392
-660
lines changed

internal/ast/ast.go

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ func (n *Node) TemplateLiteralLikeData() *TemplateLiteralLikeBase {
234234
return n.data.TemplateLiteralLikeData()
235235
}
236236

237+
type mutableNode Node
238+
239+
func (n *Node) AsMutable() *mutableNode { return (*mutableNode)(n) }
240+
func (n *mutableNode) SetModifiers(modifiers *ModifierList) { n.data.setModifiers(modifiers) }
241+
237242
func (n *Node) Symbol() *Symbol {
238243
data := n.DeclarationData()
239244
if data != nil {
@@ -1644,6 +1649,7 @@ type nodeData interface {
16441649
Clone(v NodeFactoryCoercible) *Node
16451650
Name() *DeclarationName
16461651
Modifiers() *ModifierList
1652+
setModifiers(modifiers *ModifierList)
16471653
FlowNodeData() *FlowNodeBase
16481654
DeclarationData() *DeclarationBase
16491655
ExportableData() *ExportableBase
@@ -1671,6 +1677,7 @@ func (node *NodeDefault) VisitEachChild(v *NodeVisitor) *Node { re
16711677
func (node *NodeDefault) Clone(v NodeFactoryCoercible) *Node { return nil }
16721678
func (node *NodeDefault) Name() *DeclarationName { return nil }
16731679
func (node *NodeDefault) Modifiers() *ModifierList { return nil }
1680+
func (node *NodeDefault) setModifiers(modifiers *ModifierList) {}
16741681
func (node *NodeDefault) FlowNodeData() *FlowNodeBase { return nil }
16751682
func (node *NodeDefault) DeclarationData() *DeclarationBase { return nil }
16761683
func (node *NodeDefault) ExportableData() *ExportableBase { return nil }
@@ -4802,9 +4809,10 @@ type NamedMemberBase struct {
48024809
PostfixToken *TokenNode // TokenNode. Optional
48034810
}
48044811

4805-
func (node *NamedMemberBase) DeclarationData() *DeclarationBase { return &node.DeclarationBase }
4806-
func (node *NamedMemberBase) Modifiers() *ModifierList { return node.modifiers }
4807-
func (node *NamedMemberBase) Name() *DeclarationName { return node.name }
4812+
func (node *NamedMemberBase) DeclarationData() *DeclarationBase { return &node.DeclarationBase }
4813+
func (node *NamedMemberBase) Modifiers() *ModifierList { return node.modifiers }
4814+
func (node *NamedMemberBase) setModifiers(modifiers *ModifierList) { node.modifiers = modifiers }
4815+
func (node *NamedMemberBase) Name() *DeclarationName { return node.name }
48084816

48094817
// CallSignatureDeclaration
48104818

@@ -5612,6 +5620,8 @@ func (node *BinaryExpression) computeSubtreeFacts() SubtreeFacts {
56125620
core.IfElse(node.OperatorToken.Kind == KindInKeyword && IsPrivateIdentifier(node.Left), SubtreeContainsClassFields, SubtreeFactsNone)
56135621
}
56145622

5623+
func (node *BinaryExpression) setModifiers(modifiers *ModifierList) { node.modifiers = modifiers }
5624+
56155625
func IsBinaryExpression(node *Node) bool {
56165626
return node.Kind == KindBinaryExpression
56175627
}

internal/checker/grammarchecks.go

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -308,11 +308,11 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
308308
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_already_seen, "override")
309309
} else if flags&ast.ModifierFlagsAmbient != 0 {
310310
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_be_used_with_1_modifier, "override", "declare")
311-
} else if flags&ast.ModifierFlagsReadonly != 0 {
311+
} else if flags&ast.ModifierFlagsReadonly != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
312312
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "override", "readonly")
313-
} else if flags&ast.ModifierFlagsAccessor != 0 {
313+
} else if flags&ast.ModifierFlagsAccessor != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
314314
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "override", "accessor")
315-
} else if flags&ast.ModifierFlagsAsync != 0 {
315+
} else if flags&ast.ModifierFlagsAsync != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
316316
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "override", "async")
317317
}
318318
flags |= ast.ModifierFlagsOverride
@@ -325,22 +325,22 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
325325

326326
if flags&ast.ModifierFlagsAccessibilityModifier != 0 {
327327
return c.grammarErrorOnNode(modifier, diagnostics.Accessibility_modifier_already_seen)
328-
} else if flags&ast.ModifierFlagsOverride != 0 {
328+
} else if flags&ast.ModifierFlagsOverride != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
329329
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "override")
330-
} else if flags&ast.ModifierFlagsStatic != 0 {
330+
} else if flags&ast.ModifierFlagsStatic != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
331331
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "static")
332-
} else if flags&ast.ModifierFlagsAccessor != 0 {
332+
} else if flags&ast.ModifierFlagsAccessor != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
333333
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "accessor")
334-
} else if flags&ast.ModifierFlagsReadonly != 0 {
334+
} else if flags&ast.ModifierFlagsReadonly != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
335335
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "readonly")
336-
} else if flags&ast.ModifierFlagsAsync != 0 {
336+
} else if flags&ast.ModifierFlagsAsync != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
337337
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "async")
338338
} else if node.Parent.Kind == ast.KindModuleBlock || node.Parent.Kind == ast.KindSourceFile {
339339
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_a_module_or_namespace_element, text)
340340
} else if flags&ast.ModifierFlagsAbstract != 0 {
341341
if modifier.Kind == ast.KindPrivateKeyword {
342342
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_be_used_with_1_modifier, text, "abstract")
343-
} else {
343+
} else if modifier.Flags&ast.NodeFlagsReparsed == 0 {
344344
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, text, "abstract")
345345
}
346346
} else if ast.IsPrivateIdentifierClassElementDeclaration(node) {
@@ -350,19 +350,19 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
350350
case ast.KindStaticKeyword:
351351
if flags&ast.ModifierFlagsStatic != 0 {
352352
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_already_seen, "static")
353-
} else if flags&ast.ModifierFlagsReadonly != 0 {
353+
} else if flags&ast.ModifierFlagsReadonly != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
354354
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "static", "readonly")
355-
} else if flags&ast.ModifierFlagsAsync != 0 {
355+
} else if flags&ast.ModifierFlagsAsync != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
356356
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "static", "async")
357-
} else if flags&ast.ModifierFlagsAccessor != 0 {
357+
} else if flags&ast.ModifierFlagsAccessor != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
358358
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "static", "accessor")
359359
} else if node.Parent.Kind == ast.KindModuleBlock || node.Parent.Kind == ast.KindSourceFile {
360360
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_a_module_or_namespace_element, "static")
361361
} else if node.Kind == ast.KindParameter {
362362
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_a_parameter, "static")
363363
} else if flags&ast.ModifierFlagsAbstract != 0 {
364364
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_be_used_with_1_modifier, "static", "abstract")
365-
} else if flags&ast.ModifierFlagsOverride != 0 {
365+
} else if flags&ast.ModifierFlagsOverride != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
366366
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "static", "override")
367367
}
368368
flags |= ast.ModifierFlagsStatic
@@ -395,11 +395,11 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
395395
}
396396
if flags&ast.ModifierFlagsExport != 0 {
397397
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_already_seen, "export")
398-
} else if flags&ast.ModifierFlagsAmbient != 0 {
398+
} else if flags&ast.ModifierFlagsAmbient != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
399399
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "export", "declare")
400-
} else if flags&ast.ModifierFlagsAbstract != 0 {
400+
} else if flags&ast.ModifierFlagsAbstract != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
401401
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "export", "abstract")
402-
} else if flags&ast.ModifierFlagsAsync != 0 {
402+
} else if flags&ast.ModifierFlagsAsync != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
403403
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "export", "async")
404404
} else if ast.IsClassLike(node.Parent) && !ast.IsJSTypeAliasDeclaration(node) {
405405
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_class_elements_of_this_kind, "export")
@@ -424,7 +424,7 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
424424
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_a_using_declaration, "default")
425425
} else if blockScopeKind == ast.NodeFlagsAwaitUsing {
426426
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_cannot_appear_on_an_await_using_declaration, "default")
427-
} else if flags&ast.ModifierFlagsExport == 0 {
427+
} else if flags&ast.ModifierFlagsExport == 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
428428
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "export", "default")
429429
} else if sawExportBeforeDecorators {
430430
return c.grammarErrorOnNode(firstDecorator, diagnostics.Decorators_are_not_valid_here)
@@ -481,10 +481,10 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has
481481
if flags&ast.ModifierFlagsAsync != 0 && lastAsync != nil {
482482
return c.grammarErrorOnNode(lastAsync, diagnostics.X_0_modifier_cannot_be_used_with_1_modifier, "async", "abstract")
483483
}
484-
if flags&ast.ModifierFlagsOverride != 0 {
484+
if flags&ast.ModifierFlagsOverride != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
485485
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "abstract", "override")
486486
}
487-
if flags&ast.ModifierFlagsAccessor != 0 {
487+
if flags&ast.ModifierFlagsAccessor != 0 && modifier.Flags&ast.NodeFlagsReparsed == 0 {
488488
return c.grammarErrorOnNode(modifier, diagnostics.X_0_modifier_must_precede_1_modifier, "abstract", "accessor")
489489
}
490490
}

internal/parser/reparser.go

Lines changed: 56 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -183,53 +183,57 @@ func (p *Parser) gatherTypeParameters(j *ast.Node) *ast.NodeList {
183183
func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node) {
184184
switch tag.Kind {
185185
case ast.KindJSDocTypeTag:
186-
if parent.Kind == ast.KindVariableStatement && parent.AsVariableStatement().DeclarationList != nil {
187-
for _, declaration := range parent.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes {
188-
if declaration.AsVariableDeclaration().Type == nil {
189-
declaration.AsVariableDeclaration().Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, declaration)
190-
break
186+
switch parent.Kind {
187+
case ast.KindVariableStatement:
188+
if parent.AsVariableStatement().DeclarationList != nil {
189+
for _, declaration := range parent.AsVariableStatement().DeclarationList.AsVariableDeclarationList().Declarations.Nodes {
190+
if declaration.AsVariableDeclaration().Type == nil {
191+
declaration.AsVariableDeclaration().Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, declaration)
192+
break
193+
}
191194
}
192195
}
193-
} else if parent.Kind == ast.KindVariableDeclaration {
196+
case ast.KindVariableDeclaration:
194197
if parent.AsVariableDeclaration().Type == nil {
195198
parent.AsVariableDeclaration().Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
196199
}
197-
} else if parent.Kind == ast.KindCommonJSExport {
200+
case ast.KindCommonJSExport:
198201
export := parent.AsCommonJSExport()
199202
if export.Type == nil {
200203
export.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
201204
}
202-
} else if parent.Kind == ast.KindPropertyDeclaration {
205+
case ast.KindPropertyDeclaration:
203206
declaration := parent.AsPropertyDeclaration()
204207
if declaration.Type == nil {
205208
declaration.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
206209
}
207-
} else if parent.Kind == ast.KindPropertyAssignment {
210+
case ast.KindPropertyAssignment:
208211
prop := parent.AsPropertyAssignment()
209212
if prop.Type == nil {
210213
prop.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
211214
}
212-
} else if parent.Kind == ast.KindShorthandPropertyAssignment {
215+
case ast.KindShorthandPropertyAssignment:
213216
prop := parent.AsShorthandPropertyAssignment()
214217
if prop.Type == nil {
215218
prop.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
216219
}
217-
} else if parent.Kind == ast.KindExportAssignment || parent.Kind == ast.KindJSExportAssignment {
220+
case ast.KindExportAssignment, ast.KindJSExportAssignment:
218221
export := parent.AsExportAssignment()
219222
if export.Type == nil {
220223
export.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent)
221224
}
222-
} else if parent.Kind == ast.KindReturnStatement {
225+
case ast.KindReturnStatement:
223226
ret := parent.AsReturnStatement()
224227
ret.Expression = p.makeNewTypeAssertion(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), ret.Expression)
225-
} else if parent.Kind == ast.KindParenthesizedExpression {
228+
case ast.KindParenthesizedExpression:
226229
paren := parent.AsParenthesizedExpression()
227230
paren.Expression = p.makeNewTypeAssertion(p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, nil), paren.Expression)
228-
} else if parent.Kind == ast.KindExpressionStatement &&
229-
parent.AsExpressionStatement().Expression.Kind == ast.KindBinaryExpression {
230-
bin := parent.AsExpressionStatement().Expression.AsBinaryExpression()
231-
if kind := ast.GetAssignmentDeclarationKind(bin); kind != ast.JSDeclarationKindNone {
232-
bin.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent.AsExpressionStatement().Expression)
231+
case ast.KindExpressionStatement:
232+
if parent.AsExpressionStatement().Expression.Kind == ast.KindBinaryExpression {
233+
bin := parent.AsExpressionStatement().Expression.AsBinaryExpression()
234+
if kind := ast.GetAssignmentDeclarationKind(bin); kind != ast.JSDeclarationKindNone {
235+
bin.Type = p.makeNewType(tag.AsJSDocTypeTag().TypeExpression, parent.AsExpressionStatement().Expression)
236+
}
233237
}
234238
}
235239
case ast.KindJSDocTemplateTag:
@@ -268,6 +272,40 @@ func (p *Parser) reparseHosted(tag *ast.Node, parent *ast.Node, jsDoc *ast.Node)
268272
fun.FunctionLikeData().Type = p.makeNewType(tag.AsJSDocReturnTag().TypeExpression, fun)
269273
}
270274
}
275+
case ast.KindJSDocReadonlyTag, ast.KindJSDocPrivateTag, ast.KindJSDocPublicTag, ast.KindJSDocProtectedTag, ast.KindJSDocOverrideTag:
276+
if parent.Kind == ast.KindExpressionStatement {
277+
parent = parent.AsExpressionStatement().Expression
278+
}
279+
switch parent.Kind {
280+
case ast.KindPropertyDeclaration, ast.KindMethodDeclaration, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindBinaryExpression:
281+
var keyword ast.Kind
282+
switch tag.Kind {
283+
case ast.KindJSDocReadonlyTag:
284+
keyword = ast.KindReadonlyKeyword
285+
case ast.KindJSDocPrivateTag:
286+
keyword = ast.KindPrivateKeyword
287+
case ast.KindJSDocPublicTag:
288+
keyword = ast.KindPublicKeyword
289+
case ast.KindJSDocProtectedTag:
290+
keyword = ast.KindProtectedKeyword
291+
case ast.KindJSDocOverrideTag:
292+
keyword = ast.KindOverrideKeyword
293+
}
294+
modifier := p.factory.NewModifier(keyword)
295+
modifier.Loc = tag.Loc
296+
modifier.Flags = p.contextFlags | ast.NodeFlagsReparsed
297+
var nodes []*ast.Node
298+
var loc core.TextRange
299+
if parent.Modifiers() == nil {
300+
nodes = p.nodeSlicePool.NewSlice(1)
301+
nodes[0] = modifier
302+
loc = tag.Loc
303+
} else {
304+
nodes = append(parent.Modifiers().Nodes, modifier)
305+
loc = parent.Modifiers().Loc
306+
}
307+
parent.AsMutable().SetModifiers(p.newModifierList(loc, nodes))
308+
}
271309
case ast.KindJSDocImplementsTag:
272310
if class := getClassLikeData(parent); class != nil {
273311
implementsTag := tag.AsJSDocImplementsTag()

0 commit comments

Comments
 (0)