Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.

Commit 418506c

Browse files
DaivikDaveStephen Gutekanst
authored and
Stephen Gutekanst
committed
indexer/javascript: parse jsdoc class comments
1 parent 25718e0 commit 418506c

File tree

1 file changed

+126
-57
lines changed

1 file changed

+126
-57
lines changed

doctree/indexer/javascript/indexer.go

+126-57
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ func (i *javascriptIndexer) IndexDir(ctx context.Context, dir string) (*schema.I
177177
className := firstCaptureContentOr(content, captures["class_name"], "")
178178
superClasses := firstCaptureContentOr(content, captures["superclasses"], "")
179179
classDocs := firstCaptureContentOr(content, captures["class_docs"], "\n")
180-
classDocs = sanitizeDocs(classDocs)
180+
classDocs = extractClassDocs(classDocs)
181181

182182
classLabel := schema.Markdown("class " + className + superClasses)
183183
classes := classesByMod[modName]
@@ -317,80 +317,149 @@ func getFunctions(node *sitter.Node, content []byte, q string, searchKeyPrefix [
317317
return functions, nil
318318
}
319319

320-
func extractFunctionDocs(s string) string {
320+
func extractClassDocs(s string) string {
321321
// JSDoc comments must start with a /**
322322
// sequence in order to be recognized by the JSDoc parser.
323323
// Comments beginning with /*, /***, or more than 3 stars are ignored by Jsdoc Parser.
324-
if strings.HasPrefix(s, "/**") && !strings.HasPrefix(s, "/***") {
325-
comment := []byte(s)
326-
funcDocs := ""
327-
node, err := sitter.ParseCtx(context.Background(), comment, jsdoc.GetLanguage())
328-
if err != nil {
329-
return ""
324+
if !strings.HasPrefix(s, "/**") && strings.HasPrefix(s, "/***") {
325+
return sanitizeDocs(s)
326+
}
327+
328+
comment := []byte(s)
329+
classDocs := ""
330+
node, err := sitter.ParseCtx(context.Background(), comment, jsdoc.GetLanguage())
331+
if err != nil {
332+
return ""
333+
}
334+
query, err := sitter.NewQuery([]byte(`
335+
(document
336+
(description)? @class_description
337+
(tag
338+
(tag_name)? @tag_name
339+
(type)? @identifier_type
340+
(identifier)? @identifier_name
341+
(description)? @identifier_description
342+
)
343+
)*
344+
`), jsdoc.GetLanguage())
345+
if err != nil {
346+
return ""
347+
}
348+
349+
defer query.Close()
350+
351+
cursor := sitter.NewQueryCursor()
352+
defer cursor.Close()
353+
cursor.Exec(query, node)
354+
355+
propertiesSection := ""
356+
for {
357+
match, ok := cursor.NextMatch()
358+
if !ok {
359+
break
330360
}
331-
query, err := sitter.NewQuery([]byte(`
332-
(document
333-
(description)? @func_description
334-
(tag
335-
(tag_name)? @tag_name
336-
(type)? @identifier_type
337-
(identifier)? @identifier_name
338-
(description)? @identifier_description
339-
)
340-
)*
341-
`), jsdoc.GetLanguage())
342-
if err != nil {
343-
return ""
361+
captures := getCaptures(query, match)
362+
classDescription := firstCaptureContentOr(comment, captures["class_description"], "")
363+
classDocs = fmt.Sprintf("%s\n", classDescription)
364+
365+
identifierType := firstCaptureContentOr(comment, captures["identifier_type"], "")
366+
if identifierType != "" {
367+
identifierType = fmt.Sprintf(" (%s)", identifierType)
368+
}
369+
identifierName := firstCaptureContentOr(comment, captures["identifier_name"], "")
370+
identifierDescription := firstCaptureContentOr(comment, captures["identifier_description"], "")
371+
if identifierDescription != "" {
372+
identifierDescription = fmt.Sprintf(": %s", identifierDescription)
344373
}
345374

346-
defer query.Close()
375+
tagName := firstCaptureContentOr(comment, captures["tag_name"], "")
376+
switch tagName {
377+
case "@property":
378+
propertiesSection += fmt.Sprintf("\n\t%s%s%s", identifierName, identifierType, identifierDescription)
379+
}
380+
}
347381

348-
cursor := sitter.NewQueryCursor()
349-
defer cursor.Close()
350-
cursor.Exec(query, node)
382+
if len(propertiesSection) > 0 {
383+
classDocs += fmt.Sprintf("\n Properties:\n%s", propertiesSection)
384+
}
351385

352-
argsSection := ""
353-
returnSection := ""
354-
for {
355-
match, ok := cursor.NextMatch()
356-
if !ok {
357-
break
358-
}
359-
captures := getCaptures(query, match)
360-
funcDescription := firstCaptureContentOr(comment, captures["func_description"], "")
361-
funcDocs = fmt.Sprintf("%s\n", funcDescription)
386+
return classDocs
387+
}
362388

363-
identifierType := firstCaptureContentOr(comment, captures["identifier_type"], "")
364-
if identifierType != "" {
365-
identifierType = fmt.Sprintf(" (%s)", identifierType)
366-
}
367-
identifierName := firstCaptureContentOr(comment, captures["identifier_name"], "")
368-
identifierDescription := firstCaptureContentOr(comment, captures["identifier_description"], "")
369-
if identifierDescription != "" {
370-
identifierDescription = fmt.Sprintf(": %s", identifierDescription)
371-
}
389+
func extractFunctionDocs(s string) string {
390+
// JSDoc comments must start with a /**
391+
// sequence in order to be recognized by the JSDoc parser.
392+
// Comments beginning with /*, /***, or more than 3 stars are ignored by Jsdoc Parser.
393+
if !strings.HasPrefix(s, "/**") && strings.HasPrefix(s, "/***") {
394+
return sanitizeDocs(s)
395+
}
372396

373-
tagName := firstCaptureContentOr(comment, captures["tag_name"], "")
374-
switch tagName {
375-
case "@param":
376-
argsSection += fmt.Sprintf("\n\t%s%s%s", identifierName, identifierType, identifierDescription)
377-
case "@return":
378-
returnSection += fmt.Sprintf("\n\t%s%s%s", identifierName, identifierType, identifierDescription)
379-
}
397+
comment := []byte(s)
398+
funcDocs := ""
399+
node, err := sitter.ParseCtx(context.Background(), comment, jsdoc.GetLanguage())
400+
if err != nil {
401+
return ""
402+
}
403+
query, err := sitter.NewQuery([]byte(`
404+
(document
405+
(description)? @func_description
406+
(tag
407+
(tag_name)? @tag_name
408+
(type)? @identifier_type
409+
(identifier)? @identifier_name
410+
(description)? @identifier_description
411+
)
412+
)*
413+
`), jsdoc.GetLanguage())
414+
if err != nil {
415+
return ""
416+
}
417+
418+
defer query.Close()
419+
420+
cursor := sitter.NewQueryCursor()
421+
defer cursor.Close()
422+
cursor.Exec(query, node)
423+
424+
argsSection := ""
425+
returnSection := ""
426+
for {
427+
match, ok := cursor.NextMatch()
428+
if !ok {
429+
break
380430
}
431+
captures := getCaptures(query, match)
432+
funcDescription := firstCaptureContentOr(comment, captures["func_description"], "")
433+
funcDocs = fmt.Sprintf("%s\n", funcDescription)
381434

382-
if len(argsSection) > 0 {
383-
funcDocs += fmt.Sprintf("\n Arguments:\n%s", argsSection)
435+
identifierType := firstCaptureContentOr(comment, captures["identifier_type"], "")
436+
if identifierType != "" {
437+
identifierType = fmt.Sprintf(" (%s)", identifierType)
438+
}
439+
identifierName := firstCaptureContentOr(comment, captures["identifier_name"], "")
440+
identifierDescription := firstCaptureContentOr(comment, captures["identifier_description"], "")
441+
if identifierDescription != "" {
442+
identifierDescription = fmt.Sprintf(": %s", identifierDescription)
384443
}
385444

386-
if len(returnSection) > 0 {
387-
funcDocs += fmt.Sprintf("\n Returns:\n%s", returnSection)
445+
tagName := firstCaptureContentOr(comment, captures["tag_name"], "")
446+
switch tagName {
447+
case "@param":
448+
argsSection += fmt.Sprintf("\n\t%s%s%s", identifierName, identifierType, identifierDescription)
449+
case "@return":
450+
returnSection += fmt.Sprintf("\n\t%s%s%s", identifierName, identifierType, identifierDescription)
388451
}
452+
}
453+
454+
if len(argsSection) > 0 {
455+
funcDocs += fmt.Sprintf("\n Arguments:\n%s", argsSection)
456+
}
389457

390-
return funcDocs
458+
if len(returnSection) > 0 {
459+
funcDocs += fmt.Sprintf("\n Returns:\n%s", returnSection)
391460
}
392461

393-
return sanitizeDocs(s)
462+
return funcDocs
394463
}
395464

396465
func sanitizeDocs(s string) string {

0 commit comments

Comments
 (0)