66
77import { Range , FormattingOptions , Edit , SyntaxKind , ScanError } from '../main' ;
88import { createScanner } from './scanner' ;
9+ import { cachedSpaces , cachedBreakLinesWithSpaces , supportedEols , SupportedEOL } from './string-intern' ;
910
1011export function format ( documentText : string , range : Range | undefined , options : FormattingOptions ) : Edit [ ] {
1112 let initialIndentLevel : number ;
@@ -35,26 +36,38 @@ export function format(documentText: string, range: Range | undefined, options:
3536 rangeEnd = documentText . length ;
3637 }
3738 const eol = getEOL ( options , documentText ) ;
39+ const eolFastPathSupported = supportedEols . includes ( eol as any ) ;
3840
3941 let numberLineBreaks = 0 ;
4042
4143 let indentLevel = 0 ;
4244 let indentValue : string ;
4345 if ( options . insertSpaces ) {
44- indentValue = repeat ( ' ' , options . tabSize || 4 ) ;
46+ indentValue = cachedSpaces [ options . tabSize || 4 ] ?? repeat ( cachedSpaces [ 1 ] , options . tabSize || 4 ) ;
4547 } else {
4648 indentValue = '\t' ;
4749 }
50+ const indentType = indentValue === '\t' ? '\t' : ' ' ;
4851
4952 let scanner = createScanner ( formatText , false ) ;
5053 let hasError = false ;
5154
5255 function newLinesAndIndent ( ) : string {
5356 if ( numberLineBreaks > 1 ) {
5457 return repeat ( eol , numberLineBreaks ) + repeat ( indentValue , initialIndentLevel + indentLevel ) ;
55- } else {
58+ }
59+
60+ const amountOfSpaces = indentValue . length * ( initialIndentLevel + indentLevel ) ;
61+
62+ if ( ! eolFastPathSupported || amountOfSpaces > cachedBreakLinesWithSpaces [ indentType ] [ eol as SupportedEOL ] . length ) {
5663 return eol + repeat ( indentValue , initialIndentLevel + indentLevel ) ;
5764 }
65+
66+ if ( amountOfSpaces <= 0 ) {
67+ return eol ;
68+ }
69+
70+ return cachedBreakLinesWithSpaces [ indentType ] [ eol as SupportedEOL ] [ amountOfSpaces ] ;
5871 }
5972
6073 function scanNext ( ) : SyntaxKind {
@@ -86,7 +99,9 @@ export function format(documentText: string, range: Range | undefined, options:
8699
87100 if ( firstToken !== SyntaxKind . EOF ) {
88101 let firstTokenStart = scanner . getTokenOffset ( ) + formatTextStart ;
89- let initialIndent = repeat ( indentValue , initialIndentLevel ) ;
102+ let initialIndent = ( indentValue . length * initialIndentLevel < 20 ) && options . insertSpaces
103+ ? cachedSpaces [ indentValue . length * initialIndentLevel ]
104+ : repeat ( indentValue , initialIndentLevel ) ;
90105 addEdit ( initialIndent , formatTextStart , firstTokenStart ) ;
91106 }
92107
@@ -99,7 +114,7 @@ export function format(documentText: string, range: Range | undefined, options:
99114
100115 while ( numberLineBreaks === 0 && ( secondToken === SyntaxKind . LineCommentTrivia || secondToken === SyntaxKind . BlockCommentTrivia ) ) {
101116 let commentTokenStart = scanner . getTokenOffset ( ) + formatTextStart ;
102- addEdit ( ' ' , firstTokenEnd , commentTokenStart ) ;
117+ addEdit ( cachedSpaces [ 1 ] , firstTokenEnd , commentTokenStart ) ;
103118 firstTokenEnd = scanner . getTokenOffset ( ) + scanner . getTokenLength ( ) + formatTextStart ;
104119 needsLineBreak = secondToken === SyntaxKind . LineCommentTrivia ;
105120 replaceContent = needsLineBreak ? newLinesAndIndent ( ) : '' ;
@@ -112,15 +127,15 @@ export function format(documentText: string, range: Range | undefined, options:
112127 if ( options . keepLines && numberLineBreaks > 0 || ! options . keepLines && firstToken !== SyntaxKind . OpenBraceToken ) {
113128 replaceContent = newLinesAndIndent ( ) ;
114129 } else if ( options . keepLines ) {
115- replaceContent = ' ' ;
130+ replaceContent = cachedSpaces [ 1 ] ;
116131 }
117132 } else if ( secondToken === SyntaxKind . CloseBracketToken ) {
118133 if ( firstToken !== SyntaxKind . OpenBracketToken ) { indentLevel -- ; } ;
119134
120135 if ( options . keepLines && numberLineBreaks > 0 || ! options . keepLines && firstToken !== SyntaxKind . OpenBracketToken ) {
121136 replaceContent = newLinesAndIndent ( ) ;
122137 } else if ( options . keepLines ) {
123- replaceContent = ' ' ;
138+ replaceContent = cachedSpaces [ 1 ] ;
124139 }
125140 } else {
126141 switch ( firstToken ) {
@@ -130,14 +145,14 @@ export function format(documentText: string, range: Range | undefined, options:
130145 if ( options . keepLines && numberLineBreaks > 0 || ! options . keepLines ) {
131146 replaceContent = newLinesAndIndent ( ) ;
132147 } else {
133- replaceContent = ' ' ;
148+ replaceContent = cachedSpaces [ 1 ] ;
134149 }
135150 break ;
136151 case SyntaxKind . CommaToken :
137152 if ( options . keepLines && numberLineBreaks > 0 || ! options . keepLines ) {
138153 replaceContent = newLinesAndIndent ( ) ;
139154 } else {
140- replaceContent = ' ' ;
155+ replaceContent = cachedSpaces [ 1 ] ;
141156 }
142157 break ;
143158 case SyntaxKind . LineCommentTrivia :
@@ -147,14 +162,14 @@ export function format(documentText: string, range: Range | undefined, options:
147162 if ( numberLineBreaks > 0 ) {
148163 replaceContent = newLinesAndIndent ( ) ;
149164 } else if ( ! needsLineBreak ) {
150- replaceContent = ' ' ;
165+ replaceContent = cachedSpaces [ 1 ] ;
151166 }
152167 break ;
153168 case SyntaxKind . ColonToken :
154169 if ( options . keepLines && numberLineBreaks > 0 ) {
155170 replaceContent = newLinesAndIndent ( ) ;
156171 } else if ( ! needsLineBreak ) {
157- replaceContent = ' ' ;
172+ replaceContent = cachedSpaces [ 1 ] ;
158173 }
159174 break ;
160175 case SyntaxKind . StringLiteral :
@@ -174,7 +189,7 @@ export function format(documentText: string, range: Range | undefined, options:
174189 replaceContent = newLinesAndIndent ( ) ;
175190 } else {
176191 if ( ( secondToken === SyntaxKind . LineCommentTrivia || secondToken === SyntaxKind . BlockCommentTrivia ) && ! needsLineBreak ) {
177- replaceContent = ' ' ;
192+ replaceContent = cachedSpaces [ 1 ] ;
178193 } else if ( secondToken !== SyntaxKind . CommaToken && secondToken !== SyntaxKind . EOF ) {
179194 hasError = true ;
180195 }
@@ -216,7 +231,7 @@ function computeIndentLevel(content: string, options: FormattingOptions): number
216231 const tabSize = options . tabSize || 4 ;
217232 while ( i < content . length ) {
218233 let ch = content . charAt ( i ) ;
219- if ( ch === ' ' ) {
234+ if ( ch === cachedSpaces [ 1 ] ) {
220235 nChars ++ ;
221236 } else if ( ch === '\t' ) {
222237 nChars += tabSize ;
0 commit comments