diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java index 0cbe9c32803f..8a71e69e7784 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionData.java @@ -25,6 +25,7 @@ import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.lang.ASTNode; +import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.*; import com.intellij.psi.templateLanguages.OuterLanguageElement; @@ -42,6 +43,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation. import org.jetbrains.plugins.groovy.lang.psi.api.statements.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrTraditionalForClause; 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.params.GrParameter; @@ -96,7 +98,10 @@ public class GroovyCompletionData { result.addElement(keyword("as", TailType.HUMBLE_SPACE_BEFORE_WORD)); } - if (isInfixOperatorPosition(position)) { + if (isAfterForParameter(position)) { + addKeywords(result, true, "in"); + } + else if (isInfixOperatorPosition(position)) { addKeywords(result, true, "in", PsiKeyword.INSTANCEOF); } else if (suggestThrows(position)) { result.addElement(keyword(PsiKeyword.THROWS, TailType.INSERT_SPACE)); @@ -135,6 +140,13 @@ public class GroovyCompletionData { } } + private static boolean isAfterForParameter(PsiElement position) { + ElementPattern forParameter = + psiElement().withParents(GrParameter.class, GrTraditionalForClause.class, GrForStatement.class); + return psiElement().withParent(GrReferenceExpression.class).afterLeaf(forParameter).accepts(position) || + forParameter.accepts(position) && psiElement().afterLeaf(psiElement(GroovyTokenTypes.mIDENT)).accepts(position); + } + public static void addModifiers(PsiElement position, CompletionResultSet result) { PsiClass scope = PsiTreeUtil.getParentOfType(position, PsiClass.class); PsiModifierList modifierList = ModifierChooser.findModifierList(position); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy index 57e82942aeff..4eda27241e6a 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyAutoPopupTest.groovy @@ -184,6 +184,7 @@ class GroovyAutoPopupTest extends CompletionAutoPopupTestCase { assert !lookup type 'c' assert !lookup.focused + assert 'char' in myFixture.lookupElementStrings assert myFixture.editor.document.text.contains('for(final c)') type ' in c' assert lookup.focused diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy index 739fa2d75186..475f214ad1d4 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/completion/GroovyCompletionTest.groovy @@ -1188,4 +1188,9 @@ new Base().fiex''') assert myFixture.lookupElementStrings == ['field1'] } + public void testForIn() { + assert doContainsTest('in', 'for (int i i') + assert doContainsTest('in', 'for (i i') + } + } \ No newline at end of file