mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
find overloaded constructor usages in literals
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReferenc
|
||||
if (element instanceof PsiMethod) {
|
||||
final PsiMethod method = (PsiMethod)element;
|
||||
if (method.isConstructor()) {
|
||||
GroovyConstructorUsagesSearcher.processConstructorUsages(method, queryParameters.getScope(), consumer, queryParameters.getOptimizer(), true);
|
||||
GroovyConstructorUsagesSearcher.processConstructorUsages(method, queryParameters.getScope(), consumer, queryParameters.getOptimizer(), true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -80,10 +80,10 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
|
||||
@Override
|
||||
public void processQuery(MethodReferencesSearch.SearchParameters p, Processor<PsiReference> consumer) {
|
||||
processConstructorUsages(p.getMethod(), p.getScope(), consumer, p.getOptimizer(), true);
|
||||
processConstructorUsages(p.getMethod(), p.getScope(), consumer, p.getOptimizer(), true, !p.isStrictSignatureSearch());
|
||||
}
|
||||
|
||||
static void processConstructorUsages(final PsiMethod constructor, final SearchScope searchScope, final Processor<PsiReference> consumer, final SearchRequestCollector collector, final boolean searchGppCalls) {
|
||||
static void processConstructorUsages(final PsiMethod constructor, final SearchScope searchScope, final Processor<PsiReference> consumer, final SearchRequestCollector collector, final boolean searchGppCalls, final boolean includeOverloads) {
|
||||
if (!constructor.isConstructor()) return;
|
||||
|
||||
SearchScope onlyGroovy = PsiUtil.restrictScopeToGroovyFiles(searchScope);
|
||||
@@ -103,7 +103,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
}
|
||||
}
|
||||
|
||||
final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer);
|
||||
final LiteralConstructorSearcher literalProcessor = new LiteralConstructorSearcher(constructor, consumer, includeOverloads);
|
||||
|
||||
final Processor<GrNewExpression> newExpressionProcessor = new Processor<GrNewExpression>() {
|
||||
@Override
|
||||
@@ -230,7 +230,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
}
|
||||
};
|
||||
if (currentTarget.isConstructor()) {
|
||||
processConstructorUsages(currentTarget, gppScope, gppCallProcessor, originalCollector, false);
|
||||
processConstructorUsages(currentTarget, gppScope, gppCallProcessor, originalCollector, false, false);
|
||||
}
|
||||
else {
|
||||
MethodReferencesSearch.searchOptimized(currentTarget, gppScope, true, originalCollector, gppCallProcessor);
|
||||
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package org.jetbrains.plugins.groovy.findUsages;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiReferenceBase;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
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.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class LiteralConstructorReference extends PsiReferenceBase.Poly<GrListOrMap> {
|
||||
private final PsiClassType myConstructedClass;
|
||||
|
||||
public LiteralConstructorReference(@NotNull GrListOrMap element, @NotNull PsiClassType constructedClassType) {
|
||||
super(element, TextRange.from(0, 1), false);
|
||||
myConstructedClass = constructedClassType;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiType[] argTypes() {
|
||||
final GrListOrMap literal = getElement();
|
||||
final PsiType listType = literal.getType();
|
||||
if (listType instanceof GrTupleType) {
|
||||
return ((GrTupleType)listType).getComponentTypes();
|
||||
}
|
||||
else if (listType instanceof GrMapType && ((GrMapType)listType).getValueType("super") == null) {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
final PsiType[] psiTypes = argTypes();
|
||||
if (psiTypes == null) return ResolveResult.EMPTY_ARRAY;
|
||||
|
||||
return PsiUtil.getConstructorCandidates(myConstructedClass, psiTypes, getElement());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] getVariants() {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
+19
-44
@@ -1,14 +1,13 @@
|
||||
package org.jetbrains.plugins.groovy.findUsages;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.Processor;
|
||||
import org.jetbrains.plugins.groovy.gpp.GppReferenceContributor;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -16,53 +15,29 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
public class LiteralConstructorSearcher {
|
||||
private final PsiMethod myConstructor;
|
||||
private final Processor<PsiReference> myConsumer;
|
||||
private final boolean myIncludeOverloads;
|
||||
|
||||
public LiteralConstructorSearcher(PsiMethod constructor, Processor<PsiReference> consumer) {
|
||||
public LiteralConstructorSearcher(PsiMethod constructor, Processor<PsiReference> consumer, boolean includeOverloads) {
|
||||
myConstructor = constructor;
|
||||
myConsumer = consumer;
|
||||
myIncludeOverloads = includeOverloads;
|
||||
}
|
||||
|
||||
private static boolean checkLiteralInstantiation(PsiMethod constructor,
|
||||
Processor<PsiReference> consumer,
|
||||
GrListOrMap literal,
|
||||
PsiClassType expectedType) {
|
||||
final PsiType listType = literal.getType();
|
||||
if (listType instanceof GrTupleType) {
|
||||
if (GppReferenceContributor.isConstructorCall(expectedType, ((GrTupleType)listType).getComponentTypes(), constructor, literal)) {
|
||||
return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor));
|
||||
public boolean processLiteral(GrListOrMap literal, PsiClassType expectedType) {
|
||||
if (literal.isMap()) {
|
||||
final GrNamedArgument argument = literal.findNamedArgument("super");
|
||||
if (argument != null) {
|
||||
return processConstructorReference(ObjectUtils.assertNotNull(argument.getLabel()).getReference());
|
||||
}
|
||||
}
|
||||
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())) {
|
||||
final PsiReference reference = label.getReference();
|
||||
if (reference != null && reference.isReferenceTo(constructor)) {
|
||||
return consumer.process(reference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return processConstructorReference(new LiteralConstructorReference(literal, expectedType));
|
||||
}
|
||||
|
||||
//no 'super', only default constructor applicable
|
||||
if (constructor.getParameterList().getParametersCount() == 0) {
|
||||
return consumer.process(PsiReferenceBase.createSelfReference(literal, TextRange.from(0, literal.getTextLength()), constructor));
|
||||
}
|
||||
}
|
||||
private boolean processConstructorReference(@Nullable PsiReference reference) {
|
||||
if (reference != null && (myIncludeOverloads || reference.isReferenceTo(myConstructor))) {
|
||||
return myConsumer.process(reference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean processLiteral(GrListOrMap list, PsiClassType expectedType) {
|
||||
return checkLiteralInstantiation(myConstructor, myConsumer, list, expectedType);
|
||||
}
|
||||
}
|
||||
|
||||
+4
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.UserDataHolderEx;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiArrayInitializerMemberValue;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
|
||||
@@ -42,5 +43,8 @@ public interface GrListOrMap extends UserDataHolderEx, Cloneable, Iconable, PsiE
|
||||
@NotNull
|
||||
GrNamedArgument[] getNamedArguments();
|
||||
|
||||
@Nullable
|
||||
GrNamedArgument findNamedArgument(@NotNull String label);
|
||||
|
||||
boolean isMap();
|
||||
}
|
||||
|
||||
+11
@@ -92,6 +92,17 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
return findChildrenByClass(GrNamedArgument.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrNamedArgument findNamedArgument(@NotNull String labelName) {
|
||||
for (GrNamedArgument argument : getNamedArguments()) {
|
||||
final GrArgumentLabel label = argument.getLabel();
|
||||
if (label != null && labelName.equals(label.getName())) {
|
||||
return argument;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MyTypesCalculator implements Function<GrListOrMapImpl, PsiType> {
|
||||
@Nullable
|
||||
public PsiType fun(GrListOrMapImpl listOrMap) {
|
||||
|
||||
+18
-1
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.plugins.groovy.lang
|
||||
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
import com.intellij.psi.search.searches.MethodReferencesSearch
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -160,4 +161,20 @@ class LiteralConstructorUsagesTest extends LightCodeInsightFixtureTestCase {
|
||||
assertEquals(2, ReferencesSearch.search(foo.constructors[1]).findAll().size())
|
||||
}
|
||||
|
||||
public void testOverloadedConstructorUsages() throws Exception {
|
||||
def foo = myFixture.addClass("""
|
||||
class Foo {
|
||||
Foo() {}
|
||||
Foo(int a) {}
|
||||
}
|
||||
""")
|
||||
|
||||
myFixture.addFileToProject "a.gpp", """
|
||||
Foo b = []
|
||||
Foo b1 = [2]
|
||||
"""
|
||||
assertEquals(2, MethodReferencesSearch.search(foo.constructors[0], false).findAll().size())
|
||||
assertEquals(2, MethodReferencesSearch.search(foo.constructors[1], false).findAll().size())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user