From 5ad6b602a31a3af2b2fbc756da753ad890c45c93 Mon Sep 17 00:00:00 2001 From: Peter Gromov Date: Wed, 29 Jul 2009 22:06:24 +0400 Subject: [PATCH] gather all gsp-dependent groovy parsing to GroovyParser --- .../plugins/groovy/lang/parser/GroovyParser.java | 415 +++++++++++++++++++++ .../parser/parsing/statements/ForStatement.java | 50 +-- .../parser/parsing/statements/SwitchStatement.java | 76 +--- .../statements/blocks/OpenOrClosableBlock.java | 68 +--- .../statements/constructor/ConstructorBody.java | 7 +- .../expressions/arguments/ArgumentList.java | 38 +- .../expressions/arithmetic/PathExpression.java | 2 +- .../primary/ListOrMapConstructorExpression.java | 3 +- .../expressions/primary/PrimaryExpression.java | 2 +- .../typeDefinitions/members/EnumConstant.java | 2 +- .../parser/parsing/toplevel/CompilationUnit.java | 6 +- 11 files changed, 449 insertions(+), 220 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java index dcbb9deab5..6c974effd4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/GroovyParser.java @@ -21,6 +21,20 @@ import com.intellij.lang.PsiParser; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.plugins.groovy.lang.parser.parsing.toplevel.CompilationUnit; +import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.*; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.TypeDefinition; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.imports.ImportStatement; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ConditionalExpression; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.StrictContextExpression; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ExpressionStatement; +import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; +import org.jetbrains.plugins.groovy.GroovyBundle; +import org.jetbrains.plugins.grails.lang.gsp.parsing.groovy.GspTemplateStmtParsing; +import org.jetbrains.plugins.grails.lang.gsp.lexer.GspTokenTypesEx; /** * Parser for Groovy script files @@ -38,4 +52,405 @@ public class GroovyParser implements PsiParser { return builder.getTreeBuilt(); } + + public static boolean parseForStatement(PsiBuilder builder) { + PsiBuilder.Marker marker = builder.mark(); + + ParserUtils.getToken(builder, GroovyTokenTypes.kFOR); + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } + if (!ForStatement.forClauseParse(builder)) { + builder.error(GroovyBundle.message("for.clause.expected")); + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } + + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN, GroovyBundle.message("rparen.expected"))) { + while (!builder.eof() && GroovyTokenTypes.mNLS.equals(builder.getTokenType())){ + builder.advanceLexer(); + } + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } + + PsiBuilder.Marker warn = builder.mark(); + if (builder.getTokenType() == GroovyTokenTypes.mNLS) { + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + } + + if (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + warn.rollbackTo(); + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } + + if (!parseStatement(builder, true)) { + warn.rollbackTo(); + builder.error(GroovyBundle.message("expression.expected")); + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } else { + warn.drop(); + marker.done(GroovyElementTypes.FOR_STATEMENT); + return true; + } + } + + public static boolean parseIfStatement(PsiBuilder builder) { + //allow error messages + PsiBuilder.Marker ifStmtMarker = builder.mark(); + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.kIF)) { + ifStmtMarker.rollbackTo(); + builder.error(GroovyBundle.message("if.expected")); + return false; + } + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { +// ifStmtMarker.done(IF_STATEMENT); +// return IF_STATEMENT; + ifStmtMarker.drop(); + return false; + } + + if (!ConditionalExpression.parse(builder)) { + builder.error(GroovyBundle.message("expression.expected")); + } + + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN, GroovyBundle.message("rparen.expected"))) { + while (!builder.eof() && !GroovyTokenTypes.mNLS.equals(builder.getTokenType()) && !GroovyTokenTypes.mRPAREN.equals(builder.getTokenType())) { + builder.advanceLexer(); + builder.error(GroovyBundle.message("rparen.expected")); + } + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN)) { + ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + return true; + } + } + + PsiBuilder.Marker warn = builder.mark(); + if (builder.getTokenType() == GroovyTokenTypes.mNLS) { + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + } + + if (!parseStatement(builder, true) && !GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + warn.rollbackTo(); + builder.error(GroovyBundle.message("expression.expected")); + ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + return true; + } else { + warn.drop(); + } + + PsiBuilder.Marker rb = builder.mark(); + if (GroovyTokenTypes.kELSE.equals(builder.getTokenType()) || + (Separators.parse(builder) && + builder.getTokenType() == GroovyTokenTypes.kELSE)) { + rb.drop(); + ParserUtils.getToken(builder, GroovyTokenTypes.kELSE); + + warn = builder.mark(); + if (builder.getTokenType() == GroovyTokenTypes.mNLS) { + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + } + + if (!parseStatement(builder, true) && !GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + warn.rollbackTo(); + builder.error(GroovyBundle.message("expression.expected")); + ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + return true; + } else { + warn.drop(); + } + + ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + return true; + + } else { + rb.rollbackTo(); + ifStmtMarker.done(GroovyElementTypes.IF_STATEMENT); + return true; + } + } + + /** + * Parses list of statements after case label(s) + * + * @param builder + */ + public static void parseSwitchCaseList(PsiBuilder builder) { + + if (GroovyTokenTypes.kCASE.equals(builder.getTokenType()) || + GroovyTokenTypes.kDEFAULT.equals(builder.getTokenType()) || + GroovyTokenTypes.mRCURLY.equals(builder.getTokenType())) { + return; + } + + if (!parseStatement(builder, false) && !GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + builder.error(GroovyBundle.message("wrong.statement")); + return; + } + + while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + } + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + + if (GroovyTokenTypes.kCASE.equals(builder.getTokenType()) || + GroovyTokenTypes.kDEFAULT.equals(builder.getTokenType()) || + GroovyTokenTypes.mRCURLY.equals(builder.getTokenType())) { + return; + } + boolean result = parseStatement(builder, false); + while (result && (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) || + GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + } + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + + if (GroovyTokenTypes.kCASE.equals(builder.getTokenType()) || + GroovyTokenTypes.kDEFAULT.equals(builder.getTokenType()) || + GroovyTokenTypes.mRCURLY.equals(builder.getTokenType())) { + break; + } + + result = parseStatement(builder, false); + if (!GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType())) { + cleanAfterError(builder); + } + } + Separators.parse(builder); + } + + public static boolean parseWhileStatement(PsiBuilder builder) { + + PsiBuilder.Marker marker = builder.mark(); + + ParserUtils.getToken(builder, GroovyTokenTypes.kWHILE); + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mLPAREN, GroovyBundle.message("lparen.expected"))) { + marker.done(GroovyElementTypes.WHILE_STATEMENT); + return true; + } + + if (!StrictContextExpression.parse(builder)) { + builder.error(GroovyBundle.message("expression.expected")); + } + + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN, GroovyBundle.message("rparen.expected"))) { + while (!builder.eof() && !GroovyTokenTypes.mNLS.equals(builder.getTokenType()) && !GroovyTokenTypes.mRPAREN.equals(builder.getTokenType())) { + builder.advanceLexer(); + builder.error(GroovyBundle.message("rparen.expected")); + } + if (!ParserUtils.getToken(builder, GroovyTokenTypes.mRPAREN)) { + marker.done(GroovyElementTypes.WHILE_STATEMENT); + return true; + } + } + + PsiBuilder.Marker warn = builder.mark(); + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + + if (!parseStatement(builder, true) && !GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + warn.rollbackTo(); + builder.error(GroovyBundle.message("expression.expected")); + marker.done(GroovyElementTypes.WHILE_STATEMENT); + return true; + } else { + warn.drop(); + marker.done(GroovyElementTypes.WHILE_STATEMENT); + return true; + } + } + + /** + * Rolls marker forward after possible errors + * + * @param builder + */ + public static void cleanAfterError(PsiBuilder builder) { + int i = 0; + PsiBuilder.Marker em = builder.mark(); + while (!builder.eof() && + !(GroovyTokenTypes.mNLS.equals(builder.getTokenType()) || + GroovyTokenTypes.mRCURLY.equals(builder.getTokenType()) || + GroovyTokenTypes.mSEMI.equals(builder.getTokenType())) && + !GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType()) + ) { + builder.advanceLexer(); + i++; + } + if (i > 0) { + em.error(GroovyBundle.message("separator.or.rcurly.expected")); + } else { + em.drop(); + } + } + + public static void parseBlockBody(PsiBuilder builder) { + + + GspTemplateStmtParsing.parseGspTemplateStmt(builder); + if (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || GroovyTokenTypes.mNLS.equals(builder.getTokenType())) { + Separators.parse(builder); + } + while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + Separators.parse(builder); + } + + boolean result = parseStatement(builder, false); + + while (result && + (GroovyTokenTypes.mSEMI.equals(builder.getTokenType()) || + GroovyTokenTypes.mNLS.equals(builder.getTokenType()) || + GspTemplateStmtParsing.parseGspTemplateStmt(builder))) { + Separators.parse(builder); + while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + Separators.parse(builder); + } + result = parseStatement(builder, false); + if (!GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType())) { + cleanAfterError(builder); + } + } + cleanAfterError(builder); + Separators.parse(builder); + while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { + Separators.parse(builder); + } + + } + + public static boolean parseStatement(PsiBuilder builder, boolean isBlockStatementNeeded) { + if (isBlockStatementNeeded && GroovyTokenTypes.mLCURLY.equals(builder.getTokenType())) { + return OpenOrClosableBlock.parseBlockStatement(builder); + } + + if (GroovyTokenTypes.kIMPORT.equals(builder.getTokenType())) { + PsiBuilder.Marker marker = builder.mark(); + ImportStatement.parse(builder); + marker.error(GroovyBundle.message("import.not.allowed")); + return true; + } + + if (GroovyTokenTypes.kIF.equals(builder.getTokenType())) { + return parseIfStatement(builder); + } + if (GroovyTokenTypes.kSWITCH.equals(builder.getTokenType())) { + return SwitchStatement.parse(builder); + } + if (GroovyTokenTypes.kTRY.equals(builder.getTokenType())) { + return TryCatchStatement.parse(builder); + } + if (GroovyTokenTypes.kWHILE.equals(builder.getTokenType())) { + return parseWhileStatement(builder); + } + if (GroovyTokenTypes.kFOR.equals(builder.getTokenType())) { + return parseForStatement(builder); + } + if (ParserUtils.lookAhead(builder, GroovyTokenTypes.kSYNCHRONIZED, GroovyTokenTypes.mLPAREN)) { + PsiBuilder.Marker synMarker = builder.mark(); + if (SynchronizedStatement.parse(builder)) { + synMarker.drop(); + return true; + } else { + synMarker.rollbackTo(); + } + } + + // Possible errors + if (GroovyTokenTypes.kELSE.equals(builder.getTokenType())) { + ParserUtils.wrapError(builder, GroovyBundle.message("else.without.if")); + parseStatement(builder, true); + return true; + } + if (GroovyTokenTypes.kCATCH.equals(builder.getTokenType())) { + ParserUtils.wrapError(builder, GroovyBundle.message("catch.without.try")); + parseStatement(builder, false); + return true; + } + if (GroovyTokenTypes.kFINALLY.equals(builder.getTokenType())) { + ParserUtils.wrapError(builder, GroovyBundle.message("finally.without.try")); + parseStatement(builder, false); + return true; + } + if (GroovyTokenTypes.kCASE.equals(builder.getTokenType())) { + PsiBuilder.Marker marker = builder.mark(); + SwitchStatement.parseCaseLabel(builder); + marker.error(GroovyBundle.message("case.without.switch")); + parseStatement(builder, false); + return true; + } + if (GroovyTokenTypes.kDEFAULT.equals(builder.getTokenType())) { + PsiBuilder.Marker marker = builder.mark(); + SwitchStatement.parseCaseLabel(builder); + marker.error(GroovyBundle.message("default.without.switch")); + parseStatement(builder, false); + return true; + } + + if (BranchStatement.BRANCH_KEYWORDS.contains(builder.getTokenType())) { + return BranchStatement.parse(builder); + } + if (ParserUtils.lookAhead(builder, GroovyTokenTypes.mIDENT, GroovyTokenTypes.mCOLON)) { + return parseLabeledStatement(builder); + } + + //declaration + PsiBuilder.Marker declMarker = builder.mark(); + if (!Declaration.parse(builder, false)) { + declMarker.rollbackTo(); + } else { + declMarker.drop(); + return true; + } + + if (TypeDefinition.parse(builder)) return true; + + return ExpressionStatement.parse(builder); + + } + + public static boolean parseStatementWithImports(PsiBuilder builder) { + if (GroovyTokenTypes.kIMPORT.equals(builder.getTokenType())) { + return ImportStatement.parse(builder); + } else { + return parseStatement(builder, false); + } + } + + public static boolean parseLabeledStatement(PsiBuilder builder) { + + PsiBuilder.Marker marker = builder.mark(); + ParserUtils.eatElement(builder, GroovyElementTypes.LABEL); + ParserUtils.getToken(builder, GroovyTokenTypes.mCOLON); + + ParserUtils.getToken(builder, GroovyTokenTypes.mNLS); + + parseStatement(builder, false); + + marker.done(GroovyElementTypes.LABELED_STATEMENT); + return true; + } } \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java index 608c0aa1e2..0d4b4c9f21 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/ForStatement.java @@ -16,7 +16,6 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements; import com.intellij.lang.PsiBuilder; -import org.jetbrains.plugins.grails.lang.gsp.parsing.groovy.GspTemplateStmtParsing; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.modifiers.Modifiers; @@ -32,54 +31,7 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; */ public class ForStatement implements GroovyElementTypes { - public static boolean parse(PsiBuilder builder) { - PsiBuilder.Marker marker = builder.mark(); - - ParserUtils.getToken(builder, kFOR); - if (!ParserUtils.getToken(builder, mLPAREN, GroovyBundle.message("lparen.expected"))) { - marker.done(FOR_STATEMENT); - return true; - } - if (!forClauseParse(builder)) { - builder.error(GroovyBundle.message("for.clause.expected")); - marker.done(FOR_STATEMENT); - return true; - } - - ParserUtils.getToken(builder, mNLS); - - if (!ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected"))) { - while (!builder.eof() && mNLS.equals(builder.getTokenType())){ - builder.advanceLexer(); - } - marker.done(FOR_STATEMENT); - return true; - } - - PsiBuilder.Marker warn = builder.mark(); - if (builder.getTokenType() == mNLS) { - ParserUtils.getToken(builder, mNLS); - } - - if (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - warn.rollbackTo(); - marker.done(FOR_STATEMENT); - return true; - } - - if (!Statement.parse(builder, true)) { - warn.rollbackTo(); - builder.error(GroovyBundle.message("expression.expected")); - marker.done(FOR_STATEMENT); - return true; - } else { - warn.drop(); - marker.done(FOR_STATEMENT); - return true; - } - } - - private static boolean forClauseParse(PsiBuilder builder) { + public static boolean forClauseParse(PsiBuilder builder) { ParserUtils.getToken(builder, mNLS); return forInClauseParse(builder) || tradForClauseParse(builder); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/SwitchStatement.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/SwitchStatement.java index c0f569f70d..56218112ed 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/SwitchStatement.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/SwitchStatement.java @@ -18,12 +18,9 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements; import com.intellij.lang.PsiBuilder; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; -import org.jetbrains.plugins.grails.lang.gsp.lexer.GspTokenTypesEx; -import org.jetbrains.plugins.grails.lang.gsp.parsing.groovy.GspTemplateStmtParsing; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; -import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock; +import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.AssignmentExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.StrictContextExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; @@ -103,7 +100,7 @@ public class SwitchStatement implements GroovyElementTypes { ParserUtils.lookAhead(builder, mNLS, mRCURLY)) { builder.error(GroovyBundle.message("expression.expected")); } else { - parseCaseList(builder); + GroovyParser.parseSwitchCaseList(builder); } sectionMarker.done(CASE_SECTION); } @@ -122,13 +119,6 @@ public class SwitchStatement implements GroovyElementTypes { if (kCASE.equals(elem)) { AssignmentExpression.parse(builder); -/* - if (WRONGWAY.equals(AssignmentExpression.parse(builder))) { - label.done(CASE_LABEL); - builder.error(GroovyBundle.message("expression.expected")); - return; - } -*/ } ParserUtils.getToken(builder, mCOLON, GroovyBundle.message("colon.expected")); label.done(CASE_LABEL); @@ -139,66 +129,4 @@ public class SwitchStatement implements GroovyElementTypes { } } - /** - * Parses list of statements after case label(s) - * - * @param builder - */ - private static void parseCaseList(PsiBuilder builder) { - - if (kCASE.equals(builder.getTokenType()) || - kDEFAULT.equals(builder.getTokenType()) || - mRCURLY.equals(builder.getTokenType())) { - return; - } - - if (!Statement.parse(builder, false) && !GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - builder.error(GroovyBundle.message("wrong.statement")); - return; - } - - while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - } - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - - if (kCASE.equals(builder.getTokenType()) || - kDEFAULT.equals(builder.getTokenType()) || - mRCURLY.equals(builder.getTokenType())) { - return; - } - boolean result = Statement.parse(builder, false); - while (result && (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) || - GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - } - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - - if (kCASE.equals(builder.getTokenType()) || - kDEFAULT.equals(builder.getTokenType()) || - mRCURLY.equals(builder.getTokenType())) { - break; - } - - result = Statement.parse(builder, false); - if (!GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType())) { - OpenOrClosableBlock.cleanAfterError(builder); - } - } - Separators.parse(builder); - } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/blocks/OpenOrClosableBlock.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/blocks/OpenOrClosableBlock.java index ed338ac6a1..97d071c4a5 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/blocks/OpenOrClosableBlock.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/blocks/OpenOrClosableBlock.java @@ -16,14 +16,10 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks; import com.intellij.lang.PsiBuilder; -import org.jetbrains.plugins.grails.lang.gsp.lexer.GspTokenTypesEx; -import org.jetbrains.plugins.grails.lang.gsp.parsing.groovy.GspTemplateStmtParsing; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; -import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; +import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.parameters.ParameterList; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.Statement; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; /** @@ -67,7 +63,7 @@ public class OpenOrClosableBlock implements GroovyElementTypes { return false; } ParserUtils.getToken(builder, mNLS); - parseBlockBody(builder); + GroovyParser.parseBlockBody(builder); while (!builder.eof() && !mRCURLY.equals(builder.getTokenType())) { builder.error(GroovyBundle.message("expression.expected")); @@ -98,7 +94,7 @@ public class OpenOrClosableBlock implements GroovyElementTypes { } ParserUtils.getToken(builder, mNLS); closableBlockParamsOpt(builder); - parseBlockBody(builder); + GroovyParser.parseBlockBody(builder); ParserUtils.getToken(builder, mRCURLY, GroovyBundle.message("rcurly.expected")); marker.done(CLOSABLE_BLOCK); return true; @@ -111,62 +107,4 @@ public class OpenOrClosableBlock implements GroovyElementTypes { ParserUtils.getToken(builder, mCLOSABLE_BLOCK_OP); } - public static void parseBlockBody(PsiBuilder builder) { - - - GspTemplateStmtParsing.parseGspTemplateStmt(builder); - if (mSEMI.equals(builder.getTokenType()) || mNLS.equals(builder.getTokenType())) { - Separators.parse(builder); - } - while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - Separators.parse(builder); - } - - boolean result = Statement.parse(builder, false); - - while (result && - (mSEMI.equals(builder.getTokenType()) || - mNLS.equals(builder.getTokenType()) || - GspTemplateStmtParsing.parseGspTemplateStmt(builder))) { - Separators.parse(builder); - while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - Separators.parse(builder); - } - result = Statement.parse(builder, false); - if (!GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType())) { - cleanAfterError(builder); - } - } - cleanAfterError(builder); - Separators.parse(builder); - while (GspTemplateStmtParsing.parseGspTemplateStmt(builder)) { - Separators.parse(builder); - } - - } - - /** - * Rolls marker forward after possible errors - * - * @param builder - */ - public static void cleanAfterError(PsiBuilder builder) { - int i = 0; - PsiBuilder.Marker em = builder.mark(); - while (!builder.eof() && - !(mNLS.equals(builder.getTokenType()) || - mRCURLY.equals(builder.getTokenType()) || - mSEMI.equals(builder.getTokenType())) && - !GspTokenTypesEx.GSP_GROOVY_SEPARATORS.contains(builder.getTokenType()) - ) { - builder.advanceLexer(); - i++; - } - if (i > 0) { - em.error(GroovyBundle.message("separator.or.rcurly.expected")); - } else { - em.drop(); - } - } - } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java index 963289e28a..63202db49d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/constructor/ConstructorBody.java @@ -17,10 +17,9 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.constructor; import com.intellij.lang.PsiBuilder; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.ArgumentList; import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeArguments; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; @@ -50,7 +49,7 @@ public class ConstructorBody implements GroovyElementTypes { //explicit constructor invocation Separators.parse(builder); - OpenOrClosableBlock.parseBlockBody(builder); + GroovyParser.parseBlockBody(builder); if (builder.getTokenType() != mRCURLY) { builder.error(GroovyBundle.message("rcurly.expected")); @@ -69,7 +68,7 @@ public class ConstructorBody implements GroovyElementTypes { if ((ParserUtils.getToken(builder, kTHIS) || ParserUtils.getToken(builder, kSUPER)) && ParserUtils.lookAhead(builder, mLPAREN)) { PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, mLPAREN); - ArgumentList.parse(builder, mRPAREN); + ArgumentList.parseArgumentList(builder, mRPAREN); ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected")); marker.done(ARGUMENTS); return true; diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java index d2f34a52c0..80db99722e 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arguments/ArgumentList.java @@ -21,9 +21,8 @@ import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.lexer.TokenSets; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.AssignmentExpression; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.PrimaryExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.ListOrMapConstructorExpression; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.Statement; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.primary.PrimaryExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; /** @@ -31,21 +30,15 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; */ public class ArgumentList implements GroovyElementTypes { - public static void parse(PsiBuilder builder, IElementType closingBrace) { - boolean hasntFirstArg = false; - if (hasntFirstArg = !argumentParse(builder, closingBrace)) { + public static void parseArgumentList(PsiBuilder builder, IElementType closingBrace) { + boolean hasFirstArg = argumentParse(builder, closingBrace); + if (!hasFirstArg) { if (!closingBrace.equals(builder.getTokenType())) { builder.error(GroovyBundle.message("expression.expected")); } if (mRCURLY.equals(builder.getTokenType())) return; - PsiBuilder.Marker statementMarker = builder.mark(); - if (Statement.parse(builder, true)) { - statementMarker.rollbackTo(); - return; - } else { - statementMarker.rollbackTo(); - } + if (isStatementStart(builder)) return; if (!mCOMMA.equals(builder.getTokenType()) && !closingBrace.equals(builder.getTokenType())) { @@ -55,7 +48,7 @@ public class ArgumentList implements GroovyElementTypes { ParserUtils.getToken(builder, mNLS); while (!builder.eof() && !closingBrace.equals(builder.getTokenType())) { - if (hasntFirstArg) { + if (!hasFirstArg) { ParserUtils.getToken(builder, mCOMMA); } else { ParserUtils.getToken(builder, mCOMMA, GroovyBundle.message("comma.expected")); @@ -67,13 +60,7 @@ public class ArgumentList implements GroovyElementTypes { } if (mRCURLY.equals(builder.getTokenType())) return; - PsiBuilder.Marker statementMarker = builder.mark(); - if (Statement.parse(builder, true)) { - statementMarker.rollbackTo(); - return; - } else { - statementMarker.rollbackTo(); - } + if (isStatementStart(builder)) return; if (!mCOMMA.equals(builder.getTokenType()) && !closingBrace.equals(builder.getTokenType())) { @@ -86,6 +73,17 @@ public class ArgumentList implements GroovyElementTypes { ParserUtils.getToken(builder, mNLS); } + private static boolean isStatementStart(PsiBuilder builder) { + /*PsiBuilder.Marker statementMarker = builder.mark(); + if (GroovyParser.parseStatement(builder, true)) { + statementMarker.rollbackTo(); + return true; + } else { + statementMarker.rollbackTo(); + }*/ + return false; + } + /** * Parses argument, possible with label * diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java index b38eae8ccd..89d77227c6 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/arithmetic/PathExpression.java @@ -186,7 +186,7 @@ public class PathExpression implements GroovyElementTypes { PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, mLBRACK); ParserUtils.getToken(builder, mNLS); - ArgumentList.parse(builder, mRBRACK); + ArgumentList.parseArgumentList(builder, mRBRACK); ParserUtils.getToken(builder, mNLS); ParserUtils.getToken(builder, mRBRACK, GroovyBundle.message("rbrack.expected")); marker.done(ARGUMENTS); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/ListOrMapConstructorExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/ListOrMapConstructorExpression.java index f1f74c8772..4be1507f54 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/ListOrMapConstructorExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/ListOrMapConstructorExpression.java @@ -17,7 +17,6 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions. import com.intellij.lang.PsiBuilder; import org.jetbrains.plugins.groovy.GroovyBundle; -import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arguments.ArgumentList; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; @@ -39,7 +38,7 @@ public class ListOrMapConstructorExpression implements GroovyElementTypes { } else if (ParserUtils.getToken(builder, mCOLON)) { ParserUtils.getToken(builder, mRBRACK, GroovyBundle.message("rbrack.expected")); } else { - ArgumentList.parse(builder, mRBRACK); + ArgumentList.parseArgumentList(builder, mRBRACK); ParserUtils.getToken(builder, mNLS); ParserUtils.getToken(builder, mRBRACK, GroovyBundle.message("rbrack.expected")); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java index 9df7db9038..1de1a2717d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/expressions/primary/PrimaryExpression.java @@ -178,7 +178,7 @@ public class PrimaryExpression implements GroovyElementTypes { PsiBuilder.Marker marker = builder.mark(); if (ParserUtils.getToken(builder, mLPAREN, GroovyBundle.message("lparen.expected"))) { ParserUtils.getToken(builder, mNLS); - ArgumentList.parse(builder, mRPAREN); + ArgumentList.parseArgumentList(builder, mRPAREN); ParserUtils.getToken(builder, mNLS); ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected")); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/EnumConstant.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/EnumConstant.java index 2dd8130f81..1fc4d80946 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/EnumConstant.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/statements/typeDefinitions/members/EnumConstant.java @@ -43,7 +43,7 @@ public class EnumConstant implements GroovyElementTypes { if (mLPAREN.equals(builder.getTokenType())) { PsiBuilder.Marker marker = builder.mark(); ParserUtils.getToken(builder, mLPAREN); - ArgumentList.parse(builder, mRPAREN); + ArgumentList.parseArgumentList(builder, mRPAREN); ParserUtils.getToken(builder, mNLS); ParserUtils.getToken(builder, mRPAREN, GroovyBundle.message("rparen.expected")); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/toplevel/CompilationUnit.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/toplevel/CompilationUnit.java index 10c6a5e3b8..62e51e13b4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/toplevel/CompilationUnit.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/toplevel/CompilationUnit.java @@ -18,8 +18,8 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.toplevel; import com.intellij.lang.PsiBuilder; import org.jetbrains.plugins.groovy.GroovyBundle; import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes; +import org.jetbrains.plugins.groovy.lang.parser.GroovyParser; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.Separators; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.Statement; import org.jetbrains.plugins.groovy.lang.parser.parsing.toplevel.packaging.PackageDefinition; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; @@ -38,12 +38,12 @@ public class CompilationUnit implements GroovyElementTypes { if (builder.getTokenType() == kPACKAGE) { PackageDefinition.parse(builder); } else { - Statement.parseWithImports(builder); + GroovyParser.parseStatementWithImports(builder); } cleanAfterError(builder); while (Separators.parse(builder)) { - Statement.parseWithImports(builder); + GroovyParser.parseStatementWithImports(builder); cleanAfterError(builder); } } -- 2.11.4.GIT