From a7df4c1ba332fe03bb3b809c8d5783431ce8b6c2 Mon Sep 17 00:00:00 2001 From: Maxim Medvedev Date: Tue, 10 Nov 2009 17:56:04 +0300 Subject: [PATCH] for-in fix --- .../plugins/groovy/GroovyBundle.properties | 2 + .../plugins/groovy/annotator/GroovyAnnotator.java | 20 ++++++ .../parser/parsing/statements/ForStatement.java | 84 +++++++--------------- 3 files changed, 48 insertions(+), 58 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties index 6999e58898..bb3efddebe 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/GroovyBundle.properties @@ -298,3 +298,5 @@ groovy.like.library.found.text=Do you want to set up Groovy for module ''{0}'' \ with found library ''{1}'' (Groovy version {2})? compile.groovy.files=&Compile Groovy files copy.groovy.files.to.output=Copy Groovy files to output as &resources +in.expected='in' expected +not.allowed.modifier.in.forin=Modifier ''{0}'' is not allowed here diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index 1875d195ef..508db40744 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -61,6 +61,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrBreakStatem import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrContinueStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrFlowInterruptingStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrReturnStatement; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrForInClause; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression; @@ -160,6 +161,9 @@ public class GroovyAnnotator implements Annotator { else if (element instanceof GrLiteral) { checkLiteral(((GrLiteral)element), holder); } + else if (element instanceof GrForInClause) { + checkForInClause(((GrForInClause)element), holder); + } else if (element instanceof GroovyFile) { final GroovyFile file = (GroovyFile)element; if (file.isScript()) { @@ -181,6 +185,22 @@ public class GroovyAnnotator implements Annotator { } } + private static void checkForInClause(GrForInClause forInClause, AnnotationHolder holder) { + final GrVariable[] declaredVariables = forInClause.getDeclaredVariables(); + if (declaredVariables.length < 1) return; + final GrVariable variable = declaredVariables[0]; + final GrModifierList modifierList = ((GrModifierList)variable.getModifierList()); + if (modifierList == null) return; + final PsiElement[] modifiers = modifierList.getModifiers(); + for (PsiElement modifier : modifiers) { + if (modifier instanceof PsiAnnotation) continue; + final String modifierText = modifier.getText(); + if (PsiModifier.FINAL.equals(modifierText)) continue; + if ("def".equals(modifierText)) continue; + holder.createErrorAnnotation(modifier, GroovyBundle.message("not.allowed.modifier.in.forin", modifierText)); + } + } + private static void checkLiteral(GrLiteral literal, AnnotationHolder holder) { String text = literal.getText(); if (text.startsWith("'''")) { 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 de26018560..01dc392c32 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 @@ -22,7 +22,6 @@ 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.modifiers.Modifiers; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.Declaration; -import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.declaration.DeclarationStart; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.StrictContextExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.arithmetic.ShiftExpression; import org.jetbrains.plugins.groovy.lang.parser.parsing.types.TypeSpec; @@ -42,16 +41,15 @@ public class ForStatement implements GroovyElementTypes { PsiBuilder.Marker marker = builder.mark(); - if (ParserUtils.getToken(builder, mSEMI) || - (Declaration.parse(builder, false, parser) && - ParserUtils.getToken(builder, mSEMI))) { + if (ParserUtils.getToken(builder, mSEMI) || (Declaration.parse(builder, false, 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())) { controlExpressionListParse(builder, parser); } - } else { + } + else { marker.rollbackTo(); marker = builder.mark(); controlExpressionListParse(builder, parser); @@ -77,24 +75,23 @@ public class ForStatement implements GroovyElementTypes { while (mCOMMA.equals(builder.getTokenType())) { - if (ParserUtils.lookAhead(builder, mCOMMA, mNLS, mRPAREN) || - ParserUtils.lookAhead(builder, mCOMMA, mRPAREN)) { + if (ParserUtils.lookAhead(builder, mCOMMA, mNLS, mRPAREN) || ParserUtils.lookAhead(builder, mCOMMA, mRPAREN)) { ParserUtils.getToken(builder, mCOMMA); builder.error(GroovyBundle.message("expression.expected")); - } else { + } + else { ParserUtils.getToken(builder, mCOMMA); } ParserUtils.getToken(builder, mNLS); if (!StrictContextExpression.parse(builder, parser)) { ParserUtils.getToken(builder, mNLS); - if (!mRPAREN.equals(builder.getTokenType()) && - !mSEMI.equals(builder.getTokenType())) { + if (!mRPAREN.equals(builder.getTokenType()) && !mSEMI.equals(builder.getTokenType())) { builder.error(GroovyBundle.message("expression.expected")); } if (!mRPAREN.equals(builder.getTokenType()) && - !mSEMI.equals(builder.getTokenType()) && - !mCOMMA.equals(builder.getTokenType()) && - !mNLS.equals(builder.getTokenType())) { + !mSEMI.equals(builder.getTokenType()) && + !mCOMMA.equals(builder.getTokenType()) && + !mNLS.equals(builder.getTokenType())) { builder.advanceLexer(); } } @@ -108,56 +105,27 @@ public class ForStatement implements GroovyElementTypes { PsiBuilder.Marker marker = builder.mark(); - PsiBuilder.Marker declMarker = builder.mark(); - - if (ParserUtils.lookAhead(builder, mIDENT, kIN)) { - ParserUtils.eatElement(builder, PARAMETER); - declMarker.drop(); - ParserUtils.getToken(builder, kIN); - if (!ShiftExpression.parse(builder, parser)) { - builder.error(GroovyBundle.message("expression.expected")); - } - marker.done(FOR_IN_CLAUSE); - return true; + PsiBuilder.Marker parameterMarker = builder.mark(); + Modifiers.parse(builder, parser); + if (ParserUtils.lookAhead(builder, mIDENT, kIN) || ParserUtils.lookAhead(builder, mIDENT, mCOLON)) { + ParserUtils.getToken(builder, mIDENT); } - - if (DeclarationStart.parse(builder, parser)) { - if (Modifiers.parse(builder, parser)) { - TypeSpec.parse(builder); - return singleDeclNoInitParse(builder, marker, declMarker, parser); - } + else { + TypeSpec.parseStrict(builder); + ParserUtils.getToken(builder, mIDENT, GroovyBundle.message("identifier.expected")); } + parameterMarker.done(PARAMETER); - if (TypeSpec.parse(builder)) { - return singleDeclNoInitParse(builder, marker, declMarker, parser); + if (!ParserUtils.getToken(builder, kIN) && !ParserUtils.getToken(builder, mCOLON)) { + builder.error(GroovyBundle.message("in.expected")); + marker.drop(); + return false; } - declMarker.drop(); - marker.drop(); - return false; - } - - private static boolean singleDeclNoInitParse(PsiBuilder builder, - PsiBuilder.Marker marker, - PsiBuilder.Marker declMarker, GroovyParser parser) { - if (ParserUtils.getToken(builder, mIDENT)) { - if (kIN.equals(builder.getTokenType()) || mCOLON.equals(builder.getTokenType())) { - declMarker.done(PARAMETER); - builder.advanceLexer(); - if (!ShiftExpression.parse(builder, parser)) { - builder.error(GroovyBundle.message("expression.expected")); - } - marker.done(FOR_IN_CLAUSE); - return true; - } else { - marker.rollbackTo(); - return false; - } - } else { - declMarker.drop(); - marker.rollbackTo(); - return false; + if (!ShiftExpression.parse(builder, parser)) { + builder.error(GroovyBundle.message("expression.expected")); } + marker.done(FOR_IN_CLAUSE); + return true; } - } -- 2.11.4.GIT