@@ -97,23 +97,21 @@ namespace ts.formatting {
97
97
}
98
98
99
99
export function formatOnSemicolon ( position : number , sourceFile : SourceFile , rulesProvider : RulesProvider , options : FormatCodeSettings ) : TextChange [ ] {
100
- const outermostParent = findOutermostParentWithinListLevelFromPosition ( position , SyntaxKind . SemicolonToken , sourceFile ) ;
101
- return formatOutermostParent ( outermostParent , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnSemicolon ) ;
100
+ const semicolon = findImmediatelyPrecedingTokenOfKind ( position , SyntaxKind . SemicolonToken , sourceFile ) ;
101
+ return formatOutermostNodeWithinListLevel ( semicolon , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnSemicolon ) ;
102
102
}
103
103
104
104
export function formatOnOpeningCurly ( position : number , sourceFile : SourceFile , rulesProvider : RulesProvider , options : FormatCodeSettings ) : TextChange [ ] {
105
- const openingCurly = findPrecedingTokenOfKind ( position , SyntaxKind . FirstPunctuation , sourceFile ) ;
106
- const block = openingCurly && openingCurly . parent ;
107
- if ( ! ( block && isBlock ( block ) ) ) {
108
- return [ ] ;
109
- }
110
- const outermostParent = findOutermostParentWithinListLevel ( block ) ;
111
- return formatOutermostParent ( outermostParent , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnOpeningCurlyBrace ) ;
105
+ const openingCurly = findImmediatelyPrecedingTokenOfKind ( position , SyntaxKind . OpenBraceToken , sourceFile ) ;
106
+ const curlyBraceRange = openingCurly && openingCurly . parent ;
107
+ return curlyBraceRange ?
108
+ formatOutermostNodeWithinListLevel ( curlyBraceRange , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnOpeningCurlyBrace ) :
109
+ [ ] ;
112
110
}
113
111
114
112
export function formatOnClosingCurly ( position : number , sourceFile : SourceFile , rulesProvider : RulesProvider , options : FormatCodeSettings ) : TextChange [ ] {
115
- const outermostParent = findOutermostParentWithinListLevelFromPosition ( position , SyntaxKind . CloseBraceToken , sourceFile ) ;
116
- return formatOutermostParent ( outermostParent , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnClosingCurlyBrace ) ;
113
+ const precedingToken = findImmediatelyPrecedingTokenOfKind ( position , SyntaxKind . CloseBraceToken , sourceFile ) ;
114
+ return formatOutermostNodeWithinListLevel ( precedingToken , sourceFile , options , rulesProvider , FormattingRequestKind . FormatOnClosingCurlyBrace ) ;
117
115
}
118
116
119
117
export function formatDocument ( sourceFile : SourceFile , rulesProvider : RulesProvider , options : FormatCodeSettings ) : TextChange [ ] {
@@ -133,38 +131,21 @@ namespace ts.formatting {
133
131
return formatSpan ( span , sourceFile , options , rulesProvider , FormattingRequestKind . FormatSelection ) ;
134
132
}
135
133
136
- function formatOutermostParent ( parent : Node | undefined , sourceFile : SourceFile , options : FormatCodeSettings , rulesProvider : RulesProvider , requestKind : FormattingRequestKind ) : TextChange [ ] {
137
- if ( ! parent ) {
138
- return [ ] ;
139
- }
140
-
141
- const span = {
142
- pos : getLineStartPositionForPosition ( parent . getStart ( sourceFile ) , sourceFile ) ,
143
- end : parent . end
144
- } ;
145
-
146
- return formatSpan ( span , sourceFile , options , rulesProvider , requestKind ) ;
147
- }
148
-
149
- function findPrecedingTokenOfKind ( position : number , expectedTokenKind : SyntaxKind , sourceFile : SourceFile ) : Node | undefined {
150
- const precedingToken = findPrecedingToken ( position , sourceFile ) ;
151
-
152
- return precedingToken && precedingToken . kind === expectedTokenKind && position === precedingToken . getEnd ( ) ?
153
- precedingToken :
154
- undefined ;
155
- }
156
-
157
134
/**
158
135
* Validating `expectedLastToken` ensures the token was typed in the context we expect (eg: not a comment).
159
136
* @param expectedLastToken The last token constituting the desired parent node.
160
137
*/
161
- function findOutermostParentWithinListLevelFromPosition ( position : number , expectedLastToken : SyntaxKind , sourceFile : SourceFile ) {
162
- const precedingToken = findPrecedingTokenOfKind ( position , expectedLastToken , sourceFile ) ;
163
- return precedingToken && findOutermostParentWithinListLevel ( precedingToken ) ;
138
+ function findImmediatelyPrecedingTokenOfKind ( end : number , expectedTokenKind : SyntaxKind , sourceFile : SourceFile ) : Node | undefined {
139
+ const precedingToken = findPrecedingToken ( end , sourceFile ) ;
140
+
141
+ return precedingToken && precedingToken . kind === expectedTokenKind && end === precedingToken . getEnd ( ) ?
142
+ precedingToken :
143
+ undefined ;
164
144
}
165
145
166
146
/**
167
- * Finds the outermost parent within the same list level as the token at position.
147
+ * Finds and formats the highest node enclosing `position` whose end does not exceed the given position
148
+ * and is at the same list level as the token at `position`.
168
149
*
169
150
* Consider typing the following
170
151
* ```
@@ -175,18 +156,18 @@ namespace ts.formatting {
175
156
* Upon typing the closing curly, we want to format the entire `while`-statement, but not the preceding
176
157
* variable declaration.
177
158
*/
178
- function findOutermostParentWithinListLevel ( token : Node ) : Node {
159
+ function formatOutermostNodeWithinListLevel ( node : Node , sourceFile : SourceFile , options : FormatCodeSettings , rulesProvider : RulesProvider , formattingRequestKind : FormattingRequestKind ) {
179
160
// If we walk upwards searching for the parent that has the same end value, we'll end up with the whole source file.
180
161
// `isListElement` allows to stop on the list element level.
181
- let current = token ;
162
+ let current = node ;
182
163
while ( current &&
183
164
current . parent &&
184
- current . parent . end === token . end &&
165
+ current . parent . end === node . end &&
185
166
! isListElement ( current . parent , current ) ) {
186
167
current = current . parent ;
187
168
}
188
169
189
- return current ;
170
+ return formatNodeLines ( current , sourceFile , options , rulesProvider , formattingRequestKind ) ;
190
171
}
191
172
192
173
// Returns true if node is a element in some list in parent
@@ -338,7 +319,7 @@ namespace ts.formatting {
338
319
}
339
320
340
321
/* @internal */
341
- export function formatNode ( node : Node , sourceFileLike : SourceFileLike , languageVariant : LanguageVariant , initialIndentation : number , delta : number , rulesProvider : RulesProvider ) : TextChange [ ] {
322
+ export function formatNodeGivenIndentation ( node : Node , sourceFileLike : SourceFileLike , languageVariant : LanguageVariant , initialIndentation : number , delta : number , rulesProvider : RulesProvider ) : TextChange [ ] {
342
323
const range = { pos : 0 , end : sourceFileLike . text . length } ;
343
324
return formatSpanWorker (
344
325
range ,
@@ -353,6 +334,19 @@ namespace ts.formatting {
353
334
sourceFileLike ) ;
354
335
}
355
336
337
+ function formatNodeLines ( node : Node , sourceFile : SourceFile , options : FormatCodeSettings , rulesProvider : RulesProvider , requestKind : FormattingRequestKind ) : TextChange [ ] {
338
+ if ( ! node ) {
339
+ return [ ] ;
340
+ }
341
+
342
+ const span = {
343
+ pos : getLineStartPositionForPosition ( node . getStart ( sourceFile ) , sourceFile ) ,
344
+ end : node . end
345
+ } ;
346
+
347
+ return formatSpan ( span , sourceFile , options , rulesProvider , requestKind ) ;
348
+ }
349
+
356
350
function formatSpan ( originalRange : TextRange ,
357
351
sourceFile : SourceFile ,
358
352
options : FormatCodeSettings ,
0 commit comments