@@ -24,7 +24,6 @@ module ts.formatting {
2424 getEffectiveCommentIndentation ( commentLine : number ) : number ;
2525 getDelta ( ) : number ;
2626 getIndentation ( ) : number ;
27- setDelta ( delta : number ) : number ;
2827 getCommentIndentation ( ) : number ;
2928 increaseCommentIndentation ( delta : number ) : void ;
3029 recomputeIndentation ( lineAddedByFormatting : boolean ) : void ;
@@ -252,23 +251,9 @@ module ts.formatting {
252251 increaseCommentIndentation : ( delta ) => {
253252 commentIndentation += delta ;
254253 } ,
255- setDelta ( newDelta : number ) : number {
256- var old = delta ;
257- delta = newDelta ;
258- return old ;
259- }
260254 }
261255 }
262256
263- function getListItemIndentation ( node : Node , parentStartLine : number , options : EditorOptions ) : number {
264- var start = node . getStart ( sourceFile ) ;
265- var nodeStartLine = sourceFile . getLineAndCharacterFromPosition ( start ) . line ;
266- var startLinePosition = getStartPositionOfLine ( nodeStartLine , sourceFile ) ;
267- var shareLine = nodeStartLine === parentStartLine ;
268- var column = SmartIndenter . findFirstNonWhitespaceColumn ( startLinePosition , start , sourceFile , options ) ;
269- return shareLine && start !== column ? Indentation . Unknown : column ;
270- }
271-
272257 function processNode ( node : Node , contextNode : Node , nodeStartLine : number , indentation : number , delta : number ) {
273258 if ( ! rangeOverlapsWithStartEnd ( originalRange , node . getStart ( sourceFile ) , node . getEnd ( ) ) ) {
274259 return ;
@@ -280,47 +265,45 @@ module ts.formatting {
280265 forEachChild (
281266 node ,
282267 child => {
283- processChildNode ( child , Indentation . Unknown , nodeStartLine , /*isListElement*/ false )
268+ processChildNode ( child , Indentation . Unknown , nodeIndentation , nodeStartLine , /*isListElement*/ false )
284269 } ,
285- nodes => {
270+ ( nodes : NodeArray < Node > ) => {
286271 var listStartToken = getOpenTokenForList ( node , nodes ) ;
287272 var listEndToken = getCloseTokenForOpenToken ( listStartToken ) ;
288273
274+ var listIndentation = nodeIndentation ;
275+
289276 if ( listStartToken !== SyntaxKind . Unknown ) {
290277 // try to consume open token
291- if ( formattingScanner . isOnToken ( ) ) {
278+ while ( formattingScanner . isOnToken ( ) ) {
292279 var tokenInfo = formattingScanner . readTokenInfo ( node ) ;
293- if ( tokenInfo . token . kind === listStartToken ) {
280+ if ( tokenInfo . token . end > nodes . pos ) {
281+ break ;
282+ }
283+ else if ( tokenInfo . token . kind === listStartToken ) {
294284 var tokenStartLine = sourceFile . getLineAndCharacterFromPosition ( tokenInfo . token . pos ) . line ;
285+ var indentation = computeIndentation ( tokenInfo . token , tokenStartLine , Indentation . Unknown , node , nodeStartLine ) ;
286+ listIndentation = getDynamicIndentation ( node , nodeStartLine , indentation . indentation , indentation . indentation , indentation . delta ) ;
295287 // make sure that this token does not belong to the child
296- var startTokenIndentation = nodeIndentation ;
297- var tokenStartLine = sourceFile . getLineAndCharacterFromPosition ( tokenInfo . token . pos ) . line ;
298- var oldDelta = - 1 ;
299- if ( node . parent . kind !== SyntaxKind . SourceFile && tokenStartLine !== nodeStartLine ) {
300- oldDelta = nodeIndentation . setDelta ( options . IndentSize ) ;
301- }
302- consumeTokenAndAdvanceScanner ( tokenInfo , node , startTokenIndentation ) ;
303- if ( oldDelta !== - 1 ) {
304- nodeIndentation . setDelta ( oldDelta ) ;
305- }
288+ consumeTokenAndAdvanceScanner ( tokenInfo , node , listIndentation ) ;
289+ }
290+ else {
291+ consumeTokenAndAdvanceScanner ( tokenInfo , node , nodeIndentation ) ;
306292 }
307293 }
308294 }
309295
310296 var inheritedIndentation : number = Indentation . Unknown ;
311297 var effectiveStartLine = tokenStartLine || nodeStartLine ;
312298 for ( var i = 0 , len = nodes . length ; i < len ; ++ i ) {
313- inheritedIndentation = processChildNode ( nodes [ i ] , inheritedIndentation , effectiveStartLine , /*isListElement*/ true )
299+ inheritedIndentation = processChildNode ( nodes [ i ] , inheritedIndentation , listIndentation , effectiveStartLine , /*isListElement*/ true )
314300 }
315301
316302 if ( listEndToken !== SyntaxKind . Unknown ) {
317303 if ( formattingScanner . isOnToken ( ) ) {
318304 var tokenInfo = formattingScanner . readTokenInfo ( node ) ;
319305 if ( tokenInfo . token . kind === listEndToken && formattingScanner . lastTrailingTriviaWasNewLine ( ) ) {
320- var old = nodeIndentation . setDelta ( options . IndentSize ) ;
321- //var endTokenIndentation = nodeIndentation.getIndentation() + options.IndentSize;
322- consumeTokenAndAdvanceScanner ( tokenInfo , node , nodeIndentation ) ;
323- nodeIndentation . setDelta ( old ) ;
306+ consumeTokenAndAdvanceScanner ( tokenInfo , node , listIndentation ) ;
324307 }
325308 }
326309 }
@@ -342,17 +325,18 @@ module ts.formatting {
342325 function processChildNode (
343326 child : Node ,
344327 inheritedIndentation : number ,
345- childEffectiveStartLine : number ,
346- isListElement : boolean ) : number {
328+ nodeIndentation : DynamicIndentation ,
329+ effectiveParentStartLine : number ,
330+ isListItem : boolean ) : number {
347331
348332 if ( child . kind === SyntaxKind . Missing ) {
349333 return inheritedIndentation ;
350334 }
351335
352- var start = child . getStart ( sourceFile ) ;
336+ var childStartPos = child . getStart ( sourceFile ) ;
353337 while ( formattingScanner . isOnToken ( ) ) {
354338 var tokenInfo = formattingScanner . readTokenInfo ( node ) ;
355- if ( tokenInfo . token . end > start ) {
339+ if ( tokenInfo . token . end > childStartPos ) {
356340 break ;
357341 }
358342
@@ -363,23 +347,14 @@ module ts.formatting {
363347 return inheritedIndentation ;
364348 }
365349
366- var childStart = sourceFile . getLineAndCharacterFromPosition ( start ) ;
367- var actualIndentation = inheritedIndentation ;
368- var childIndentationAmount = Indentation . Unknown ;
369- var childDelta = 0 ;
370- var isChildInRange = rangeOverlapsWithStartEnd ( originalRange , start , child . getEnd ( ) ) ;
371- if ( isListElement ) {
372- if ( isChildInRange ) {
373- if ( inheritedIndentation !== Indentation . Unknown ) {
374- childIndentationAmount = inheritedIndentation ;
375- }
376- }
377- else {
378- var actualIndentation = getListItemIndentation ( child , childEffectiveStartLine , options ) ;
379- if ( actualIndentation !== Indentation . Unknown ) {
380- inheritedIndentation = childIndentationAmount = actualIndentation ;
381- }
382- }
350+ var childStart = sourceFile . getLineAndCharacterFromPosition ( childStartPos ) ;
351+ var childIndentationAmount =
352+ isListItem
353+ ? tryComputeIndentationForListItem ( childStartPos , child . end , effectiveParentStartLine , originalRange , inheritedIndentation )
354+ : Indentation . Unknown ;
355+
356+ if ( isListItem && childIndentationAmount !== Indentation . Unknown ) {
357+ inheritedIndentation = childIndentationAmount ;
383358 }
384359
385360 if ( isToken ( child ) ) {
@@ -389,40 +364,77 @@ module ts.formatting {
389364 return inheritedIndentation ;
390365 }
391366
392- if ( childIndentationAmount === Indentation . Unknown ) {
393- if ( isSomeBlock ( child . kind ) ) {
394- // child is indented
395- childDelta = options . IndentSize ;
396- if ( isSomeBlock ( node . kind ) || node . kind === SyntaxKind . SourceFile || node . kind === SyntaxKind . CaseClause || node . kind === SyntaxKind . DefaultClause ) {
397- childIndentationAmount = nodeIndentation . getIndentation ( ) + nodeIndentation . getDelta ( ) ;
367+ var childIndentation = computeIndentation ( child , childStart . line , childIndentationAmount , node , effectiveParentStartLine ) ;
368+
369+ processNode ( child , childContextNode , childStart . line , childIndentation . indentation , childIndentation . delta ) ;
370+
371+ childContextNode = node ;
372+
373+ return inheritedIndentation ;
374+ }
375+
376+ function tryComputeIndentationForListItem ( startPos : number , endPos : number , effectiveParentStartLine : number , range : TextRange , inheritedIndentation : number ) : number {
377+ if ( rangeOverlapsWithStartEnd ( range , startPos , endPos ) ) {
378+ if ( inheritedIndentation !== Indentation . Unknown ) {
379+ return inheritedIndentation ;
380+ }
381+ }
382+ else {
383+ var startLine = sourceFile . getLineAndCharacterFromPosition ( startPos ) . line ;
384+ var startLinePosition = getStartLinePositionForPosition ( startPos , sourceFile ) ;
385+ var column = SmartIndenter . findFirstNonWhitespaceColumn ( startLinePosition , startPos , sourceFile , options ) ;
386+ if ( startLine !== effectiveParentStartLine || startPos === column ) {
387+ return column
388+ }
389+ }
390+
391+ return Indentation . Unknown ;
392+ }
393+
394+ function computeIndentation (
395+ node : TextRangeWithKind ,
396+ startLine : number ,
397+ indentation : number ,
398+ parent : Node ,
399+ effectiveParentStartLine : number ) : { indentation : number ; delta : number } {
400+
401+ var delta = 0 ;
402+ if ( indentation === Indentation . Unknown ) {
403+ if ( isSomeBlock ( node . kind ) ) {
404+ delta = options . IndentSize ;
405+ if ( isSomeBlock ( parent . kind ) ||
406+ parent . kind === SyntaxKind . SourceFile ||
407+ parent . kind === SyntaxKind . CaseClause ||
408+ parent . kind === SyntaxKind . DefaultClause ) {
409+
410+ indentation = nodeIndentation . getIndentation ( ) + nodeIndentation . getDelta ( ) ;
398411 }
399412 else {
400- childIndentationAmount = nodeIndentation . getIndentation ( ) ;
413+ indentation = nodeIndentation . getIndentation ( ) ;
401414 }
402415 }
403416 else {
404- if ( SmartIndenter . childStartsOnTheSameLineWithElseInIfStatement ( node , child , childStart . line , sourceFile ) ) {
405- childIndentationAmount = nodeIndentation . getIndentation ( ) ;
417+ if ( SmartIndenter . childStartsOnTheSameLineWithElseInIfStatement ( parent , < Node > node , startLine , sourceFile ) ) {
418+ indentation = nodeIndentation . getIndentation ( ) ;
406419 }
407420 else {
408- childIndentationAmount = nodeIndentation . getIndentation ( ) + nodeIndentation . getDelta ( ) ;
421+ indentation = nodeIndentation . getIndentation ( ) + nodeIndentation . getDelta ( ) ;
409422 }
410423 }
411424 }
412425
413- if ( shouldIndentChildNodes ( child . kind ) ) {
414- childDelta = options . IndentSize ;
426+ if ( shouldIndentChildNodes ( node . kind ) ) {
427+ delta = options . IndentSize ;
415428 }
416429
417- if ( childEffectiveStartLine === childStart . line ) {
418- childIndentationAmount = nodeIndentation . getIndentation ( ) ;
419- childDelta = Math . min ( options . IndentSize , delta + childDelta ) ;
430+ if ( effectiveParentStartLine === startLine ) {
431+ indentation = nodeIndentation . getIndentation ( ) ;
432+ delta = Math . min ( options . IndentSize , nodeIndentation . getDelta ( ) + delta ) ;
433+ }
434+ return {
435+ indentation : indentation ,
436+ delta : delta
420437 }
421-
422- processNode ( child , childContextNode , childStart . line , childIndentationAmount , childDelta ) ;
423- childContextNode = node ;
424-
425- return inheritedIndentation ;
426438 }
427439
428440 function consumeTokenAndAdvanceScanner ( currentTokenInfo : TokenInfo , parent : Node , indentation : DynamicIndentation ) : void {
@@ -761,9 +773,11 @@ module ts.formatting {
761773 case SyntaxKind . DoStatement :
762774 case SyntaxKind . FunctionExpression :
763775 case SyntaxKind . FunctionDeclaration :
776+ case SyntaxKind . ArrowFunction :
764777 case SyntaxKind . Method :
765778 case SyntaxKind . GetAccessor :
766779 case SyntaxKind . SetAccessor :
780+ case SyntaxKind . Constructor :
767781 return true ;
768782 }
769783
0 commit comments