5
5
package golang
6
6
7
7
import (
8
- "bytes"
9
8
"cmp"
10
9
"context"
11
10
"go/ast"
@@ -65,7 +64,7 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
65
64
switch n := cur .Node ().(type ) {
66
65
case * ast.BlockStmt :
67
66
// Fold between positions of or lines between "{" and "}".
68
- start , end = getLineFoldingRange ( pgf , n .Lbrace , n .Rbrace , lineFoldingOnly )
67
+ start , end = bracketedFoldingRange ( n .Lbrace , n .Rbrace )
69
68
70
69
case * ast.CaseClause :
71
70
// Fold from position of ":" to end.
@@ -77,19 +76,19 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
77
76
78
77
case * ast.CallExpr :
79
78
// Fold between positions of or lines between "(" and ")".
80
- start , end = getLineFoldingRange ( pgf , n .Lparen , n .Rparen , lineFoldingOnly )
79
+ start , end = bracketedFoldingRange ( n .Lparen , n .Rparen )
81
80
82
81
case * ast.FieldList :
83
82
// Fold between positions of or lines between opening parenthesis/brace and closing parenthesis/brace.
84
- start , end = getLineFoldingRange ( pgf , n .Opening , n .Closing , lineFoldingOnly )
83
+ start , end = bracketedFoldingRange ( n .Opening , n .Closing )
85
84
86
85
case * ast.GenDecl :
87
86
// If this is an import declaration, set the kind to be protocol.Imports.
88
87
if n .Tok == token .IMPORT {
89
88
kind = protocol .Imports
90
89
}
91
90
// Fold between positions of or lines between "(" and ")".
92
- start , end = getLineFoldingRange ( pgf , n .Lparen , n .Rparen , lineFoldingOnly )
91
+ start , end = bracketedFoldingRange ( n .Lparen , n .Rparen )
93
92
94
93
case * ast.BasicLit :
95
94
// Fold raw string literals from position of "`" to position of "`".
@@ -99,7 +98,7 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
99
98
100
99
case * ast.CompositeLit :
101
100
// Fold between positions of or lines between "{" and "}".
102
- start , end = getLineFoldingRange ( pgf , n .Lbrace , n .Rbrace , lineFoldingOnly )
101
+ start , end = bracketedFoldingRange ( n .Lbrace , n .Rbrace )
103
102
104
103
default :
105
104
panic (n )
@@ -136,9 +135,9 @@ func FoldingRange(ctx context.Context, snapshot *cache.Snapshot, fh file.Handle,
136
135
return ranges , nil
137
136
}
138
137
139
- // getLineFoldingRange returns the folding range for nodes with parentheses/braces/brackets
138
+ // bracketedFoldingRange returns the folding range for nodes with parentheses/braces/brackets
140
139
// that potentially can take up multiple lines.
141
- func getLineFoldingRange ( pgf * parsego. File , open , close token.Pos , lineFoldingOnly bool ) (token.Pos , token.Pos ) {
140
+ func bracketedFoldingRange ( open , close token.Pos ) (token.Pos , token.Pos ) {
142
141
if ! open .IsValid () || ! close .IsValid () {
143
142
return token .NoPos , token .NoPos
144
143
}
@@ -147,56 +146,38 @@ func getLineFoldingRange(pgf *parsego.File, open, close token.Pos, lineFoldingOn
147
146
return token .NoPos , token .NoPos
148
147
}
149
148
150
- if ! lineFoldingOnly {
151
- // Can fold between opening and closing parenthesis/brace
152
- // even if they are on the same line.
153
- return open + 1 , close
154
- }
155
-
156
149
// Clients with "LineFoldingOnly" set to true can fold only full lines.
157
- // So, we return a folding range only when the closing parenthesis/brace
158
- // and the end of the last argument/statement/element are on different lines.
150
+ // This is checked in the caller.
159
151
//
160
- // We could skip the check for the opening parenthesis/brace and start of
161
- // the first argument/statement/element. For example, the following code
152
+ // Clients that support folding ranges can display them in various ways
153
+ // (e.g., how are folding ranges marked? is the final line displayed?).
154
+ // The most common client
155
+ // is vscode, which displays the first line followed by ..., and then does not
156
+ // display any other lines in the range, but other clients might also display
157
+ // final line of the range. For example, the following code
162
158
//
163
159
// var x = []string{"a",
164
160
// "b",
165
161
// "c" }
166
162
//
167
- // can be folded to
163
+ // can be folded (in vscode) to
164
+ //
165
+ // var x = []string{"a", ...
166
+ //
167
+ // or in some other client
168
168
//
169
169
// var x = []string{"a", ...
170
170
// "c" }
171
171
//
172
- // However, this might look confusing. So, check the lines of "open" and
173
- // "start" positions as well.
174
-
175
- // isOnlySpaceBetween returns true if there are only space characters between "from" and "to".
176
- isOnlySpaceBetween := func (from token.Pos , to token.Pos ) bool {
177
- text , err := pgf .PosText (from , to )
178
- if err != nil {
179
- bug .Reportf ("failed to get offsets: %s" , err ) // can't happen
180
- return false
181
- }
182
- return len (bytes .TrimSpace (text )) == 0
183
- }
184
-
185
- nextLine := safetoken .Line (pgf .Tok , open ) + 1
186
- if nextLine > pgf .Tok .LineCount () {
187
- return token .NoPos , token .NoPos
188
- }
189
- nextLineStart := pgf .Tok .LineStart (nextLine )
190
- if ! isOnlySpaceBetween (open + 1 , nextLineStart ) {
191
- return token .NoPos , token .NoPos
192
- }
193
-
194
- prevLineEnd := pgf .Tok .LineStart (safetoken .Line (pgf .Tok , close )) - 1 // there must be a previous line
195
- if ! isOnlySpaceBetween (prevLineEnd , close ) {
196
- return token .NoPos , token .NoPos
197
- }
172
+ // This is a change in behavior. The old code would not fold this example,
173
+ // nor would it have folded
174
+ //
175
+ // func foo() { // a non-godoc comment
176
+ // ...
177
+ // }
178
+ // which seems wrong.
198
179
199
- return open + 1 , prevLineEnd
180
+ return open + 1 , close
200
181
}
201
182
202
183
// commentsFoldingRange returns the folding ranges for all comment blocks in file.
0 commit comments