From d03918c12b04abecd1bd16f6bb302bcebb5934d2 Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 18 Mar 2015 12:06:37 +0100 Subject: [PATCH] more strict control over which unresolved references to report as groovy dynamic usages: take into account closure arguments don't report property access as a method usage don't return usages with a qualifier of a known type --- .../MethodLateBoundReferencesSearcher.java | 39 +++++++++++++------ .../lang/findUsages/FindUsagesTest.groovy | 4 ++ .../DynamicCallExpressionUsages.groovy | 9 +++++ .../dynamicUsages/DynamicUsages.groovy | 8 +++- 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 plugins/groovy/testdata/findUsages/dynamicCallExpressionUsages/DynamicCallExpressionUsages.groovy diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java index 9cb674308041..004965dac484 100644 --- a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java +++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/findUsages/MethodLateBoundReferencesSearcher.java @@ -21,12 +21,17 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiMethod; +import com.intellij.psi.PsiReference; import com.intellij.psi.search.*; import com.intellij.psi.search.searches.MethodReferencesSearch; import com.intellij.psi.util.PropertyUtil; import com.intellij.util.Processor; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCommandArgumentList; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression; import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil; @@ -46,9 +51,8 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBase consumer) { final PsiMethod method = queryParameters.getMethod(); - SearchScope searchScope = GroovyScopeUtil.restrictScopeToGroovyFiles(queryParameters.getEffectiveSearchScope()).intersectWith(getUseScope(method)); - PsiClass aClass = method.getContainingClass(); - String className = aClass == null ? null : aClass.getName(); + SearchScope searchScope = GroovyScopeUtil.restrictScopeToGroovyFiles(queryParameters.getEffectiveSearchScope()).intersectWith( + getUseScope(method)); orderSearching(searchScope, method.getName(), method, queryParameters.getOptimizer(), method.getParameterList().getParametersCount()); final String propName = PropertyUtil.getPropertyName(method); @@ -85,16 +89,29 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBase= 0 && !ref.hasMemberPointer() && + (!(parent instanceof GrMethodCall) || !argumentsMatch((GrMethodCall)parent, paramCount))) { + return true; + } + + GrExpression qualifier = ref.getQualifierExpression(); + if (qualifier == null || qualifier.getType() != null) { + return true; + } + + if (ref.resolve() != null) { + return true; + } + + if (ResolveUtil.isKeyOfMap(ref)) { return true; } @@ -104,7 +121,7 @@ public class MethodLateBoundReferencesSearcher extends QueryExecutorBaseo(a) { } +} + +def boo(Map args, p) { + p.foo 2 + p.foo { println "hello" } +} + diff --git a/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy b/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy index 84dfaee0d831..c043e1c6f632 100644 --- a/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy +++ b/plugins/groovy/testdata/findUsages/dynamicUsages/DynamicUsages.groovy @@ -6,6 +6,12 @@ def boo(Map args, p) { println p.focused println p.isFocused() - println args.focused //not a usage + // not usage candidates + println focused + println isFocused() + println "a".focused + println "a".isFocused() + + println args.focused }