(start: CharacterCursor)
| 297 | } |
| 298 | |
| 299 | private _consumeBlockStart(start: CharacterCursor) { |
| 300 | this._requireCharCode(chars.$AT); |
| 301 | this._beginToken(TokenType.BLOCK_OPEN_START, start); |
| 302 | const startToken = this._endToken([this._getBlockName()]); |
| 303 | |
| 304 | if (this._cursor.peek() === chars.$LPAREN) { |
| 305 | // Advance past the opening paren. |
| 306 | this._cursor.advance(); |
| 307 | // Capture the parameters. |
| 308 | this._consumeBlockParameters(); |
| 309 | // Allow spaces before the closing paren. |
| 310 | this._attemptCharCodeUntilFn(isNotWhitespace); |
| 311 | |
| 312 | if (this._attemptCharCode(chars.$RPAREN)) { |
| 313 | // Allow spaces after the paren. |
| 314 | this._attemptCharCodeUntilFn(isNotWhitespace); |
| 315 | } else { |
| 316 | startToken.type = TokenType.INCOMPLETE_BLOCK_OPEN; |
| 317 | return; |
| 318 | } |
| 319 | } |
| 320 | |
| 321 | if (startToken.parts[0] === 'default never' && this._attemptCharCode(chars.$SEMICOLON)) { |
| 322 | this._beginToken(TokenType.BLOCK_OPEN_END); |
| 323 | this._endToken([]); |
| 324 | this._beginToken(TokenType.BLOCK_CLOSE); |
| 325 | this._endToken([]); |
| 326 | return; |
| 327 | } |
| 328 | |
| 329 | if (this._attemptCharCode(chars.$LBRACE)) { |
| 330 | this._beginToken(TokenType.BLOCK_OPEN_END); |
| 331 | this._endToken([]); |
| 332 | } else if ( |
| 333 | this._isBlockStart() && |
| 334 | (startToken.parts[0] === 'case' || startToken.parts[0] === 'default') |
| 335 | ) { |
| 336 | // We only allow @case statements to be consecutive without a block in between. |
| 337 | this._beginToken(TokenType.BLOCK_OPEN_END); |
| 338 | this._endToken([]); |
| 339 | this._beginToken(TokenType.BLOCK_CLOSE); |
| 340 | this._endToken([]); |
| 341 | } else { |
| 342 | startToken.type = TokenType.INCOMPLETE_BLOCK_OPEN; |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | private _consumeBlockEnd(start: CharacterCursor) { |
| 347 | this._beginToken(TokenType.BLOCK_CLOSE, start); |
no test coverage detected