Skip to content

Commit 3be15ad

Browse files
authored
feat: go docs to be formatted as JSDocs (#61)
Converts Golang style docs to JSDocs format.
1 parent 3f5ec56 commit 3be15ad

File tree

13 files changed

+123
-17
lines changed

13 files changed

+123
-17
lines changed

bindings/bindings.go

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package bindings
22

33
import (
44
"fmt"
5+
"strings"
56

67
"github.com/dop251/goja"
78
"golang.org/x/xerrors"
@@ -733,8 +734,47 @@ func (b *Bindings) CommentGojaObject(comments []SyntheticComment, object *goja.O
733734
return nil, err
734735
}
735736

736-
node := object
737+
// Group all comments that should be included into a JSDoc block.
738+
jsDoc := make([]SyntheticComment, 0)
739+
rest := make([]SyntheticComment, 0)
740+
737741
for _, c := range comments {
742+
if !c.DoNotFormat && c.Leading && c.SingleLine {
743+
jsDoc = append(jsDoc, c)
744+
continue
745+
}
746+
rest = append(rest, c)
747+
}
748+
749+
// JSDoc comments should be blocked together
750+
node := object
751+
if len(jsDoc) > 0 {
752+
var jsDocComment strings.Builder
753+
// JSDoc requires '/**' start and ' */' end. The default synthetic comment only places 1 '*'.
754+
// So include the second '*', and start the comment line.
755+
jsDocComment.WriteString("*\n *")
756+
sep := ""
757+
for _, cmt := range jsDoc {
758+
jsDocComment.WriteString(sep)
759+
jsDocComment.WriteString(cmt.Text)
760+
sep = "\n *"
761+
}
762+
jsDocComment.WriteString("\n ")
763+
764+
res, err := commentF(goja.Undefined(),
765+
node,
766+
b.vm.ToValue(true),
767+
b.vm.ToValue(false),
768+
b.vm.ToValue(jsDocComment.String()),
769+
b.vm.ToValue(true),
770+
)
771+
if err != nil {
772+
return nil, xerrors.Errorf("call addSyntheticComment for JSDoc: %w", err)
773+
}
774+
node = res.ToObject(b.vm)
775+
}
776+
777+
for _, c := range rest {
738778
res, err := commentF(goja.Undefined(),
739779
node,
740780
b.vm.ToValue(c.Leading),

bindings/comments.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,24 @@ type SyntheticComment struct {
1919
SingleLine bool
2020
Text string
2121
TrailingNewLine bool
22+
23+
// DoNotFormat indicates this comment should not be attempted to be reformatted.
24+
// Guts will attempt to format comments into JSDoc style comments where possible.
25+
DoNotFormat bool
2226
}
2327

2428
type SupportComments struct {
2529
comments []SyntheticComment
2630
}
2731

28-
// LeadingComment is a helper function for the most common type of comment.
2932
func (s *SupportComments) LeadingComment(text string) {
3033
s.AppendComment(SyntheticComment{
3134
Leading: true,
3235
SingleLine: true,
3336
// All go comments are `// ` prefixed, so add a space.
3437
Text: " " + text,
3538
TrailingNewLine: false,
39+
DoNotFormat: true,
3640
})
3741
}
3842

@@ -66,5 +70,6 @@ func (s Source) SourceComment() (SyntheticComment, bool) {
6670
SingleLine: true,
6771
Text: fmt.Sprintf(" From %s", s.File),
6872
TrailingNewLine: false,
73+
DoNotFormat: true,
6974
}, s.File != ""
7075
}

config/mutations.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,3 +417,24 @@ func isGoEnum(n bindings.Node) (*bindings.Alias, *bindings.UnionType, bool) {
417417

418418
return al, union, true
419419
}
420+
421+
// NoJSDocTransform prevents `guts` from reformatting Golang comments to JSDoc.
422+
// JSDoc comments use `/** */` style multi-line comments.
423+
func NoJSDocTransform(ts *guts.Typescript) {
424+
ts.ForEach(func(key string, node bindings.Node) {
425+
walk.Walk(&noJSDocTransformWalker{}, node)
426+
})
427+
}
428+
429+
type noJSDocTransformWalker struct{}
430+
431+
func (v *noJSDocTransformWalker) Visit(node bindings.Node) walk.Visitor {
432+
if commentedNode, ok := node.(bindings.Commentable); ok {
433+
comments := commentedNode.Comments()
434+
for i := range comments {
435+
comments[i].DoNotFormat = true
436+
}
437+
}
438+
439+
return v
440+
}

convert_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ func TestGeneration(t *testing.T) {
130130
mutations = append(mutations, config.InterfaceToType)
131131
case "BiomeLintIgnoreAnyTypeParameters":
132132
mutations = append(mutations, config.BiomeLintIgnoreAnyTypeParameters)
133+
case "NoJSDocTransform":
134+
mutations = append(mutations, config.NoJSDocTransform)
133135
default:
134136
t.Fatal("unknown mutation, add it to the list:", m)
135137
}

testdata/comments/comments.ts

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,26 @@ export interface BlockComment {
88
}
99

1010
// From comments/comments.go
11-
// CommentedStructure is a struct with a comment.
12-
//
13-
// It actually has 2 comments?!
14-
// TODO: Maybe add a third comment!
11+
/**
12+
* CommentedStructure is a struct with a comment.
13+
*
14+
* It actually has 2 comments?!
15+
* TODO: Maybe add a third comment!
16+
*/
1517
export interface CommentedStructure {
1618
readonly Inline: string; // Field comment
17-
// Leading comment
19+
/**
20+
* Leading comment
21+
*/
1822
readonly Leading: string;
1923
readonly Trailing: string;
20-
// Leading comment
24+
/**
25+
* Leading comment
26+
*/
2127
readonly All: string; // Inline comment
22-
// Another leading comment
28+
/**
29+
* Another leading comment
30+
*/
2331
readonly Block: string;
2432
/* Multi
2533
Line
@@ -29,7 +37,9 @@ export interface CommentedStructure {
2937
}
3038

3139
// From comments/comments.go
32-
// Constant is just a value
40+
/**
41+
* Constant is just a value
42+
*/
3343
export const Constant = "value"; // An inline note
3444

3545

testdata/enums/enums.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ export enum EnumInt {
1414
}
1515

1616
// From enums/enums.go
17-
// EnumSliceType is a slice of string-based enums
17+
/**
18+
* EnumSliceType is a slice of string-based enums
19+
*/
1820
export type EnumSliceType = readonly EnumString[];
1921

2022
// From enums/enums.go

testdata/generics/generics.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ export interface Complex<C extends Comparable, S extends Single, T extends Custo
2525
export type Custom = string | boolean | number | number | string[] | (number | null);
2626

2727
// From codersdk/generics.go
28-
// Dynamic has some dynamic fields.
28+
/**
29+
* Dynamic has some dynamic fields.
30+
*/
2931
export interface Dynamic<A extends any, S extends Single> {
3032
readonly dynamic: Fields<boolean, A, string, S>;
3133
readonly comparable: boolean | null;
@@ -49,7 +51,9 @@ export interface FieldsDiffOrder<A extends any, C extends Comparable, S extends
4951
export type Single = string;
5052

5153
// From codersdk/generics.go
52-
// Static has all generic fields defined in the field
54+
/**
55+
* Static has all generic fields defined in the field
56+
*/
5357
export interface Static {
5458
readonly static: Fields<string, number, number, string>;
5559
}

testdata/inheritance/inheritance.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ export interface FooBarPtr extends Bar, GenBar<string> {
2121
}
2222

2323
// From codersdk/inheritance.go
24-
// FooBuzz has a json tag for the embedded
25-
// See: https://go.dev/play/p/-p6QYmY8mtR
24+
/**
25+
* FooBuzz has a json tag for the embedded
26+
* See: https://go.dev/play/p/-p6QYmY8mtR
27+
*/
2628
export interface FooBuzz {
2729
readonly foo: Buzz; // Json tag changes the inheritance
2830
readonly bazz: string;

testdata/nojsdoc/mutations

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
NoJSDocTransform

testdata/nojsdoc/nojsdoc.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package nojsdoc
2+
3+
// Commented is a struct that does nothing
4+
type Commented struct {
5+
// Nothing is not very helpful
6+
Nothing string
7+
}

0 commit comments

Comments
 (0)