IDEA-52429 GDSL enclosingCall doesn't match method calls without parentheses.
authorpeter <peter.gromov@jetbrains.com>
Mon, 8 Mar 2010 22:28:28 +0000 (22:28 +0000)
committerpeter <peter.gromov@jetbrains.com>
Mon, 8 Mar 2010 22:28:28 +0000 (22:28 +0000)
plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/dsltop/GroovyDslDefaultMembers.java
plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiElementCategory.java
plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/psi/PsiExpressionCategory.java
plugins/groovy/src/org/jetbrains/plugins/groovy/dsl/toplevel/Context.groovy
plugins/groovy/test/org/jetbrains/plugins/groovy/dsl/GroovyDslTest.groovy
plugins/groovy/testdata/groovy/dsl/DelegateToArgument2.groovy [new file with mode: 0644]
plugins/groovy/testdata/groovy/dsl/DelegateToArgument2_after.groovy [new file with mode: 0644]

index ceaa3c0ae54a0b83fe6855d05c85bd6b24e6cc4e..0bedfa2cf9c388ac76a9275fc7232c3a751f4b33 100644 (file)
@@ -22,10 +22,13 @@ import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.dsl.GdslMembersHolderConsumer;
 import org.jetbrains.plugins.groovy.dsl.holders.DelegatedMembersHolder;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
 
 /**
  * @author ilyas
@@ -90,23 +93,30 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider {
    * Returns enclosing method call of a given context's place
    */
   @Nullable
-  public GrMethodCallExpression enclosingCall(String name, GdslMembersHolderConsumer consumer) {
+  public GrCall enclosingCall(String name, GdslMembersHolderConsumer consumer) {
     final PsiElement place = consumer.getPlace();
     if (place == null) return null;
-    GrMethodCallExpression call = PsiTreeUtil.getParentOfType(place, GrMethodCallExpression.class, true);
+    GrCall call = PsiTreeUtil.getParentOfType(place, GrCall.class, true);
     if (call == null) return null;
     while (call != null && !name.equals(getInvokedMethodName(call))) {
-      call = PsiTreeUtil.getParentOfType(call, GrMethodCallExpression.class, true);
+      call = PsiTreeUtil.getParentOfType(call, GrCall.class, true);
     }
     if (call == null) return null;
-    for (GrExpression arg : call.getClosureArguments()) {
-      if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
-        return call;
+
+    final GrArgumentList argumentList = call.getArgumentList();
+    if (argumentList != null) {
+      for (GrExpression arg : argumentList.getExpressionArguments()) {
+        if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
+          return call;
+        }
       }
     }
-    for (GrExpression arg : call.getExpressionArguments()) {
-      if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
-        return call;
+
+    if (call instanceof GrMethodCallExpression) {
+      for (GrExpression arg : ((GrMethodCallExpression)call).getClosureArguments()) {
+        if (arg instanceof GrClosableBlock && PsiTreeUtil.findCommonParent(place, arg) == arg) {
+          return call;
+        }
       }
     }
     return null;
@@ -135,11 +145,12 @@ public class GroovyDslDefaultMembers implements GdslMembersProvider {
     return PsiTreeUtil.getParentOfType(place, PsiClass.class, true);
   }
 
-  private static String getInvokedMethodName(GrMethodCallExpression call) {
-    final GrExpression expr = call.getInvokedExpression();
+  @Nullable
+  private static String getInvokedMethodName(GrCall call) {
+    final GrExpression expr = call instanceof GrApplicationStatement ? ((GrApplicationStatement)call).getFunExpression() :
+                              call instanceof GrMethodCallExpression ? ((GrMethodCallExpression)call).getInvokedExpression() : null;
     if (expr instanceof GrReferenceExpression) {
-      GrReferenceExpression ref = (GrReferenceExpression)expr;
-      return ref.getName();
+      return ((GrReferenceExpression)expr).getName();
     }
     return null;
   }
index 3ef0290859cd8d2b364ea62bf8bbe71ef279e0cb..688c56e70d41e153b9347aa63763232a161391d8 100644 (file)
@@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrApplicationStatement;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
@@ -38,14 +39,11 @@ public class PsiElementCategory implements PsiEnhancerCategory {
 
   @Nullable
   public static PsiElement bind(PsiElement element) {
-    PsiElement elem = element instanceof GrMethodCallExpression ? ((GrMethodCallExpression)element).getInvokedExpression() : element;
+    PsiElement elem = element instanceof GrMethodCallExpression ? ((GrMethodCallExpression)element).getInvokedExpression() :
+                      element instanceof GrApplicationStatement ? ((GrApplicationStatement)element).getFunExpression() :
+                      element;
     final PsiReference ref = elem.getReference();
-    if (ref == null) {
-      return null;
-    }
-    else {
-      return ref.resolve();
-    }
+    return ref == null ? null : ref.resolve();
   }
 
   @Nullable
index d67f165093346345969631e64f90cf3346925f68..a44f9c783a833672f03c152e2deaf2b188c900ff 100644 (file)
 
 package org.jetbrains.plugins.groovy.dsl.psi;
 
-import com.intellij.psi.*;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiType;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
 
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 
 /**
  * @author ilyas
  */
+@SuppressWarnings({"UnusedDeclaration"})
 public class PsiExpressionCategory implements PsiEnhancerCategory{
 
   @Nullable
@@ -37,15 +40,15 @@ public class PsiExpressionCategory implements PsiEnhancerCategory{
   }
 
   /**
-   * Returns arguments of a call expression
    * @param call
-   * @return
+   * @return arguments
    */
-  public static Collection<GrExpression> getArguments(GrExpression call) {
-    if (call instanceof GrMethodCallExpression) {
-      return Arrays.asList(((GrMethodCallExpression)call).getExpressionArguments());
+  public static Collection<GrExpression> getArguments(GrCall call) {
+    final GrArgumentList argumentList = call.getArgumentList();
+    if (argumentList != null) {
+      return Arrays.asList(argumentList.getExpressionArguments());
     }
-    return new ArrayList<GrExpression>();
+    return Collections.emptyList();
   }
 
 }
index 0b451c19b30a275c07a3fdaa4a27659c2773efce..002a3c6a7983aff6bfa0665fa50a3a90dd754535 100644 (file)
@@ -12,8 +12,8 @@ import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ScriptScope
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression
-import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
 import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition
 import org.jetbrains.plugins.groovy.lang.psi.patterns.GroovyPatterns
 
@@ -102,7 +102,7 @@ class Context {
             if (parent instanceof GrArgumentList) {
               parent = parent.parent
             }
-            return parent instanceof GrMethodCallExpression
+            return parent instanceof GrCall
           }
         }
 
index 8fe717300dfa0c66a26961684ecd2c46de440823..dfda8d3181b5b8c9fc5a4d8bf5707ea97272fcb8 100644 (file)
@@ -84,6 +84,19 @@ public class GroovyDslTest extends CompletionTestBase {
       })
 """)
   }
+  
+  public void testDelegateToArgument2() throws Throwable {
+    doCustomTest("""
+      def ctx = context(scope: closureScope(isArgument: true))
+
+      contributor(ctx, {
+        def call = enclosingCall("boo")
+        if (call) {
+          delegatesTo(call.arguments[0]?.classType)
+        }
+      })
+""")
+  }
 
   public void testClassContext() throws Throwable {
     doCustomTest( """
diff --git a/plugins/groovy/testdata/groovy/dsl/DelegateToArgument2.groovy b/plugins/groovy/testdata/groovy/dsl/DelegateToArgument2.groovy
new file mode 100644 (file)
index 0000000..6b96ba0
--- /dev/null
@@ -0,0 +1,14 @@
+class MyDelegate {
+  def saySomething(String str) {
+    println str
+  }
+}
+
+class Runner {
+  def boo(c, Closure cl) { }
+}
+
+def runner = new Runner()
+runner.boo new MyDelegate(), {
+  say<caret>
+}
\ No newline at end of file
diff --git a/plugins/groovy/testdata/groovy/dsl/DelegateToArgument2_after.groovy b/plugins/groovy/testdata/groovy/dsl/DelegateToArgument2_after.groovy
new file mode 100644 (file)
index 0000000..5d873cc
--- /dev/null
@@ -0,0 +1,14 @@
+class MyDelegate {
+  def saySomething(String str) {
+    println str
+  }
+}
+
+class Runner {
+  def boo(c, Closure cl) { }
+}
+
+def runner = new Runner()
+runner.boo new MyDelegate(), {
+  saySomething <caret>
+}
\ No newline at end of file