@@ -18,6 +18,8 @@ export default class Formatter {
1818 this . params = new Params ( this . cfg . params ) ;
1919 this . tokenizer = tokenizer ;
2020 this . previousReservedWord = { } ;
21+ this . tokens = [ ] ;
22+ this . index = 0 ;
2123 }
2224
2325 /**
@@ -27,18 +29,20 @@ export default class Formatter {
2729 * @return {String } formatted query
2830 */
2931 format ( query ) {
30- const tokens = this . tokenizer . tokenize ( query ) ;
31- const formattedQuery = this . getFormattedQueryFromTokens ( tokens ) ;
32+ this . tokens = this . tokenizer . tokenize ( query ) ;
33+ const formattedQuery = this . getFormattedQueryFromTokens ( ) ;
3234
3335 return formattedQuery . trim ( ) ;
3436 }
3537
36- getFormattedQueryFromTokens ( tokens ) {
38+ getFormattedQueryFromTokens ( ) {
3739 let formattedQuery = "" ;
3840
39- tokens . forEach ( ( token , index ) => {
41+ this . tokens . forEach ( ( token , index ) => {
42+ this . index = index ;
43+
4044 if ( token . type === tokenTypes . WHITESPACE ) {
41- return ;
45+ // ignore (we do our own whitespace formatting)
4246 }
4347 else if ( token . type === tokenTypes . LINE_COMMENT ) {
4448 formattedQuery = this . formatLineComment ( token , formattedQuery ) ;
@@ -59,7 +63,7 @@ export default class Formatter {
5963 this . previousReservedWord = token ;
6064 }
6165 else if ( token . type === tokenTypes . OPEN_PAREN ) {
62- formattedQuery = this . formatOpeningParentheses ( tokens , index , formattedQuery ) ;
66+ formattedQuery = this . formatOpeningParentheses ( token , formattedQuery ) ;
6367 }
6468 else if ( token . type === tokenTypes . CLOSE_PAREN ) {
6569 formattedQuery = this . formatClosingParentheses ( token , formattedQuery ) ;
@@ -116,15 +120,20 @@ export default class Formatter {
116120 }
117121
118122 // Opening parentheses increase the block indent level and start a new line
119- formatOpeningParentheses ( tokens , index , query ) {
120- // Take out the preceding space unless there was whitespace there in the original query or another opening parens
121- const previousToken = tokens [ index - 1 ] ;
122- if ( previousToken && previousToken . type !== tokenTypes . WHITESPACE && previousToken . type !== tokenTypes . OPEN_PAREN ) {
123+ formatOpeningParentheses ( token , query ) {
124+ // Take out the preceding space unless there was whitespace there in the original query
125+ // or another opening parens or line comment
126+ const preserveWhitespaceFor = [
127+ tokenTypes . WHITESPACE ,
128+ tokenTypes . OPEN_PAREN ,
129+ tokenTypes . LINE_COMMENT ,
130+ ] ;
131+ if ( ! preserveWhitespaceFor . includes ( this . previousToken ( ) . type ) ) {
123132 query = trimEnd ( query ) ;
124133 }
125- query += tokens [ index ] . value ;
134+ query += token . value ;
126135
127- this . inlineBlock . beginIfPossible ( tokens , index ) ;
136+ this . inlineBlock . beginIfPossible ( this . tokens , this . index ) ;
128137
129138 if ( ! this . inlineBlock . isActive ( ) ) {
130139 this . indentation . increaseBlockLevel ( ) ;
@@ -151,7 +160,7 @@ export default class Formatter {
151160
152161 // Commas start a new line (unless within inline parentheses or SQL "LIMIT" clause)
153162 formatComma ( token , query ) {
154- query = trimEnd ( query ) + token . value + " " ;
163+ query = this . trimTrailingWhitespace ( query ) + token . value + " " ;
155164
156165 if ( this . inlineBlock . isActive ( ) ) {
157166 return query ;
@@ -165,11 +174,11 @@ export default class Formatter {
165174 }
166175
167176 formatWithSpaceAfter ( token , query ) {
168- return trimEnd ( query ) + token . value + " " ;
177+ return this . trimTrailingWhitespace ( query ) + token . value + " " ;
169178 }
170179
171180 formatWithoutSpaces ( token , query ) {
172- return trimEnd ( query ) + token . value ;
181+ return this . trimTrailingWhitespace ( query ) + token . value ;
173182 }
174183
175184 formatWithSpaces ( token , query ) {
@@ -179,4 +188,25 @@ export default class Formatter {
179188 addNewline ( query ) {
180189 return trimEnd ( query ) + "\n" + this . indentation . getIndent ( ) ;
181190 }
191+
192+ trimTrailingWhitespace ( query ) {
193+ if ( this . previousNonWhitespaceToken ( ) . type === tokenTypes . LINE_COMMENT ) {
194+ return trimEnd ( query ) + "\n" ;
195+ }
196+ else {
197+ return trimEnd ( query ) ;
198+ }
199+ }
200+
201+ previousNonWhitespaceToken ( ) {
202+ let n = 1 ;
203+ while ( this . previousToken ( n ) . type === tokenTypes . WHITESPACE ) {
204+ n ++ ;
205+ }
206+ return this . previousToken ( n ) ;
207+ }
208+
209+ previousToken ( offset = 1 ) {
210+ return this . tokens [ this . index - offset ] || { } ;
211+ }
182212}
0 commit comments