private StatementNode parseStatement() {
            saveScannerState();
            switch (lexicalUnit) {
            case OpenBrace:
                return parseBlockStatement();

            case SemiColon:
            	var emptyStatement = new EmptyStatementNode { EndPosition = scanner.EndPosition };
            	setScannerState(emptyStatement);
                nextLexicalUnit(false);
                return emptyStatement;

            case Keyword:
            case ContextualKeyword:
                switch (scanner.Keyword) {
                case Byte:
                case Char:
                case Short:
                case Int:
                case Long:
                case Boolean:
                case Double:
                case Float:
                case Void:
				case String:
                    return parseLabeledOrLocalDeclarationOrExpressionStatement();

                case Yield: {
                    var yieldStatement = new YieldStatementNode();
                    setScannerState(yieldStatement);
                    switch (nextLexicalUnit(true)) {
                    case Keyword:
                        switch (scanner.Keyword) {
                        case Return:
                            nextLexicalUnit(true);
                            yieldStatement.Value = parseExpression();
                            break;
                        case Break:
                            nextLexicalUnit(true);
                            break;
                        default:
                            throw error(ParseErrorId.ReturnOrBreakExpected);
                        }
                        break;
                    default:
                        throw error(ParseErrorId.ReturnOrBreakExpected);
                    }
                    yieldStatement.EndPosition = parseSemiColon(false, false);
                    return yieldStatement;
                }

                case Try: {
                    var tryStatement = new TryStatementNode();
                    setScannerState(tryStatement);
                    nextLexicalUnit(true);
                    tryStatement.Block = parseBlockStatement();
                    var hasCatch = false;
                    var done = false;
                	int endPosition = 0;
                    do {
                        switch (lexicalUnit) {
                        case Keyword:
                            switch (scanner.Keyword) {
                            case Catch:
                                var catchClause = new CatchClauseNode();
                                setScannerState(catchClause);
                                if (nextLexicalUnit(true) == LexicalUnit.OpenParenthesis) {
                                    nextLexicalUnit(true);
                                    catchClause.ExceptionType = parseType(true);
                                    if (isIdentifier(lexicalUnit)) {
                                        catchClause.NameOffset = scanner.StartPosition;
                                        catchClause.NameLength = getLexicalUnitLength();
                                        nextLexicalUnit(true);
                                    }
                                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                                        throw error(ParseErrorId.CloseParenthesisExpected);
                                    }
                                    nextLexicalUnit(true);
                                }
                                catchClause.Block = parseBlockStatement();
                                tryStatement.CatchClauses.add(catchClause);
                                endPosition = catchClause.Block.EndPosition;
                                catchClause.EndPosition = endPosition;
                                hasCatch = true;
                                break;

                            case Finally:
                                nextLexicalUnit(true);
                                tryStatement.Finally = parseBlockStatement();
                                endPosition = tryStatement.Finally.EndPosition;
                                done = true;
                                break;

                            default:
                                if (!hasCatch) {
                                    throw error(ParseErrorId.FinallyExpected);
                                }
                                done = true;
                                break;
                            }
                            break;

                        default:
                            if (!hasCatch) {
                                throw error(ParseErrorId.FinallyExpected);
                            }
                            done = true;
                            break;
                        }
                    } while (!done);
                    tryStatement.EndPosition = endPosition;
                    return tryStatement;
                }

                case Using: {
                    var usingStatement = new UsingStatementNode();
                    setScannerState(usingStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) {
                        var restorePoint = this.createRestorePoint();
                        saveScannerState();
                        if (isIdentifier(nextLexicalUnit(true))) {
                            usingStatement.ResourceAcquisition = parseLocalDeclarationStatement(null, false);
                        } else {
                            this.restore(restorePoint);
                        }
                    }
                    if (usingStatement.ResourceAcquisition == null) {
                        var restorePoint = this.createRestorePoint();
                        saveScannerState();
                        var type = parseType(false);
                        if (type != null && isIdentifier(lexicalUnit)) {
                            usingStatement.ResourceAcquisition = parseLocalDeclarationStatement(type, false);
                            if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                                this.restore(restorePoint);
                                usingStatement.ResourceAcquisition = null;
                            }
                        } else {
                            this.restore(restorePoint);
                        }
                    }
                    if (usingStatement.ResourceAcquisition == null) {
                        var exp = new ExpressionStatementNode();
                        setScannerState(exp);
                        exp.Expression = parseExpression();
                        usingStatement.ResourceAcquisition = exp;
                    }
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    usingStatement.Statement = parseEmbeddedStatement();
                    usingStatement.EndPosition = usingStatement.Statement.EndPosition;
                    return usingStatement;
                }

                case Return: {
                    var returnStatement = new ReturnStatementNode();
                    setScannerState(returnStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.SemiColon) {
                        returnStatement.Value = parseExpression();
                    }
                    returnStatement.EndPosition = parseSemiColon(false, false);
                    return returnStatement;
                }

                case Throw: {
                    var throwStatement = new ThrowStatementNode();
                    setScannerState(throwStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.SemiColon) {
                        throwStatement.Exception = parseExpression();
                    }
                    throwStatement.EndPosition = parseSemiColon(false, false);
                    return throwStatement;
                }

                case If: {
                    var ifStatement = new IfStatementNode();
                    setScannerState(ifStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    ifStatement.Condition = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    ifStatement.IfTrue = parseEmbeddedStatement();
                    if (lexicalUnit == LexicalUnit.Keyword && scanner.Keyword == Keyword.Else) {
                        nextLexicalUnit(true);
                        ifStatement.IfFalse = parseEmbeddedStatement();
                        ifStatement.EndPosition = ifStatement.IfFalse.EndPosition;
                    } else {
                    	ifStatement.EndPosition = ifStatement.IfTrue.EndPosition;
                    }
                    return ifStatement;
                }

                case While: {
                    var whileStatement = new WhileStatementNode();
                    setScannerState(whileStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    whileStatement.Condition = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    whileStatement.Statement = parseEmbeddedStatement();
                    whileStatement.EndPosition = whileStatement.Statement.EndPosition;
                    return whileStatement;
                }

                case Do: {
                    var doStatement = new DoStatementNode();
                    setScannerState(doStatement);
                    nextLexicalUnit(true);
                    doStatement.Statement = parseEmbeddedStatement();
                    if (lexicalUnit != LexicalUnit.Keyword || scanner.Keyword != Keyword.While) {
                        throw error(ParseErrorId.WhileExpected);
                    }
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    doStatement.Condition = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    doStatement.EndPosition = parseSemiColon(true, false);
                    return doStatement;
                }

                case Switch: {
                    var switchStatement = new SwitchStatementNode();
                    setScannerState(switchStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    switchStatement.Selector = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    if (nextLexicalUnit(true) != LexicalUnit.OpenBrace) {
                        throw error(ParseErrorId.OpenBraceExpected);
                    }
                    nextLexicalUnit(true);
                    var done = false;
                    int endPosition = 0;
                    do {
                        switch (lexicalUnit) {
                        case Keyword:
                            var filename = scanner.Filename;
                            var line = scanner.StartLine;
                            var column = scanner.StartColumn;
                            var disabledWarnings = scanner.CodeErrorManager.DisabledWarnings;
	                    	int startPosition = scanner.StartPosition;
                            ExpressionNode expr = null;
                            switch (scanner.Keyword) {
                            case Case:
                                nextLexicalUnit(true);
                                expr = parseExpression();
                                break;

                            case Default:
                                nextLexicalUnit(true);
                                break;

                            default:
                                throw error(ParseErrorId.CloseBraceExpected);
                            }
                            if (lexicalUnit != LexicalUnit.Colon) {
                                throw error(ParseErrorId.ColonExpected);
                            }
                            var switchSection = new SwitchSectionNode { Filename = filename, Line = line, Column = column,
                                    DisabledWarnings = disabledWarnings, StartPosition = startPosition };
                            switchSection.CaseExpression = expr;
                            switchStatement.Sections.add(switchSection);
                            int end = scanner.EndPosition;
                            nextLexicalUnit(true);
                            var caseDone = false;
                            do {
                                switch (lexicalUnit) {
                                case Keyword:
                                    switch (scanner.Keyword) {
                                    case Case:
                                    case Default:
	                                	switchSection.EndPosition = end;
                                        caseDone = true;
                                        break;

                                    default:
                                    	var statement = parseStatement();
                                        switchSection.Statements.add(statement);
	                                    endPosition = statement.EndPosition;
	                                    switchSection.EndPosition = endPosition;
                                        break;
                                    }
                                    break;

                                case CloseBrace:
                                	endPosition = scanner.EndPosition;
                                	switchSection.EndPosition = end;
                                    caseDone = true;
                                    break;

                                default:
                                	var statement = parseStatement();
                                    switchSection.Statements.add(statement);
                                    endPosition = statement.EndPosition;
                                    switchSection.EndPosition = endPosition;
                                    break;
                                }
                            } while (!caseDone);
                            break;

                        case CloseBrace:
                            done = true;
                            endPosition = scanner.EndPosition;
                            nextLexicalUnit(false);
                            break;

                        default:
                            throw error(ParseErrorId.CloseBraceExpected);
                        }
                    } while (!done);
                    switchStatement.EndPosition = endPosition;
                    return switchStatement;
                }

                case Foreach: {
                    var foreachStatement = new ForeachStatementNode();
                    setScannerState(foreachStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) {
                        var restorePoint = this.createRestorePoint();
                        if (isIdentifier(nextLexicalUnit(true))) {
                            foreachStatement.NameOffset = scanner.StartPosition;
                            foreachStatement.NameLength = getLexicalUnitLength();
                        } else {
                            this.restore(restorePoint);
                        }
                    }
                    if (foreachStatement.NameLength == 0) {
                        var t = parseType(true);
                        if (!isIdentifier(lexicalUnit)) {
                            throw error(ParseErrorId.IdentifierExpected);
                        }
                        foreachStatement.Type = t;
                        foreachStatement.NameOffset = scanner.StartPosition;
                        foreachStatement.NameLength = getLexicalUnitLength();
                    }
                    if (nextLexicalUnit(true) != LexicalUnit.Keyword && scanner.Keyword != Keyword.In) {
                        throw error(ParseErrorId.InExpected);
                    }
                    nextLexicalUnit(true);
                    foreachStatement.Source = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    foreachStatement.Statement = parseEmbeddedStatement();
                    foreachStatement.EndPosition = foreachStatement.Statement.EndPosition;
                    return foreachStatement;
                }

                case For: {
                    var forStatement = new ForStatementNode();
                    setScannerState(forStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    StatementNode statement = null;
                    nextLexicalUnit(true);
                    if (lexicalUnit == LexicalUnit.ContextualKeyword && scanner.Keyword == Keyword.Var) {
                        var restorePoint = this.createRestorePoint();
                        saveScannerState();
                        if (isIdentifier(nextLexicalUnit(true))) {
                            statement = parseLocalDeclarationStatement(null, false);
                        } else {
                            this.restore(restorePoint);
                        }
                    }
                    if (statement == null && lexicalUnit != LexicalUnit.SemiColon) {
                        statement = parseLocalDeclarationOrExpressionStatement(false);
                    }
                    if (statement != null) {
                        forStatement.Initializer.add(statement);
                        if (statement.StatementKind != StatementKind.LocalDeclaration) {
                            while (lexicalUnit == LexicalUnit.Comma) {
                                nextLexicalUnit(true);
                                forStatement.Initializer.add(parseExpressionStatement(false));
                            }
                        }
                    }
                    parseSemiColon(false, true);
                    if (lexicalUnit != LexicalUnit.SemiColon) {
                        forStatement.Condition = parseExpression();
                    }
                    parseSemiColon(false, true);
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        forStatement.Iterator.add(parseExpressionStatement(false));
                        while (lexicalUnit == LexicalUnit.Comma) {
                            nextLexicalUnit(true);
                            forStatement.Iterator.add(parseExpressionStatement(false));
                        }
                    }
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    forStatement.Statement = parseEmbeddedStatement();
                    forStatement.EndPosition = forStatement.Statement.EndPosition;
                    return forStatement;
                }

                case Synchronized: {
                    var syncStatement = new SynchronizedStatementNode();
                    setScannerState(syncStatement);
                    if (nextLexicalUnit(true) != LexicalUnit.OpenParenthesis) {
                        throw error(ParseErrorId.OpenParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    syncStatement.Lock = parseExpression();
                    if (lexicalUnit != LexicalUnit.CloseParenthesis) {
                        throw error(ParseErrorId.CloseParenthesisExpected);
                    }
                    nextLexicalUnit(true);
                    syncStatement.Statement = parseEmbeddedStatement();
                    syncStatement.EndPosition = syncStatement.Statement.EndPosition;
                    return syncStatement;
                }

                case Goto: {
                    saveScannerState();
                    switch (nextLexicalUnit(true)) {
                    case Keyword:
                        switch (scanner.Keyword) {
                        case Case: {
                            var result = new GotoCaseStatementNode();
                            setSavedScannerState(result);
                            nextLexicalUnit(true);
                            result.Expression = parseExpression();
                            result.EndPosition = parseSemiColon(false, false);
                            return result;
                        }
                        case Default: {
                            var result = new GotoCaseStatementNode();
                            setSavedScannerState(result);
                            result.EndPosition = parseSemiColon(true, false);
                            return result;
                        }
                        default:
                            throw error(ParseErrorId.IdentifierExpected);
                        }

                    case Identifier:
                    case ContextualKeyword:
                        var gotoStatement = new GotoStatementNode();
                        setSavedScannerState(gotoStatement);
                        gotoStatement.LabelOffset = scanner.StartPosition;
                        gotoStatement.LabelLength = getLexicalUnitLength();
                        gotoStatement.EndPosition = parseSemiColon(true, false);
                        return gotoStatement;

                    default:
                        throw error(ParseErrorId.IdentifierExpected);
                    }
                }

                case Continue: {
                    var continueStatement = new ContinueStatementNode();
                    setScannerState(continueStatement);
                    continueStatement.EndPosition = parseSemiColon(true, false);
                    return continueStatement;
                }

                case Break: {
                    var breakStatement = new BreakStatementNode();
                    setScannerState(breakStatement);
                    breakStatement.EndPosition = parseSemiColon(true, false);
                    return breakStatement;
                }

                case Var: {
                    var restorePoint = this.createRestorePoint();
                    saveScannerState();
                    if (isIdentifier(nextLexicalUnit(true))) {
                        return parseLocalDeclarationStatement(null, true);
                    } else {
                        this.restore(restorePoint);
                        return parseLabeledOrLocalDeclarationOrExpressionStatement();
                    }
                }

                default:
                    return parseLabeledOrLocalDeclarationOrExpressionStatement();
                }

            default:
                return parseLabeledOrLocalDeclarationOrExpressionStatement();
            }
        }
Exemple #2
0
 protected virtual TResult handleReturn(ReturnStatementNode returnStatement, TSource source)
 {
     return(defaultHandler());
 }