|
1 | 1 | package org.antlr.codebuff; |
2 | 2 |
|
| 3 | +import com.google.common.base.CharMatcher; |
3 | 4 | import org.antlr.v4.runtime.CommonToken; |
4 | 5 | import org.antlr.v4.runtime.CommonTokenStream; |
5 | 6 | import org.antlr.v4.runtime.ParserRuleContext; |
@@ -112,6 +113,8 @@ public void processToken(int indexIntoRealTokens, int tokenIndexInStream) { |
112 | 113 | CommonToken curToken = (CommonToken)tokens.get(tokenIndexInStream); |
113 | 114 | String tokText = curToken.getText(); |
114 | 115 |
|
| 116 | + emitCommentsToTheLeft(tokenIndexInStream); |
| 117 | + |
115 | 118 | int[] features = getNodeFeatures(tokenToNodeMap, doc, tokenIndexInStream, line, tabSize); |
116 | 119 | // must set "prev end column" value as token stream doesn't have it; |
117 | 120 | // we're tracking it as we emit tokens |
@@ -215,6 +218,50 @@ else if ( (align&0xFF)==CAT_INDENT_FROM_ANCESTOR_FIRST_TOKEN ) { |
215 | 218 | charPosInLine += n; |
216 | 219 | } |
217 | 220 |
|
| 221 | + /** Look into the token stream to get the comments to the left of current |
| 222 | + * token. Emit all whitespace and comments except for whitespace at the |
| 223 | + * end as we'll inject that per newline prediction. |
| 224 | + */ |
| 225 | + public void emitCommentsToTheLeft(int tokenIndexInStream) { |
| 226 | + List<Token> hiddenTokensToLeft = tokens.getHiddenTokensToLeft(tokenIndexInStream); |
| 227 | + if ( hiddenTokensToLeft!=null ) { |
| 228 | + // if at least one is not whitespace, assume it's a comment and print all hidden stuff including whitespace |
| 229 | + boolean hasComment = false; |
| 230 | + for (Token hidden : hiddenTokensToLeft) { |
| 231 | + String hiddenText = hidden.getText(); |
| 232 | + if ( !hiddenText.matches("\\s+") ) { |
| 233 | + hasComment = true; |
| 234 | + break; |
| 235 | + } |
| 236 | + } |
| 237 | + if ( hasComment ) { |
| 238 | + // avoid whitespace at end of sequence as we'll inject that |
| 239 | + int last = -1; |
| 240 | + for (int i=hiddenTokensToLeft.size()-1; i>=0; i--) { |
| 241 | + Token hidden = hiddenTokensToLeft.get(i); |
| 242 | + String hiddenText = hidden.getText(); |
| 243 | + if ( !hiddenText.matches("\\s+") ) { |
| 244 | + last = i; |
| 245 | + break; |
| 246 | + } |
| 247 | + } |
| 248 | + List<Token> stripped = hiddenTokensToLeft.subList(0, last+1); |
| 249 | + for (Token hidden : stripped) { |
| 250 | + String hiddenText = hidden.getText(); |
| 251 | + output.append(hiddenText); |
| 252 | + if ( hiddenText.matches("\\n+") ) { |
| 253 | + line += CharMatcher.is('\n').countIn(hiddenText); |
| 254 | + charPosInLine = 0; |
| 255 | + } |
| 256 | + else { |
| 257 | + // if a comment or plain ' ', must count char position |
| 258 | + charPosInLine += hiddenText.length(); |
| 259 | + } |
| 260 | + } |
| 261 | + } |
| 262 | + } |
| 263 | + } |
| 264 | + |
218 | 265 | public TokenPositionAnalysis getTokenAnalysis(int[] features, int indexIntoRealTokens, int tokenIndexInStream, |
219 | 266 | int injectNewline, |
220 | 267 | int alignWithPrevious, |
|
0 commit comments