mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
parameter info for closures
This commit is contained in:
+1
-1
@@ -264,7 +264,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
|
||||
}
|
||||
else if (call instanceof GrCallExpression) {
|
||||
GrCallExpression constructorCall = (GrCallExpression)call;
|
||||
ContainerUtil.addAll(results, constructorCall.getMethodVariants(null));
|
||||
ContainerUtil.addAll(results, constructorCall.getCallVariants(null));
|
||||
final PsiType type = ((GrCallExpression)call).getType();
|
||||
if (type instanceof PsiClassType) {
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandler<GroovyPs
|
||||
}
|
||||
|
||||
public void showParameterInfo(@NotNull GroovyPsiElement place, CreateParameterInfoContext context) {
|
||||
GroovyResolveResult[] variants = ResolveUtil.getMethodVariants(place);
|
||||
GroovyResolveResult[] variants = ResolveUtil.getCallVariants(place);
|
||||
final List<GroovyResolveResult> namedElements = ContainerUtil.findAll(variants, new Condition<GroovyResolveResult>() {
|
||||
public boolean value(GroovyResolveResult groovyResolveResult) {
|
||||
final PsiElement element = groovyResolveResult.getElement();
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public interface GrCallExpression extends GrExpression, GrCall {
|
||||
PsiMethod resolveMethod();
|
||||
|
||||
@NotNull
|
||||
GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument);
|
||||
GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument);
|
||||
|
||||
//PsiElement addNamedArgument(GrNamedArgument argument);
|
||||
}
|
||||
|
||||
+2
-2
@@ -127,7 +127,7 @@ public class GroovyExpectedTypesProvider {
|
||||
final int closureIndex = closureArgs.indexOf(myExpression);
|
||||
if (closureIndex >= 0) {
|
||||
List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
|
||||
for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(myExpression)) {
|
||||
for (GroovyResolveResult variant : ResolveUtil.getCallVariants(myExpression)) {
|
||||
PsiParameter[] parameters = getCallParameters(variant);
|
||||
if (parameters == null || parameters.length == 0) continue;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class GroovyExpectedTypesProvider {
|
||||
int idx = list.getExpressionArgumentIndex(myExpression);
|
||||
|
||||
List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
|
||||
for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(list)) {
|
||||
for (GroovyResolveResult variant : ResolveUtil.getCallVariants(list)) {
|
||||
PsiParameter[] parameters = getCallParameters(variant);
|
||||
if (parameters == null || parameters.length <= idx) continue;
|
||||
PsiType parameterType = variant.getSubstitutor().substitute(parameters[idx].getType());
|
||||
|
||||
+1
-1
@@ -182,7 +182,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) {
|
||||
public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) {
|
||||
final GrCodeReferenceElement referenceElement = getReferenceElement();
|
||||
if (referenceElement == null) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
final GroovyResolveResult[] classResults = referenceElement.multiResolve(false);
|
||||
|
||||
+116
-97
@@ -77,6 +77,120 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
super(node);
|
||||
}
|
||||
|
||||
public GroovyResolveResult[] resolveTypeOrProperty() {
|
||||
String name = getReferenceName();
|
||||
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
EnumSet<ClassHint.ResolveKind> kinds = getParent() instanceof GrReferenceExpression
|
||||
? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE)
|
||||
: EnumSet.of(ClassHint.ResolveKind.CLASS);
|
||||
boolean hasAt = hasAt();
|
||||
GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY;
|
||||
if (!hasAt) {
|
||||
ResolverProcessor classProcessor = new ClassResolverProcessor(getReferenceName(), this, kinds);
|
||||
resolveImpl(classProcessor);
|
||||
classCandidates = classProcessor.getCandidates();
|
||||
for (GroovyResolveResult classCandidate : classCandidates) {
|
||||
final PsiElement element = classCandidate.getElement();
|
||||
if (element instanceof PsiClass && ((PsiClass)element).isEnum()) {
|
||||
return classCandidates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResolverProcessor processor = new PropertyResolverProcessor(name, this);
|
||||
resolveImpl(processor);
|
||||
final GroovyResolveResult[] fieldCandidates = processor.getCandidates();
|
||||
|
||||
if (hasAt) {
|
||||
return fieldCandidates;
|
||||
}
|
||||
|
||||
//if reference expression is in class we need to return field instead of accessor method
|
||||
for (GroovyResolveResult candidate : fieldCandidates) {
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiField) {
|
||||
final PsiClass containingClass = ((PsiField)element).getContainingClass();
|
||||
if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, this, true)) return fieldCandidates;
|
||||
} else {
|
||||
return fieldCandidates;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean isLValue = PsiUtil.isLValue(this);
|
||||
String[] names;
|
||||
names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name);
|
||||
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
|
||||
for (String getterName : names) {
|
||||
AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, this, !isLValue);
|
||||
resolveImpl(accessorResolver);
|
||||
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate
|
||||
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
|
||||
return candidates;
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addAll(accessorResults, candidates);
|
||||
}
|
||||
}
|
||||
if (fieldCandidates.length > 0) return fieldCandidates;
|
||||
if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)};
|
||||
|
||||
return classCandidates;
|
||||
}
|
||||
|
||||
public GroovyResolveResult[] resolveMethodOrProperty() {
|
||||
return resolveMethodOrProperty(false, null);
|
||||
}
|
||||
|
||||
public GroovyResolveResult[] getCallVariants(GrExpression upToArgument) {
|
||||
return resolveMethodOrProperty(true, upToArgument);
|
||||
}
|
||||
|
||||
private GroovyResolveResult[] resolveMethodOrProperty(boolean allVariants, GrExpression upToArgument) {
|
||||
String name = getReferenceName();
|
||||
if (name == null) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
final PsiType[] argTypes = PsiUtil.getArgumentTypes(this, false, upToArgument);
|
||||
MethodResolverProcessor methodResolver = runMethodResolverProcessor(argTypes, allVariants);
|
||||
assert methodResolver != null;
|
||||
if (!allVariants && methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates();
|
||||
|
||||
final String[] names = GroovyPropertyUtils.suggestGettersName(name);
|
||||
List<GroovyResolveResult> list = new ArrayList<GroovyResolveResult>();
|
||||
for (String getterName : names) {
|
||||
AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, this, true);
|
||||
resolveImpl(getterResolver);
|
||||
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
|
||||
if (!allVariants && candidates.length == 1 && candidates[0].isStaticsOK()) {
|
||||
putUserData(IS_RESOLVED_TO_GETTER, true);
|
||||
return candidates;
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addAll(list, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, this);
|
||||
resolveImpl(propertyResolver);
|
||||
if (!allVariants && propertyResolver.hasCandidates()) return propertyResolver.getCandidates();
|
||||
|
||||
if (allVariants) {
|
||||
if (list.isEmpty()) ContainerUtil.addAll(list, propertyResolver.getCandidates());
|
||||
ContainerUtil.addAll(list, methodResolver.getCandidates());
|
||||
return list.toArray(new GroovyResolveResult[list.size()]);
|
||||
}
|
||||
|
||||
if (methodResolver.hasCandidates()) {
|
||||
return methodResolver.getCandidates();
|
||||
}
|
||||
else if (list.size() > 0) {
|
||||
putUserData(IS_RESOLVED_TO_GETTER, true);
|
||||
return list.toArray(new GroovyResolveResult[list.size()]);
|
||||
}
|
||||
|
||||
return GroovyResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public void accept(GroovyElementVisitor visitor) {
|
||||
visitor.visitReferenceExpression(this);
|
||||
}
|
||||
@@ -422,108 +536,13 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
|
||||
|
||||
switch (kind) {
|
||||
case METHOD_OR_PROPERTY:
|
||||
return resolveMethodOrProperty(refExpr, name);
|
||||
return refExpr.resolveMethodOrProperty();
|
||||
case TYPE_OR_PROPERTY:
|
||||
return resolveTypeOrProperty(refExpr, name);
|
||||
return refExpr.resolveTypeOrProperty();
|
||||
default:
|
||||
return GroovyResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
private static GroovyResolveResult[] resolveTypeOrProperty(GrReferenceExpressionImpl refExpr, String name) {
|
||||
EnumSet<ClassHint.ResolveKind> kinds = refExpr.getParent() instanceof GrReferenceExpression
|
||||
? EnumSet.of(ClassHint.ResolveKind.CLASS, ClassHint.ResolveKind.PACKAGE)
|
||||
: EnumSet.of(ClassHint.ResolveKind.CLASS);
|
||||
boolean hasAt = refExpr.hasAt();
|
||||
GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY;
|
||||
if (!hasAt) {
|
||||
ResolverProcessor classProcessor = new ClassResolverProcessor(refExpr.getReferenceName(), refExpr, kinds);
|
||||
refExpr.resolveImpl(classProcessor);
|
||||
classCandidates = classProcessor.getCandidates();
|
||||
for (GroovyResolveResult classCandidate : classCandidates) {
|
||||
final PsiElement element = classCandidate.getElement();
|
||||
if (element instanceof PsiClass && ((PsiClass)element).isEnum()) {
|
||||
return classCandidates;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResolverProcessor processor = new PropertyResolverProcessor(name, refExpr);
|
||||
refExpr.resolveImpl(processor);
|
||||
final GroovyResolveResult[] fieldCandidates = processor.getCandidates();
|
||||
|
||||
if (refExpr.hasAt()) {
|
||||
return fieldCandidates;
|
||||
}
|
||||
|
||||
//if reference expression is in class we need to return field instead of accessor method
|
||||
for (GroovyResolveResult candidate : fieldCandidates) {
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiField) {
|
||||
final PsiClass containingClass = ((PsiField)element).getContainingClass();
|
||||
if (containingClass != null && PsiTreeUtil.isAncestor(containingClass, refExpr, true)) return fieldCandidates;
|
||||
} else {
|
||||
return fieldCandidates;
|
||||
}
|
||||
}
|
||||
|
||||
final boolean isLValue = PsiUtil.isLValue(refExpr);
|
||||
String[] names;
|
||||
names = isLValue ? GroovyPropertyUtils.suggestSettersName(name) : GroovyPropertyUtils.suggestGettersName(name);
|
||||
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
|
||||
for (String getterName : names) {
|
||||
AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, refExpr, !isLValue);
|
||||
refExpr.resolveImpl(accessorResolver);
|
||||
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate
|
||||
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
|
||||
return candidates;
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addAll(accessorResults, candidates);
|
||||
}
|
||||
}
|
||||
if (fieldCandidates.length > 0) return fieldCandidates;
|
||||
if (accessorResults.size() > 0) return new GroovyResolveResult[]{accessorResults.get(0)};
|
||||
|
||||
return classCandidates;
|
||||
}
|
||||
|
||||
private static GroovyResolveResult[] resolveMethodOrProperty(GrReferenceExpressionImpl refExpr, String name) {
|
||||
final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false);
|
||||
MethodResolverProcessor methodResolver = refExpr.runMethodResolverProcessor(argTypes, false);
|
||||
assert methodResolver != null;
|
||||
if (methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates();
|
||||
|
||||
final String[] names = GroovyPropertyUtils.suggestGettersName(name);
|
||||
List<GroovyResolveResult> list = new ArrayList<GroovyResolveResult>();
|
||||
for (String getterName : names) {
|
||||
AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, refExpr, true);
|
||||
refExpr.resolveImpl(getterResolver);
|
||||
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
|
||||
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
|
||||
refExpr.putUserData(IS_RESOLVED_TO_GETTER, true);
|
||||
return candidates;
|
||||
}
|
||||
else {
|
||||
ContainerUtil.addAll(list, candidates);
|
||||
}
|
||||
}
|
||||
|
||||
PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, refExpr);
|
||||
refExpr.resolveImpl(propertyResolver);
|
||||
if (propertyResolver.hasCandidates()) return propertyResolver.getCandidates();
|
||||
|
||||
if (methodResolver.hasCandidates()) {
|
||||
return methodResolver.getCandidates();
|
||||
}
|
||||
else if (list.size() > 0) {
|
||||
refExpr.putUserData(IS_RESOLVED_TO_GETTER, true);
|
||||
return list.toArray(new GroovyResolveResult[list.size()]);
|
||||
}
|
||||
|
||||
return GroovyResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void resolveImpl(ResolverProcessor processor) {
|
||||
|
||||
+2
-9
@@ -41,7 +41,6 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -187,17 +186,11 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) {
|
||||
public GroovyResolveResult[] getCallVariants(@Nullable GrExpression upToArgument) {
|
||||
final GrExpression invoked = getInvokedExpression();
|
||||
if (!(invoked instanceof GrReferenceExpressionImpl)) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
final PsiType[] partialArgs = PsiUtil.getArgumentTypes(invoked, false, upToArgument);
|
||||
final MethodResolverProcessor processor = ((GrReferenceExpressionImpl)invoked).runMethodResolverProcessor(partialArgs, true);
|
||||
if (processor != null) {
|
||||
return processor.getCandidates();
|
||||
}
|
||||
|
||||
return GroovyResolveResult.EMPTY_ARRAY;
|
||||
return ((GrReferenceExpressionImpl)invoked).getCallVariants(upToArgument);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -42,7 +42,7 @@ public class GroovyExpressionPattern<T extends GrExpression, Self extends Groovy
|
||||
public GroovyMethodCallPattern methodCall(final ElementPattern<? extends PsiMethod> method) {
|
||||
return new GroovyMethodCallPattern().and(this).with(new PatternCondition<GrCallExpression>("methodCall") {
|
||||
public boolean accepts(@NotNull GrCallExpression callExpression, ProcessingContext context) {
|
||||
final GroovyResolveResult[] results = callExpression.getMethodVariants(null);
|
||||
final GroovyResolveResult[] results = callExpression.getCallVariants(null);
|
||||
for (GroovyResolveResult result : results) {
|
||||
if (method.getCondition().accepts(result.getElement(), context)) {
|
||||
return true;
|
||||
|
||||
@@ -632,7 +632,7 @@ public class PsiUtil {
|
||||
}
|
||||
|
||||
public static boolean isRawMethodCall(GrMethodCallExpression call) {
|
||||
final GroovyResolveResult[] resolveResults = call.getMethodVariants(null);
|
||||
final GroovyResolveResult[] resolveResults = call.getCallVariants(null);
|
||||
if (resolveResults.length == 0) return false;
|
||||
final PsiElement element = resolveResults[0].getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
|
||||
@@ -439,11 +439,11 @@ public class ResolveUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static GroovyResolveResult[] getMethodVariants(GroovyPsiElement place) {
|
||||
public static GroovyResolveResult[] getCallVariants(GroovyPsiElement place) {
|
||||
final PsiElement parent = place.getParent();
|
||||
GroovyResolveResult[] variants = GroovyResolveResult.EMPTY_ARRAY;
|
||||
if (parent instanceof GrCallExpression) {
|
||||
variants = ((GrCallExpression) parent).getMethodVariants(place instanceof GrExpression ? (GrExpression)place : null);
|
||||
variants = ((GrCallExpression) parent).getCallVariants(place instanceof GrExpression ? (GrExpression)place : null);
|
||||
} else if (parent instanceof GrConstructorInvocation) {
|
||||
final PsiClass clazz = ((GrConstructorInvocation) parent).getDelegatedClass();
|
||||
if (clazz != null) {
|
||||
|
||||
Reference in New Issue
Block a user