mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
navigation from literals to the constructors they represent
overloaded constructors found in groovy 'new' syntax, too
This commit is contained in:
+7
-11
@@ -109,7 +109,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
@Override
|
||||
public boolean process(GrNewExpression grNewExpression) {
|
||||
final PsiMethod resolvedConstructor = grNewExpression.resolveConstructor();
|
||||
if (constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) {
|
||||
if (includeOverloads || constructor.getManager().areElementsEquivalent(resolvedConstructor, constructor)) {
|
||||
return consumer.process(grNewExpression.getReferenceElement());
|
||||
}
|
||||
return true;
|
||||
@@ -217,7 +217,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
for (PsiType psiType : GroovyExpectedTypesProvider.getDefaultExpectedTypes(argument)) {
|
||||
if (psiType instanceof PsiClassType &&
|
||||
targetClass.getManager().areElementsEquivalent(targetClass, ((PsiClassType)psiType).resolve()) &&
|
||||
!literalProcessor.processLiteral((GrListOrMap)argument, (PsiClassType)psiType)) {
|
||||
!literalProcessor.processLiteral((GrListOrMap)argument)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
final GrVariable[] vars = ((GrVariableDeclaration)grandpa).getVariables();
|
||||
if (vars.length == 1) {
|
||||
final GrVariable variable = vars[0];
|
||||
if (!checkLiteralInstantiation(variable.getInitializerGroovy(), typeElement, literalProcessor)) {
|
||||
if (!checkLiteralInstantiation(variable.getInitializerGroovy(), literalProcessor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -282,7 +282,7 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
ControlFlowUtils.visitAllExitPoints(method.getBlock(), new ControlFlowUtils.ExitPointVisitor() {
|
||||
@Override
|
||||
public boolean visitExitPoint(Instruction instruction, @Nullable GrExpression returnValue) {
|
||||
if (!checkLiteralInstantiation(returnValue, typeElement, literalProcessor)) {
|
||||
if (!checkLiteralInstantiation(returnValue, literalProcessor)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -293,14 +293,14 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
else if (grandpa instanceof GrTypeCastExpression) {
|
||||
final GrTypeCastExpression cast = (GrTypeCastExpression)grandpa;
|
||||
if (cast.getCastTypeElement() == typeElement &&
|
||||
!checkLiteralInstantiation(cast.getOperand(), typeElement, literalProcessor)) {
|
||||
!checkLiteralInstantiation(cast.getOperand(), literalProcessor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (grandpa instanceof GrSafeCastExpression) {
|
||||
final GrSafeCastExpression cast = (GrSafeCastExpression)grandpa;
|
||||
if (cast.getCastTypeElement() == typeElement &&
|
||||
!checkLiteralInstantiation(cast.getOperand(), typeElement, literalProcessor)) {
|
||||
!checkLiteralInstantiation(cast.getOperand(), literalProcessor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -336,14 +336,10 @@ public class GroovyConstructorUsagesSearcher extends QueryExecutorBase<PsiRefere
|
||||
}
|
||||
|
||||
private static boolean checkLiteralInstantiation(GrExpression expression,
|
||||
final GrTypeElement typeElement,
|
||||
final LiteralConstructorSearcher literalProcessor) {
|
||||
|
||||
if (expression instanceof GrListOrMap) {
|
||||
final PsiType expectedType = typeElement.getType();
|
||||
if (expectedType instanceof PsiClassType) {
|
||||
return literalProcessor.processLiteral((GrListOrMap)expression, (PsiClassType)expectedType);
|
||||
}
|
||||
return literalProcessor.processLiteral((GrListOrMap)expression);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
+81
-9
@@ -1,17 +1,26 @@
|
||||
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 com.intellij.psi.*;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
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.GrNamedArgument;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrTypeCastExpression;
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
@@ -19,10 +28,66 @@ public class LiteralConstructorReference extends PsiReferenceBase.Poly<GrListOrM
|
||||
private final PsiClassType myConstructedClass;
|
||||
|
||||
public LiteralConstructorReference(@NotNull GrListOrMap element, @NotNull PsiClassType constructedClassType) {
|
||||
super(element, TextRange.from(0, 1), false);
|
||||
super(element, TextRange.from(0, 0), false);
|
||||
myConstructedClass = constructedClassType;
|
||||
}
|
||||
|
||||
private static boolean isConstructorCall(PsiClassType expectedType,
|
||||
@Nullable 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 static List<ResolveResult> getConstructorCandidates(PsiClassType classType,
|
||||
@NotNull GroovyPsiElement context, @Nullable PsiType[] argTypes) {
|
||||
PsiClass psiClass = classType.resolve();
|
||||
if (psiClass == null) return Collections.emptyList();
|
||||
|
||||
List<ResolveResult> applicable = CollectionFactory.arrayList();
|
||||
final List<ResolveResult> byName = CollectionFactory.arrayList();
|
||||
for (PsiMethod constructor : psiClass.getConstructors()) {
|
||||
final ResolveResult resolveResult = new PsiElementResolveResult(constructor);
|
||||
byName.add(resolveResult);
|
||||
if (argTypes != null && isConstructorCall(classType, argTypes, constructor, context)) {
|
||||
applicable.add(resolveResult);
|
||||
}
|
||||
}
|
||||
if (applicable.isEmpty()) {
|
||||
applicable.addAll(byName);
|
||||
}
|
||||
return applicable;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiClassType getTargetConversionType(@NotNull GrExpression expression) {
|
||||
//todo hack
|
||||
if (expression.getParent() instanceof GrSafeCastExpression) {
|
||||
final PsiType type = ((GrSafeCastExpression)expression.getParent()).getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
return (PsiClassType)type;
|
||||
}
|
||||
}
|
||||
if (expression.getParent() instanceof GrTypeCastExpression) {
|
||||
final PsiType type = ((GrTypeCastExpression)expression.getParent()).getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
return (PsiClassType)type;
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiType type : GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression)) {
|
||||
if (type instanceof PsiClassType) {
|
||||
return (PsiClassType)type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiType[] argTypes() {
|
||||
final GrListOrMap literal = getElement();
|
||||
@@ -30,7 +95,7 @@ public class LiteralConstructorReference extends PsiReferenceBase.Poly<GrListOrM
|
||||
if (listType instanceof GrTupleType) {
|
||||
return ((GrTupleType)listType).getComponentTypes();
|
||||
}
|
||||
else if (listType instanceof GrMapType && ((GrMapType)listType).getValueType("super") == null) {
|
||||
else if (listType instanceof GrMapType) {
|
||||
return PsiType.EMPTY_ARRAY;
|
||||
}
|
||||
return null;
|
||||
@@ -39,10 +104,17 @@ public class LiteralConstructorReference extends PsiReferenceBase.Poly<GrListOrM
|
||||
@NotNull
|
||||
@Override
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
final PsiType[] psiTypes = argTypes();
|
||||
if (psiTypes == null) return ResolveResult.EMPTY_ARRAY;
|
||||
final GrListOrMap literal = getElement();
|
||||
final GrNamedArgument superConstructor = literal.findNamedArgument("super");
|
||||
if (superConstructor != null) {
|
||||
final PsiReference reference = ObjectUtils.assertNotNull(superConstructor.getLabel()).getReference();
|
||||
if (reference instanceof PsiPolyVariantReference) {
|
||||
return ((PsiPolyVariantReference)reference).multiResolve(incompleteCode);
|
||||
}
|
||||
}
|
||||
|
||||
return PsiUtil.getConstructorCandidates(myConstructedClass, psiTypes, getElement());
|
||||
final List<ResolveResult> candidates = getConstructorCandidates(myConstructedClass, literal, argTypes());
|
||||
return candidates.toArray(new ResolveResult[candidates.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+4
-5
@@ -1,6 +1,5 @@
|
||||
package org.jetbrains.plugins.groovy.findUsages;
|
||||
|
||||
import com.intellij.psi.PsiClassType;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
@@ -23,7 +22,7 @@ public class LiteralConstructorSearcher {
|
||||
myIncludeOverloads = includeOverloads;
|
||||
}
|
||||
|
||||
public boolean processLiteral(GrListOrMap literal, PsiClassType expectedType) {
|
||||
public boolean processLiteral(GrListOrMap literal) {
|
||||
if (literal.isMap()) {
|
||||
final GrNamedArgument argument = literal.findNamedArgument("super");
|
||||
if (argument != null) {
|
||||
@@ -31,13 +30,13 @@ public class LiteralConstructorSearcher {
|
||||
}
|
||||
}
|
||||
|
||||
return processConstructorReference(new LiteralConstructorReference(literal, expectedType));
|
||||
return processConstructorReference(literal.getReference());
|
||||
}
|
||||
|
||||
private boolean processConstructorReference(@Nullable PsiReference reference) {
|
||||
if (reference != null && (myIncludeOverloads || reference.isReferenceTo(myConstructor))) {
|
||||
return myConsumer.process(reference);
|
||||
}
|
||||
return myConsumer.process(reference);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,54 +9,38 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.findUsages.LiteralConstructorReference;
|
||||
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.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrSafeCastExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
*/
|
||||
public class GppReferenceContributor extends PsiReferenceContributor {
|
||||
public static boolean mayInvokeConstructor(PsiClassType expectedType, PsiMethod constructor, GrExpression args) {
|
||||
if (args == null) {
|
||||
return true;
|
||||
@Nullable
|
||||
private static PsiType[] getSuperConstructorArguments(GrExpression superAttributeValue) {
|
||||
if (superAttributeValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiType type = args.getType();
|
||||
final PsiType type = superAttributeValue.getType();
|
||||
if (type == null) {
|
||||
return true;
|
||||
return null;
|
||||
}
|
||||
|
||||
if (type instanceof GrTupleType) {
|
||||
return isConstructorCall(expectedType, ((GrTupleType)type).getComponentTypes(), constructor, args);
|
||||
return ((GrTupleType)type).getComponentTypes();
|
||||
}
|
||||
|
||||
return isConstructorCall(expectedType, new PsiType[]{type}, constructor, args);
|
||||
}
|
||||
|
||||
public 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;
|
||||
return new PsiType[]{type};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,67 +74,38 @@ public class GppReferenceContributor extends PsiReferenceContributor {
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
final GrArgumentLabel context = getElement();
|
||||
final GrNamedArgument namedArgument = (GrNamedArgument) context.getParent();
|
||||
for (PsiType type : getTargetConversionTypes((GrExpression)namedArgument.getParent())) {
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClassType classType = (PsiClassType)type;
|
||||
final PsiClass psiClass = classType.resolve();
|
||||
if (psiClass != null) {
|
||||
final GrExpression value = namedArgument.getExpression();
|
||||
final PsiClassType classType = LiteralConstructorReference.getTargetConversionType((GrExpression)namedArgument.getParent());
|
||||
if (classType != null) {
|
||||
final PsiClass psiClass = classType.resolve();
|
||||
if (psiClass != null) {
|
||||
final GrExpression value = namedArgument.getExpression();
|
||||
|
||||
final List<ResolveResult> applicable = addMethodCandidates(classType, value);
|
||||
final List<ResolveResult> applicable = addMethodCandidates(classType, value);
|
||||
|
||||
final String memberName = getValue();
|
||||
if ("super".equals(memberName) && GppTypeConverter.hasTypedContext(myElement)) {
|
||||
applicable.addAll(addConstructorCandidates(classType, psiClass, value));
|
||||
}
|
||||
final String memberName = getValue();
|
||||
if ("super".equals(memberName) && GppTypeConverter.hasTypedContext(myElement)) {
|
||||
applicable.addAll(LiteralConstructorReference.getConstructorCandidates(classType, context, getSuperConstructorArguments(value)));
|
||||
}
|
||||
|
||||
if (value == null || applicable.isEmpty()) {
|
||||
final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, memberName, false, true);
|
||||
if (setter != null) {
|
||||
applicable.add(new PsiElementResolveResult(setter));
|
||||
} else {
|
||||
final PsiField field = PropertyUtil.findPropertyField(psiClass.getProject(), psiClass, memberName, false);
|
||||
if (field != null) {
|
||||
applicable.add(new PsiElementResolveResult(field));
|
||||
}
|
||||
if (value == null || applicable.isEmpty()) {
|
||||
final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, memberName, false, true);
|
||||
if (setter != null) {
|
||||
applicable.add(new PsiElementResolveResult(setter));
|
||||
} else {
|
||||
final PsiField field = PropertyUtil.findPropertyField(psiClass.getProject(), psiClass, memberName, false);
|
||||
if (field != null) {
|
||||
applicable.add(new PsiElementResolveResult(field));
|
||||
}
|
||||
}
|
||||
|
||||
return applicable.toArray(new ResolveResult[applicable.size()]);
|
||||
}
|
||||
|
||||
return applicable.toArray(new ResolveResult[applicable.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
return ResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private static Set<PsiType> getTargetConversionTypes(GrExpression expression) {
|
||||
//todo hack
|
||||
if (expression.getParent() instanceof GrSafeCastExpression) {
|
||||
final PsiType type = ((GrSafeCastExpression)expression.getParent()).getType();
|
||||
if (type != null) {
|
||||
return Collections.singleton(type);
|
||||
}
|
||||
}
|
||||
|
||||
return GroovyExpectedTypesProvider.getDefaultExpectedTypes(expression);
|
||||
}
|
||||
|
||||
|
||||
private static List<ResolveResult> addConstructorCandidates(PsiClassType classType, PsiClass psiClass, GrExpression value) {
|
||||
List<ResolveResult> applicable = CollectionFactory.arrayList();
|
||||
final List<ResolveResult> byName = CollectionFactory.arrayList();
|
||||
for (PsiMethod constructor : psiClass.getConstructors()) {
|
||||
final ResolveResult resolveResult = new PsiElementResolveResult(constructor);
|
||||
byName.add(resolveResult);
|
||||
if (mayInvokeConstructor(classType, constructor, value)) {
|
||||
applicable.add(resolveResult);
|
||||
}
|
||||
}
|
||||
if (applicable.isEmpty()) {
|
||||
applicable.addAll(byName);
|
||||
}
|
||||
return applicable;
|
||||
}
|
||||
|
||||
private List<ResolveResult> addMethodCandidates(PsiClassType classType, GrExpression value) {
|
||||
PsiType valueType = value == null ? null : value.getType();
|
||||
|
||||
+27
-8
@@ -21,6 +21,8 @@ import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
@@ -37,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrUnaryE
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
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.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
@@ -142,14 +145,9 @@ public class GroovyExpectedTypesProvider {
|
||||
|
||||
@Override
|
||||
public void visitOpenBlock(GrOpenBlock block) {
|
||||
if (block.getParent() instanceof PsiMethod) {
|
||||
final GrStatement[] statements = block.getStatements();
|
||||
if (statements.length > 0 && myExpression.equals(statements[statements.length - 1])) {
|
||||
final PsiType type = ((PsiMethod)block.getParent()).getReturnType();
|
||||
if (type != null) {
|
||||
myResult = new TypeConstraint[]{new SubtypeConstraint(type, type)};
|
||||
}
|
||||
}
|
||||
final GrStatement[] statements = block.getStatements();
|
||||
if (statements.length > 0 && myExpression.equals(statements[statements.length - 1])) {
|
||||
checkExitPoint();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +155,27 @@ public class GroovyExpectedTypesProvider {
|
||||
if (myExpression.equals(ifStatement.getCondition())) {
|
||||
myResult = new TypeConstraint[]{new SubtypeConstraint(TypesUtil.getJavaLangObject(ifStatement), PsiType.BOOLEAN)};
|
||||
}
|
||||
else if (myExpression.equals(ifStatement.getThenBranch()) || myExpression.equals(ifStatement.getElseBranch())) {
|
||||
checkExitPoint();
|
||||
}
|
||||
}
|
||||
|
||||
private void checkExitPoint() {
|
||||
final PsiElement element = PsiTreeUtil.getParentOfType(myExpression, PsiMethod.class, GrClosableBlock.class);
|
||||
if (element instanceof GrMethod) {
|
||||
final GrMethod method = (GrMethod)element;
|
||||
ControlFlowUtils.visitAllExitPoints(method.getBlock(), new ControlFlowUtils.ExitPointVisitor() {
|
||||
@Override
|
||||
public boolean visitExitPoint(Instruction instruction, @Nullable GrExpression returnValue) {
|
||||
if (returnValue == myExpression) {
|
||||
final PsiType returnType = method.getReturnType();
|
||||
myResult = new TypeConstraint[]{new SubtypeConstraint(returnType, returnType)};
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void visitWhileStatement(GrWhileStatement whileStatement) {
|
||||
|
||||
+11
@@ -24,6 +24,7 @@ import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.Function;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.findUsages.LiteralConstructorReference;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyElementVisitor;
|
||||
@@ -103,6 +104,16 @@ public class GrListOrMapImpl extends GrExpressionImpl implements GrListOrMap {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
final PsiClassType conversionType = LiteralConstructorReference.getTargetConversionType(this);
|
||||
if (conversionType != null) {
|
||||
return new LiteralConstructorReference(this, conversionType);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static class MyTypesCalculator implements Function<GrListOrMapImpl, PsiType> {
|
||||
@Nullable
|
||||
public PsiType fun(GrListOrMapImpl listOrMap) {
|
||||
|
||||
@@ -407,6 +407,29 @@ class Point {
|
||||
assertEquals 2, multiResolveReference().size()
|
||||
}
|
||||
|
||||
public void testGotoSuperConstructorFromLiteralOnsets() throws Exception {
|
||||
PsiClass point = myFixture.addClass("""
|
||||
class Point {
|
||||
Point() {}
|
||||
Point(int y) {}
|
||||
}""")
|
||||
|
||||
configureGppScript "Point p = <caret>[super: 2]"
|
||||
assertEquals point.constructors[1], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[2]"
|
||||
assertEquals point.constructors[1], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[]"
|
||||
assertEquals point.constructors[0], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[:]"
|
||||
assertEquals point.constructors[0], resolveReference()
|
||||
|
||||
configureGppScript "Point p = <caret>[239, 42]"
|
||||
assertEquals 2, multiResolveReference().size()
|
||||
}
|
||||
|
||||
public void testResolveTraitMethod() throws Exception {
|
||||
configureScript """
|
||||
@Trait
|
||||
|
||||
+8
-2
@@ -27,8 +27,14 @@ class LiteralConstructorUsagesTest extends LightCodeInsightFixtureTestCase {
|
||||
Foo() {}
|
||||
}
|
||||
""")
|
||||
myFixture.addFileToProject "a.groovy", "Foo foo() { if (true) [] else return [] }"
|
||||
assertEquals(2, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
myFixture.addFileToProject "a.groovy", """
|
||||
Foo foo() {
|
||||
if (true) []
|
||||
else return []
|
||||
}
|
||||
Foo bar() { [] }
|
||||
"""
|
||||
assertEquals(3, ReferencesSearch.search(foo.constructors[0]).findAll().size())
|
||||
}
|
||||
|
||||
public void testList_Cast() throws Exception {
|
||||
|
||||
+7
-1
@@ -71,7 +71,13 @@ public class FindUsagesTest extends LightGroovyTestCase {
|
||||
}
|
||||
|
||||
public void testConstructorUsageInNewExpression() throws Throwable {
|
||||
doTestImpl("ConstructorUsageInNewExpression.groovy", 2);
|
||||
myFixture.configureByFile("ConstructorUsageInNewExpression.groovy");
|
||||
final PsiElement resolved = TargetElementUtilBase.findTargetElement(myFixture.getEditor(),
|
||||
TargetElementUtilBase.getInstance().getReferenceSearchFlags());
|
||||
assertNotNull("Could not resolve reference", resolved);
|
||||
final GlobalSearchScope projectScope = GlobalSearchScope.projectScope(myFixture.getProject());
|
||||
assertEquals(2, MethodReferencesSearch.search((PsiMethod)resolved, projectScope, true).findAll().size());
|
||||
assertEquals(4, MethodReferencesSearch.search((PsiMethod)resolved, projectScope, false).findAll().size());
|
||||
}
|
||||
|
||||
public void testGotoConstructor() throws Throwable {
|
||||
|
||||
Reference in New Issue
Block a user