| 80 | private _isInFinally = false; |
| 81 | |
| 82 | parseSourceFile(fileContents: string, parseOptions: ParseOptions, |
| 83 | diagSink: DiagnosticSink, cancelToken?: CancelToken): ParseResults { |
| 84 | timingStats.tokenizeFileTime.timeOperation(() => { |
| 85 | this._startNewParse(fileContents, 0, fileContents.length, |
| 86 | parseOptions, diagSink, cancelToken); |
| 87 | }); |
| 88 | |
| 89 | let moduleNode = new ModuleNode(new TextRange(0, fileContents.length)); |
| 90 | |
| 91 | timingStats.parseFileTime.timeOperation(() => { |
| 92 | while (!this._atEof()) { |
| 93 | if (!this._consumeTokenIfType(TokenType.NewLine)) { |
| 94 | // Handle a common error case and try to recover. |
| 95 | let nextToken = this._peekToken(); |
| 96 | if (nextToken.type === TokenType.Indent) { |
| 97 | this._getNextToken(); |
| 98 | nextToken = this._peekToken(); |
| 99 | this._addError('Unexpected indentation', nextToken); |
| 100 | } |
| 101 | |
| 102 | let statement = this._parseStatement(); |
| 103 | if (!statement) { |
| 104 | // Perform basic error recovery to get to the next line. |
| 105 | this._consumeTokensUntilType(TokenType.NewLine); |
| 106 | } else { |
| 107 | moduleNode.statements.push(statement); |
| 108 | } |
| 109 | |
| 110 | this._checkCancel(); |
| 111 | } |
| 112 | } |
| 113 | }); |
| 114 | |
| 115 | return { |
| 116 | parseTree: moduleNode, |
| 117 | tokens: this._tokenizerOutput!.tokens, |
| 118 | lines: this._tokenizerOutput!.lines |
| 119 | }; |
| 120 | } |
| 121 | |
| 122 | parseTextExpression(fileContents: string, textOffset: number, textLength: number, |
| 123 | parseOptions: ParseOptions): ParseExpressionTextResults { |