diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java index a810c1ee862f..2c00d4cafbee 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/parser/parsing/auxiliary/parameters/ParameterDeclaration.java @@ -23,6 +23,7 @@ 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.VariableInitializer; import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.annotations.Annotation; +import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.typeDefinitions.ReferenceElement; import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeSpec; import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier; @@ -36,17 +37,33 @@ import java.util.Set; public class ParameterDeclaration implements GroovyElementTypes { public static boolean parse(PsiBuilder builder, GroovyParser parser) { + return parse(builder, parser, false); + } + + public static boolean parse(PsiBuilder builder, GroovyParser parser, boolean forForStatement) { PsiBuilder.Marker pdMarker = builder.mark(); // Parse optional modifier(s) - parseOptionalModifier(builder, parser); + final boolean hasModifiers = parseOptionalModifier(builder, parser); PsiBuilder.Marker rb = builder.mark(); - TypeSpec.parseStrict(builder); - if (!(mIDENT.equals(builder.getTokenType()) || mTRIPLE_DOT.equals(builder.getTokenType()))) { - rb.rollbackTo(); - } else { + final ReferenceElement.ReferenceElementResult result = TypeSpec.parseStrict(builder); + + if (forForStatement && result == ReferenceElement.ReferenceElementResult.fail && !hasModifiers) { rb.drop(); + pdMarker.rollbackTo(); + return false; + } + + if (mIDENT.equals(builder.getTokenType()) || (!forForStatement && mTRIPLE_DOT.equals(builder.getTokenType()))) { + rb.drop(); + } + else { + rb.rollbackTo(); + if (forForStatement && !hasModifiers) { + pdMarker.rollbackTo(); + return false; + } } // Possible it is a parameter, not statement @@ -58,12 +75,14 @@ public class ParameterDeclaration implements GroovyElementTypes { } pdMarker.done(PARAMETER); return true; - } else { + } + else { // If has triple dots if (hasDots) { pdMarker.error(GroovyBundle.message("identifier.expected")); return true; - } else { + } + else { pdMarker.rollbackTo(); return false; } @@ -75,16 +94,17 @@ public class ParameterDeclaration implements GroovyElementTypes { * * @param builder Given builder */ - private static void parseOptionalModifier(PsiBuilder builder, GroovyParser parser) { + private static boolean parseOptionalModifier(PsiBuilder builder, GroovyParser parser) { Set modSet = new HashSet(); PsiBuilder.Marker marker = builder.mark(); + boolean hasModifiers = false; while (builder.getTokenType() == kFINAL || builder.getTokenType() == kDEF || builder.getTokenType() == mAT) { - + hasModifiers = true; if (kFINAL.equals(builder.getTokenType())) { if (modSet.contains(kFINAL)) { ParserUtils.wrapError(builder, GroovyBundle.message("duplicate.modifier", GrModifier.FINAL)); @@ -106,6 +126,7 @@ public class ParameterDeclaration implements GroovyElementTypes { } } marker.done(MODIFIERS); + return hasModifiers; } } 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 5a0bfd4e596d..e004af2b4063 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 @@ -42,27 +42,19 @@ public class ForStatement implements GroovyElementTypes { private static boolean tradForClauseParse(PsiBuilder builder, GroovyParser parser) { PsiBuilder.Marker marker = builder.mark(); - if (ParserUtils.getToken(builder, mSEMI) || (ParameterDeclaration.parse(builder, parser) && ParserUtils.getToken(builder, mSEMI))) { - StrictContextExpression.parse(builder, parser); - ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected")); - ParserUtils.getToken(builder, mNLS); - if (!mRPAREN.equals(builder.getTokenType())) { - StrictContextExpression.parse(builder, parser); - } - } - else { + if (!ParameterDeclaration.parse(builder, parser, true)) { marker.rollbackTo(); marker = builder.mark(); StrictContextExpression.parse(builder, parser); - ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected")); - StrictContextExpression.parse(builder, parser); - ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected")); - ParserUtils.getToken(builder, mNLS); - if (!mRPAREN.equals(builder.getTokenType())) { - StrictContextExpression.parse(builder, parser); - } } + ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected")); + StrictContextExpression.parse(builder, parser); + ParserUtils.getToken(builder, mSEMI, GroovyBundle.message("semi.expected")); + ParserUtils.getToken(builder, mNLS); + if (!mRPAREN.equals(builder.getTokenType())) { + StrictContextExpression.parse(builder, parser); + } marker.done(FOR_TRADITIONAL_CLAUSE); return true; } diff --git a/plugins/groovy/testdata/parsing/groovy/statements/for/for10.test b/plugins/groovy/testdata/parsing/groovy/statements/for/for10.test index ea6cf9600cfb..24de169dd13b 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/for/for10.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/for/for10.test @@ -6,7 +6,7 @@ Groovy script PsiWhiteSpace(' ') PsiElement(()('(') Traditional FOR clause - Variable definitions + Parameter Modifiers Built in type diff --git a/plugins/groovy/testdata/parsing/groovy/statements/for/for5.test b/plugins/groovy/testdata/parsing/groovy/statements/for/for5.test index 39a9266ac84b..776d13a2f9fb 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/for/for5.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/for/for5.test @@ -6,7 +6,7 @@ Groovy script PsiWhiteSpace(' ') PsiElement(()('(') Traditional FOR clause - Variable definitions + Parameter Modifiers PsiElement(def)('def') PsiWhiteSpace(' ') diff --git a/plugins/groovy/testdata/parsing/groovy/statements/for/for9.test b/plugins/groovy/testdata/parsing/groovy/statements/for/for9.test index ea6cf9600cfb..24de169dd13b 100644 --- a/plugins/groovy/testdata/parsing/groovy/statements/for/for9.test +++ b/plugins/groovy/testdata/parsing/groovy/statements/for/for9.test @@ -6,7 +6,7 @@ Groovy script PsiWhiteSpace(' ') PsiElement(()('(') Traditional FOR clause - Variable definitions + Parameter Modifiers Built in type