diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java index 67e627d267c9..852872969121 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java @@ -16,12 +16,10 @@ package org.jetbrains.plugins.groovy.findUsages; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.QueryExecutorBase; import com.intellij.openapi.application.ReadActionProcessor; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectRootManager; -import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -110,27 +108,28 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase processedMethods = new ConcurrentHashSet(); + final PairProcessor literalProcessor = new PairProcessor() { - ReferencesSearch.searchOptimized(clazz, searchScope, true, collector, true, new PairProcessor() { @Override - public boolean process(PsiReference ref, SearchRequestCollector collector) { - final PsiElement element = ref.getElement(); - if (element instanceof GrCodeReferenceElement) { - if (!processGroovyConstructorUsages((GrCodeReferenceElement)element, constructor, consumer, ref, !searchGppCalls)) { - return false; - } - } + public boolean process(GrListOrMap list, PsiClassType expectedType) { + return checkListInstantiation(constructor, consumer, list, expectedType); + } + }; - if (searchGppCalls) { - final PsiMethod method = getMethodToSearchForCallsWithLiteralArguments(element, clazz); - if (method != null && processedMethods.add(method)) { - processGppMethodCalls(clazz, constructor, consumer, searchScope, collector, method); - } + final boolean mapsNeeded = false; + + final Processor newExpressionProcessor = new Processor() { + @Override + public boolean process(GrNewExpression grNewExpression) { + final PsiMethod resolvedConstructor = grNewExpression.resolveConstructor(); + if (constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) { + return consumer.process(grNewExpression.getReferenceElement()); } return true; } - }); + }; + + processGroovyClassUsages(clazz, searchScope, collector, searchGppCalls, mapsNeeded, newExpressionProcessor, literalProcessor); //this() if (clazz instanceof GrTypeDefinition) { @@ -139,8 +138,9 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase() { - public boolean process(PsiClass inheritor) { + DirectClassInheritorsSearch.search(clazz, onlyGroovy).forEach(new ReadActionProcessor() { + @Override + public boolean processInReadAction(PsiClass inheritor) { if (inheritor instanceof GrTypeDefinition) { if (!processConstructors(constructor, consumer, inheritor, false)) return false; } @@ -149,8 +149,39 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase newExpressionProcessor, + final PairProcessor literalProcessor) { + final Set processedMethods = new ConcurrentHashSet(); + + ReferencesSearch.searchOptimized(clazz, scope, true, collector, true, new PairProcessor() { + @Override + public boolean process(PsiReference ref, SearchRequestCollector collector) { + final PsiElement element = ref.getElement(); + + if (element instanceof GrCodeReferenceElement) { + if (!processGroovyConstructorUsages((GrCodeReferenceElement)element, !searchGppCalls, newExpressionProcessor, mapsNeeded, literalProcessor)) { + return false; + } + } + + if (searchGppCalls) { + final PsiMethod method = getMethodToSearchForCallsWithLiteralArguments(element, clazz); + if (method != null && processedMethods.add(method)) { + processGppMethodCalls(clazz, scope, collector, method, mapsNeeded, literalProcessor); + } + } + return true; + } + }); + } + @Nullable - static PsiMethod getMethodToSearchForCallsWithLiteralArguments(PsiElement element, PsiClass targetClass) { + private static PsiMethod getMethodToSearchForCallsWithLiteralArguments(PsiElement element, PsiClass targetClass) { final PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class); if (parameter != null) { final PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class); @@ -167,10 +198,10 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase originalProcessor, SearchScope scope, - SearchRequestCollector originalCollector, @NotNull PsiMethod currentTarget) { + SearchRequestCollector originalCollector, @NotNull PsiMethod currentTarget, + final boolean mapsNeeded, + final PairProcessor literalProcessor) { final SearchScope gppScope = getGppScope(targetClass.getProject()).intersectWith(scope); final ReadActionProcessor gppCallProcessor = new ReadActionProcessor() { @Override @@ -183,7 +214,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase() { @Override public Result compute() { @@ -223,22 +254,25 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, - PsiReference ref, boolean usualCallsOnly) { + private static boolean processGroovyConstructorUsages(GrCodeReferenceElement element, + boolean usualCallsOnly, + final Processor newExpressionProcessor, + final boolean mapsNeeded, + final PairProcessor literalProcessor) { PsiElement parent = element.getParent(); if (parent instanceof GrAnonymousClassDefinition) { parent = parent.getParent(); } if (parent instanceof GrNewExpression) { - final PsiMethod resolvedConstructor = ((GrNewExpression)parent).resolveConstructor(); - if (constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor) && !consumer.process(ref)) { - return false; - } + return newExpressionProcessor.process((GrNewExpression)parent); } - else if (!usualCallsOnly && parent instanceof GrTypeElement) { + + if (usualCallsOnly) { + return true; + } + + if (parent instanceof GrTypeElement) { final GrTypeElement typeElement = (GrTypeElement)parent; final PsiElement grandpa = typeElement.getParent(); @@ -246,7 +280,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, - GrExpression expression, final GrTypeElement typeElement) { - if (expression instanceof GrListOrMap) { - final GrListOrMap list = (GrListOrMap)expression; - if (!list.isMap()) { - final PsiType expectedType = typeElement.getType(); - if (expectedType instanceof PsiClassType) { - return checkListInstantiation(constructor, consumer, list, (PsiClassType)expectedType); - } + private static boolean checkLiteralInstantiation(GrExpression expression, final GrTypeElement typeElement, final PairProcessor literalProcessor, boolean mapsNeeded) { + + if (expression instanceof GrListOrMap && mapsNeeded == ((GrListOrMap)expression).isMap()) { + final PsiType expectedType = typeElement.getType(); + if (expectedType instanceof PsiClassType) { + return literalProcessor.process((GrListOrMap)expression, (PsiClassType)expectedType); } } return true; } - static boolean checkListInstantiation(PsiMethod constructor, + private static boolean checkListInstantiation(PsiMethod constructor, Processor consumer, GrListOrMap list, PsiClassType expectedType) { @@ -342,19 +372,8 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase consumer, final PsiClass clazz, + private static boolean processConstructors(final PsiMethod searchedConstructor, final Processor consumer, final PsiClass clazz, final boolean processThisRefs) { - return ApplicationManager.getApplication().runReadAction(new Computable() { - public Boolean compute() { - return processClassConstructors(clazz, constructor, consumer, processThisRefs); - } - }); - } - - static boolean processClassConstructors(PsiClass clazz, - PsiMethod searchedConstructor, - Processor consumer, - boolean processThisRefs) { final PsiMethod[] constructors = clazz.getConstructors(); if (constructors.length == 0) { processImplicitConstructorCall(clazz, consumer, searchedConstructor); @@ -379,7 +398,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase processor, final PsiMethod constructor) { if (constructor instanceof GrMethod) {