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 493de46d9ddd..53318217f5a1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/GroovyConstructorUsagesSearcher.java @@ -47,15 +47,12 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils; import org.jetbrains.plugins.groovy.gpp.GppTypeConverter; import org.jetbrains.plugins.groovy.lang.psi.GrReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; -import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrConstructorInvocation; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable; import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList; -import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock; import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*; import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter; @@ -67,9 +64,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction; import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider; -import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; -import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; -import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.Arrays; import java.util.HashSet; @@ -111,13 +105,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase literalProcessor = new PairProcessor() { - - @Override - public boolean process(GrListOrMap list, PsiClassType expectedType) { - return checkLiteralInstantiation(constructor, consumer, list, expectedType); - } - }; + final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer); final Processor newExpressionProcessor = new Processor() { @Override @@ -155,7 +143,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase newExpressionProcessor, - final PairProcessor literalProcessor) { + final LiteralConstructorSearcher literalProcessor) { final Set processedMethods = new ConcurrentHashSet(); ReferencesSearch.searchOptimized(clazz, scope, true, collector, true, new PairProcessor() { @@ -200,7 +188,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase literalProcessor) { + final LiteralConstructorSearcher literalProcessor) { final SearchScope gppScope = getGppScope(targetClass.getProject()).intersectWith(scope); final ReadActionProcessor gppCallProcessor = new ReadActionProcessor() { @Override @@ -224,7 +212,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase newExpressionProcessor, - final PairProcessor literalProcessor) { + final LiteralConstructorSearcher literalProcessor) { PsiElement parent = element.getParent(); if (parent instanceof GrAnonymousClassDefinition) { @@ -344,88 +332,17 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase literalProcessor) { + final LiteralConstructorSearcher literalProcessor) { if (expression instanceof GrListOrMap) { final PsiType expectedType = typeElement.getType(); if (expectedType instanceof PsiClassType) { - return literalProcessor.process((GrListOrMap)expression, (PsiClassType)expectedType); + return literalProcessor.processLiteral((GrListOrMap)expression, (PsiClassType)expectedType); } } return true; } - private static boolean checkLiteralInstantiation(PsiMethod constructor, - Processor consumer, - GrListOrMap literal, - PsiClassType expectedType) { - final PsiType listType = literal.getType(); - if (listType instanceof GrTupleType) { - if (isConstructorCall(expectedType, ((GrTupleType)listType).getComponentTypes(), constructor, literal)) { - return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); - } - } - else if (listType instanceof GrMapType) { - final PsiType constructorArgs = ((GrMapType)listType).getValueType("super"); - if (constructorArgs == null) { - if (constructor.getParameterList().getParametersCount() == 0) { - if (!consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor))) { - return false; - } - } - return true; - } - - for (GrNamedArgument argument : literal.getNamedArguments()) { - final GrArgumentLabel label = argument.getLabel(); - if (label != null && "super".equals(label.getName())) { - if (mayInvokeConstructor(expectedType, constructor, argument.getExpression())) { - return consumer.process(PsiReferenceBase.createSelfReference(label, TextRange.from(0, label.getTextLength()), constructor)); - } - return true; - } - } - - //no 'super', only default constructor applicable - if (constructor.getParameterList().getParametersCount() == 0) { - return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); - } - } - return true; - } - - private static boolean mayInvokeConstructor(PsiClassType expectedType, PsiMethod constructor, GrExpression args) { - if (args == null) { - return true; - } - - final PsiType type = args.getType(); - if (type == null) { - return true; - } - - if (type instanceof GrTupleType) { - if (!isConstructorCall(expectedType, ((GrTupleType)type).getComponentTypes(), constructor, args)) { - return false; - } - } else if (!isConstructorCall(expectedType, new PsiType[]{type}, constructor, args)) { - return false; - } - return true; - } - - private static boolean isConstructorCall(PsiClassType expectedType, - PsiType[] argTypes, - PsiMethod constructor, - GroovyPsiElement context) { - for (GroovyResolveResult candidate : PsiUtil.getConstructorCandidates(expectedType, argTypes, context)) { - if (constructor.getManager().areElementsEquivalent(candidate.getElement(), constructor)) { - return true; - } - } - return false; - } - private static boolean processConstructors(final PsiMethod searchedConstructor, final Processor consumer, final PsiClass clazz, final boolean processThisRefs) { final PsiMethod[] constructors = clazz.getConstructors(); diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java new file mode 100644 index 000000000000..135571684e41 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/LiteralConstructorSearcher.java @@ -0,0 +1,99 @@ +package org.jetbrains.plugins.groovy.findUsages; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.util.Processor; +import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement; +import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult; +import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType; +import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; + +/** +* @author peter +*/ +class LiteralConstructorSearcher { + private final PsiMethod myConstructor; + private final Processor myConsumer; + + public LiteralConstructorSearcher(PsiMethod constructor, Processor consumer) { + myConstructor = constructor; + myConsumer = consumer; + } + + private static boolean checkLiteralInstantiation(PsiMethod constructor, + Processor consumer, + GrListOrMap literal, + PsiClassType expectedType) { + final PsiType listType = literal.getType(); + if (listType instanceof GrTupleType) { + if (isConstructorCall(expectedType, ((GrTupleType)listType).getComponentTypes(), constructor, literal)) { + return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); + } + } + else if (listType instanceof GrMapType) { + final PsiType constructorArgs = ((GrMapType)listType).getValueType("super"); + if (constructorArgs == null) { + if (constructor.getParameterList().getParametersCount() == 0) { + if (!consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor))) { + return false; + } + } + return true; + } + + for (GrNamedArgument argument : literal.getNamedArguments()) { + final GrArgumentLabel label = argument.getLabel(); + if (label != null && "super".equals(label.getName())) { + if (mayInvokeConstructor(expectedType, constructor, argument.getExpression())) { + return consumer.process(PsiReferenceBase.createSelfReference(label, TextRange.from(0, label.getTextLength()), constructor)); + } + return true; + } + } + + //no 'super', only default constructor applicable + if (constructor.getParameterList().getParametersCount() == 0) { + return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor)); + } + } + return true; + } + + private static boolean mayInvokeConstructor(PsiClassType expectedType, PsiMethod constructor, GrExpression args) { + if (args == null) { + return true; + } + + final PsiType type = args.getType(); + if (type == null) { + return true; + } + + if (type instanceof GrTupleType) { + return isConstructorCall(expectedType, ((GrTupleType)type).getComponentTypes(), constructor, args); + } + + return isConstructorCall(expectedType, new PsiType[]{type}, constructor, args); + } + + private static boolean isConstructorCall(PsiClassType expectedType, + PsiType[] argTypes, + PsiMethod constructor, + GroovyPsiElement context) { + for (GroovyResolveResult candidate : PsiUtil.getConstructorCandidates(expectedType, argTypes, context)) { + if (constructor.getManager().areElementsEquivalent(candidate.getElement(), constructor)) { + return true; + } + } + return false; + } + + public boolean processLiteral(GrListOrMap list, PsiClassType expectedType) { + return checkLiteralInstantiation(myConstructor, myConsumer, list, expectedType); + } +}