Source file
src/go/printer/comment.go
1
2
3
4
5 package printer
6
7 import (
8 "go/ast"
9 "go/doc/comment"
10 "strings"
11 )
12
13
14
15 func formatDocComment(list []*ast.Comment) []*ast.Comment {
16
17 var kind, text string
18 var directives []*ast.Comment
19 if len(list) == 1 && strings.HasPrefix(list[0].Text, "/*") {
20 kind = "/*"
21 text = list[0].Text
22 if !strings.Contains(text, "\n") || allStars(text) {
23
24
25
26
27
28
29
30
31
32 return list
33 }
34 text = text[2 : len(text)-2]
35 } else if strings.HasPrefix(list[0].Text, "//") {
36 kind = "//"
37 var b strings.Builder
38 for _, c := range list {
39 after, found := strings.CutPrefix(c.Text, "//")
40 if !found {
41 return list
42 }
43
44 if isDirective(after) {
45 directives = append(directives, c)
46 continue
47 }
48 b.WriteString(strings.TrimPrefix(after, " "))
49 b.WriteString("\n")
50 }
51 text = b.String()
52 } else {
53
54 return list
55 }
56
57 if text == "" {
58 return list
59 }
60
61
62 var p comment.Parser
63 d := p.Parse(text)
64
65 var pr comment.Printer
66 text = string(pr.Comment(d))
67
68
69 slash := list[0].Slash
70 if kind == "/*" {
71 c := &ast.Comment{
72 Slash: slash,
73 Text: "/*\n" + text + "*/",
74 }
75 return []*ast.Comment{c}
76 }
77
78
79 var out []*ast.Comment
80 for text != "" {
81 var line string
82 line, text, _ = strings.Cut(text, "\n")
83 if line == "" {
84 line = "//"
85 } else if strings.HasPrefix(line, "\t") {
86 line = "//" + line
87 } else {
88 line = "// " + line
89 }
90 out = append(out, &ast.Comment{
91 Slash: slash,
92 Text: line,
93 })
94 }
95 if len(directives) > 0 {
96 out = append(out, &ast.Comment{
97 Slash: slash,
98 Text: "//",
99 })
100 for _, c := range directives {
101 out = append(out, &ast.Comment{
102 Slash: slash,
103 Text: c.Text,
104 })
105 }
106 }
107 return out
108 }
109
110
111
112
113 func isDirective(c string) bool {
114
115
116
117
118 if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") {
119 return true
120 }
121
122
123
124 colon := strings.Index(c, ":")
125 if colon <= 0 || colon+1 >= len(c) {
126 return false
127 }
128 for i := 0; i <= colon+1; i++ {
129 if i == colon {
130 continue
131 }
132 b := c[i]
133 if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
134 return false
135 }
136 }
137 return true
138 }
139
140
141
142 func allStars(text string) bool {
143 for i := 0; i < len(text); i++ {
144 if text[i] == '\n' {
145 j := i + 1
146 for j < len(text) && (text[j] == ' ' || text[j] == '\t') {
147 j++
148 }
149 if j < len(text) && text[j] != '*' {
150 return false
151 }
152 }
153 }
154 return true
155 }
156
View as plain text