()
| 251 | |
| 252 | // suite: ':' (simple_stmt | NEWLINE INDENT stmt+ DEDENT) |
| 253 | private _parseSuite(): SuiteNode { |
| 254 | let nextToken = this._peekToken(); |
| 255 | let suite = new SuiteNode(nextToken); |
| 256 | |
| 257 | if (!this._consumeTokenIfType(TokenType.Colon)) { |
| 258 | this._addError('Expected ":"', nextToken); |
| 259 | return suite; |
| 260 | } |
| 261 | |
| 262 | if (this._consumeTokenIfType(TokenType.NewLine)) { |
| 263 | if (!this._consumeTokenIfType(TokenType.Indent)) { |
| 264 | this._addError('Expected indented block', this._peekToken()); |
| 265 | } |
| 266 | |
| 267 | while (true) { |
| 268 | // Handle a common error here and see if we can recover. |
| 269 | let nextToken = this._peekToken(); |
| 270 | if (nextToken.type === TokenType.Indent) { |
| 271 | this._getNextToken(); |
| 272 | nextToken = this._peekToken(); |
| 273 | this._addError('Unexpected indentation', nextToken); |
| 274 | } |
| 275 | |
| 276 | let statement = this._parseStatement(); |
| 277 | if (!statement) { |
| 278 | // Perform basic error recovery to get to the next line. |
| 279 | this._consumeTokensUntilType(TokenType.NewLine); |
| 280 | } else { |
| 281 | suite.statements.push(statement); |
| 282 | } |
| 283 | |
| 284 | let dedentToken = this._peekToken() as DedentToken; |
| 285 | if (this._consumeTokenIfType(TokenType.Dedent)) { |
| 286 | if (!dedentToken.matchesIndent) { |
| 287 | this._addError('Unindent amount does not match previous indent', dedentToken); |
| 288 | } |
| 289 | break; |
| 290 | } |
| 291 | |
| 292 | if (this._peekTokenType() === TokenType.EndOfStream) { |
| 293 | break; |
| 294 | } |
| 295 | } |
| 296 | } else { |
| 297 | suite.statements.push(this._parseSimpleStatement()); |
| 298 | } |
| 299 | |
| 300 | if (suite.statements.length > 0) { |
| 301 | suite.extend(suite.statements); |
| 302 | } |
| 303 | |
| 304 | return suite; |
| 305 | } |
| 306 | |
| 307 | // for_stmt: [async] 'for' exprlist 'in' testlist suite ['else' suite] |
| 308 | private _parseForStatement(asyncToken?: KeywordToken): ForNode { |
no test coverage detected