diff --git a/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java b/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java index 27392019f5c2..645d668b1a89 100644 --- a/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java +++ b/java/java-impl/src/com/intellij/codeInsight/template/JavaCodeContextType.java @@ -94,10 +94,10 @@ public abstract class JavaCodeContextType extends TemplateContextType { } private static boolean isStatementContext(PsiElement element) { - if (!Expression.isExpressionContext(element)) { + if (isAfterExpression(element)) { return false; } - + PsiStatement statement = PsiTreeUtil.getParentOfType(element, PsiStatement.class); return statement != null && statement.getTextRange().getStartOffset() == element.getTextRange().getStartOffset(); } @@ -132,17 +132,22 @@ public abstract class JavaCodeContextType extends TemplateContextType { return false; } - ProcessingContext context = new ProcessingContext(); - if (psiElement().inside(PsiExpression.class).afterLeaf(psiElement().inside(psiElement(PsiExpression.class).save("prevExpr"))).accepts(element, context)) { - PsiExpression prevExpr = (PsiExpression)context.get("prevExpr"); - if (prevExpr.getTextRange().getEndOffset() <= element.getTextRange().getStartOffset()) { - return false; - } - } - - return true; + return !isAfterExpression(element); } } + + private static boolean isAfterExpression(PsiElement element) { + ProcessingContext context = new ProcessingContext(); + if (psiElement().inside(PsiExpression.class).afterLeaf(psiElement().inside(psiElement(PsiExpression.class).save("prevExpr"))).accepts(element, context)) { + PsiExpression prevExpr = (PsiExpression)context.get("prevExpr"); + if (prevExpr.getTextRange().getEndOffset() <= element.getTextRange().getStartOffset()) { + return true; + } + } + + return false; + } + public static class Declaration extends JavaCodeContextType { public Declaration() { super("JAVA_DECLARATION", "Declaration", Generic.class); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/template/GroovyTemplateContextType.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/template/GroovyTemplateContextType.java index ffbf21162869..4e0387dc8e36 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/template/GroovyTemplateContextType.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/template/GroovyTemplateContextType.java @@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.template; import com.intellij.codeInsight.template.EverywhereContextType; import com.intellij.codeInsight.template.TemplateContextType; +import com.intellij.openapi.util.Condition; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; @@ -80,12 +81,16 @@ public abstract class GroovyTemplateContextType extends TemplateContextType { @Override protected boolean isInContext(@NotNull PsiElement element) { - return isStatementContext(element); + PsiElement stmt = PsiTreeUtil.findFirstParent(element, new Condition() { + @Override + public boolean value(PsiElement element11) { + return PsiUtil.isExpressionStatement(element11.getParent()); + } + }); + + return !isAfterExpression(element) && stmt != null && stmt.getTextRange().getStartOffset() == element.getTextRange().getStartOffset(); } - private static boolean isStatementContext(PsiElement element) { - return Expression.isExpressionContext(element) && PsiUtil.isExpressionStatement(element.getParent()); - } } public static class Expression extends GroovyTemplateContextType { @@ -109,17 +114,22 @@ public abstract class GroovyTemplateContextType extends TemplateContextType { if (parent.getParent() instanceof GrCall) { return false; } - ProcessingContext context = new ProcessingContext(); - if (PlatformPatterns.psiElement().inside(GrExpression.class).afterLeaf( - PlatformPatterns.psiElement().inside(PlatformPatterns.psiElement(GrExpression.class).save("prevExpr"))).accepts(element, context)) { - PsiElement prevExpr = (PsiElement)context.get("prevExpr"); - if (prevExpr.getTextRange().getEndOffset() <= element.getTextRange().getStartOffset()) { - return false; - } - } - return true; + return !isAfterExpression(element); } } + + private static boolean isAfterExpression(PsiElement element) { + ProcessingContext context = new ProcessingContext(); + if (PlatformPatterns.psiElement().afterLeaf( + PlatformPatterns.psiElement().inside(PlatformPatterns.psiElement(GrExpression.class).save("prevExpr"))).accepts(element, context)) { + PsiElement prevExpr = (PsiElement)context.get("prevExpr"); + if (prevExpr.getTextRange().getEndOffset() <= element.getTextRange().getStartOffset()) { + return true; + } + } + return false; + } + public static class Declaration extends GroovyTemplateContextType { public Declaration() { super("GROOVY_DECLARATION", "Declaration", Generic.class); diff --git a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyLiveTemplatesTest.java b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyLiveTemplatesTest.java index ce5cddb94c8b..bec6e453fd68 100644 --- a/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyLiveTemplatesTest.java +++ b/plugins/groovy/test/org/jetbrains/plugins/groovy/lang/GroovyLiveTemplatesTest.java @@ -63,6 +63,8 @@ public class GroovyLiveTemplatesTest extends LightCodeInsightFixtureTestCase{ assertTrue(isApplicable("inst", template)); assertFalse(isApplicable("class Foo {{ return (inst) }}", template)); assertFalse(isApplicable("class Foo {{ return a inst) }}", template)); + assertTrue(isApplicable("a.b()", template)); + assertTrue(isApplicable("a()", template)); } public void testGroovyExpressionContext() throws Exception {