mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-68175 multi-signature closure types
This commit is contained in:
@@ -103,9 +103,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrVariableDeclarationOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.TypeInferenceHelper;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.auxiliary.annotation.GrAnnotationImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
+1
-1
@@ -54,8 +54,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyConstantExpressionEvaluator;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlo
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesProvider;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.AbstractClosureParameterEnhancer;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.GroovyExpectedTypesPr
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SubtypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrTupleType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -9,12 +9,12 @@ import org.jetbrains.plugins.groovy.findUsages.LiteralConstructorReference;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrTypeConverter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
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.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -85,7 +85,7 @@ public class GppTypeConverter extends GrTypeConverter {
|
||||
}
|
||||
|
||||
public static boolean isClosureOverride(PsiType[] methodParameters, GrClosureType closureType, GroovyPsiElement context) {
|
||||
final GrClosureSignature signature = closureType.getSignature();
|
||||
final GrSignature signature = closureType.getSignature();
|
||||
if (methodParameters != null && GrClosureSignatureUtil.isSignatureApplicable(signature, methodParameters, context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
+4
-4
@@ -39,6 +39,7 @@ import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentLabel;
|
||||
@@ -47,9 +48,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
@@ -123,8 +123,8 @@ public class ConvertClosureToMethodIntention extends Intention {
|
||||
LOG.assertTrue(initializer != null);
|
||||
final PsiType type = initializer.getType();
|
||||
LOG.assertTrue(type instanceof GrClosureType);
|
||||
final GrClosureSignature signature = ((GrClosureType)type).getSignature();
|
||||
final List<MethodSignature> signatures = GrClosureSignatureUtil.generateAllMethodSignaturesByClosureSignature(fieldName, signature);
|
||||
final GrSignature signature = ((GrClosureType)type).getSignature();
|
||||
final List<MethodSignature> signatures = GrClosureSignatureUtil.generateAllMethodSignaturesBySignature(fieldName, signature);
|
||||
for (MethodSignature s : signatures) {
|
||||
final PsiMethod method = MethodSignatureUtil.findMethodBySignature(containingClass, s, true);
|
||||
if (method != null) {
|
||||
|
||||
+1
-1
@@ -58,8 +58,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.PsiUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+2
-2
@@ -47,6 +47,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GrNamedElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
@@ -60,10 +61,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrMapType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.members.GrMethodImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyValidationUtil;
|
||||
|
||||
|
||||
+71
-73
@@ -20,13 +20,11 @@ import com.intellij.codeInsight.completion.JavaCompletionUtil;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.lang.parameterInfo.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.hash.HashSet;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -35,6 +33,8 @@ import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
@@ -42,7 +42,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
@@ -131,32 +130,25 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void showParameterInfo(@NotNull GroovyPsiElement place, CreateParameterInfoContext context) {
|
||||
public void showParameterInfo(@NotNull GroovyPsiElement place, @NotNull CreateParameterInfoContext context) {
|
||||
GroovyResolveResult[] variants = ResolveUtil.getCallVariants(place);
|
||||
|
||||
final List elementToShow = new ArrayList();
|
||||
final PsiElement parent = place.getParent();
|
||||
if (parent instanceof GrMethodCall) {
|
||||
final Condition<GroovyResolveResult> methodsOrClosures = new Condition<GroovyResolveResult>() {
|
||||
public boolean value(GroovyResolveResult result) {
|
||||
final PsiElement element = result.getElement();
|
||||
return element instanceof PsiMethod && !result.isInvokedOnProperty() ||
|
||||
element instanceof GrVariable && ((GrVariable)element).getTypeGroovy() instanceof GrClosureType;
|
||||
}
|
||||
};
|
||||
final GrExpression invoked = ((GrMethodCall)parent).getInvokedExpression();
|
||||
if (isPropertyOrVariableInvoked(invoked)) {
|
||||
final PsiType type = invoked.getType();
|
||||
if (type instanceof GrClosureType) {
|
||||
elementToShow.add(type);
|
||||
addSignatureVariant(elementToShow, (GrClosureType)type);
|
||||
}
|
||||
else if (type != null) {
|
||||
final GroovyResolveResult[] calls = ResolveUtil.getMethodCandidates(type, "call", place, PsiUtil.getArgumentTypes(place, true));
|
||||
elementToShow.addAll(ContainerUtil.findAll(calls, methodsOrClosures));
|
||||
addMethodAndClosureVariants(elementToShow,
|
||||
ResolveUtil.getMethodCandidates(type, "call", place, PsiUtil.getArgumentTypes(place, true)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
elementToShow.addAll(ContainerUtil.findAll(variants, methodsOrClosures));
|
||||
addMethodAndClosureVariants(elementToShow, variants);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -168,6 +160,30 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
context.showHint(place, place.getTextRange().getStartOffset(), this);
|
||||
}
|
||||
|
||||
private static void addMethodAndClosureVariants(@NotNull List<Object> elementToShow, @NotNull GroovyResolveResult[] variants) {
|
||||
for (GroovyResolveResult variant : variants) {
|
||||
final PsiElement element = variant.getElement();
|
||||
if (element instanceof PsiMethod) {
|
||||
elementToShow.add(variant);
|
||||
}
|
||||
else if (element instanceof GrVariable) {
|
||||
final PsiType type = ((GrVariable)element).getTypeGroovy();
|
||||
if (type instanceof GrClosureType) {
|
||||
addSignatureVariant(elementToShow, (GrClosureType)type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void addSignatureVariant(@NotNull final List<Object> elementToShow, @NotNull GrClosureType type) {
|
||||
type.getSignature().accept(new GrRecursiveSignatureVisitor() {
|
||||
@Override
|
||||
public void visitClosureSignature(GrClosureSignature signature) {
|
||||
elementToShow.add(signature);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void filterOutReflectedMethods(List toShow) {
|
||||
Set<GrMethod> methods = new HashSet<GrMethod>();
|
||||
|
||||
@@ -230,25 +246,21 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
}
|
||||
argTypes = PsiUtil.getArgumentTypes(place, false);
|
||||
}
|
||||
else if (namedElement instanceof GrVariable) {
|
||||
final PsiType type = ((GrVariable)namedElement).getTypeGroovy();
|
||||
if (type instanceof GrClosureType) {
|
||||
argTypes = PsiUtil.getArgumentTypes(place, false);
|
||||
parameterTypes = ((GrClosureType)type).getClosureParameterTypes();
|
||||
}
|
||||
}
|
||||
if (argTypes == null) continue;
|
||||
}
|
||||
else if (objects[i] instanceof GrClosureType) {
|
||||
final GrClosureType type = (GrClosureType)objects[i];
|
||||
else if (objects[i] instanceof GrClosureSignature) {
|
||||
final GrClosureSignature signature = (GrClosureSignature)objects[i];
|
||||
argTypes = PsiUtil.getArgumentTypes(place, false);
|
||||
parameterTypes = type.getClosureParameterTypes();
|
||||
parameterTypes = new PsiType[signature.getParameterCount()];
|
||||
int j = 0;
|
||||
for (GrClosureParameter parameter : signature.getParameters()) {
|
||||
parameterTypes[j++] = parameter.getType();
|
||||
}
|
||||
}
|
||||
else {
|
||||
continue Outer;
|
||||
}
|
||||
|
||||
assert parameterTypes != null;
|
||||
assert argTypes != null;
|
||||
|
||||
if (parameterTypes.length <= currIndex) {
|
||||
@@ -360,8 +372,8 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (o instanceof GrClosureType) {
|
||||
if (!((GrClosureType)o).isValid()) {
|
||||
else if (o instanceof GrClosureSignature) {
|
||||
if (!((GrClosureSignature)o).isValid()) {
|
||||
context.setUIComponentEnabled(false);
|
||||
return;
|
||||
}
|
||||
@@ -374,6 +386,8 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
int highlightStartOffset = -1;
|
||||
int highlightEndOffset = -1;
|
||||
|
||||
final int currentParameter = context.getCurrentParameterIndex();
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
|
||||
|
||||
@@ -393,8 +407,6 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
buffer.append('(');
|
||||
}
|
||||
|
||||
final int currentParameter = context.getCurrentParameterIndex();
|
||||
|
||||
final PsiParameter[] params = method.getParameterList().getParameters();
|
||||
|
||||
int numParams = params.length;
|
||||
@@ -415,10 +427,7 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
}
|
||||
|
||||
if (context.isUIComponentEnabled() &&
|
||||
(j == currentParameter ||
|
||||
(j == numParams - 1 && param.isVarArgs() && currentParameter >= numParams)
|
||||
)
|
||||
) {
|
||||
(j == currentParameter || (j == numParams - 1 && param.isVarArgs() && currentParameter >= numParams))) {
|
||||
highlightStartOffset = startOffset;
|
||||
highlightEndOffset = endOffset;
|
||||
}
|
||||
@@ -434,23 +443,37 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
} else if (element instanceof PsiClass) {
|
||||
buffer.append("no parameters");
|
||||
}
|
||||
else if (element instanceof GrVariable) {
|
||||
final PsiElement parent = context.getParameterOwner().getParent();
|
||||
if (parent == null || !parent.isValid()) {
|
||||
context.setUIComponentEnabled(false);
|
||||
return;
|
||||
}
|
||||
final PsiType type;
|
||||
if (parent instanceof GrMethodCallExpression) {
|
||||
type = ((GrMethodCallExpression)parent).getInvokedExpression().getType();
|
||||
else if (element instanceof GrClosureSignature) {
|
||||
GrClosureParameter[] parameters = ((GrClosureSignature)element).getParameters();
|
||||
if (parameters.length > 0) {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (i > 0) buffer.append(", ");
|
||||
|
||||
int startOffset = buffer.length();
|
||||
final PsiType psiType = parameters[i].getType();
|
||||
if (psiType == null) {
|
||||
buffer.append("def");
|
||||
}
|
||||
else {
|
||||
buffer.append(psiType.getPresentableText());
|
||||
}
|
||||
int endOffset = buffer.length();
|
||||
|
||||
if (context.isUIComponentEnabled() &&
|
||||
(i == currentParameter || (i == parameters.length - 1 && ((GrClosureSignature)element).isVarargs() && currentParameter >= parameters.length))) {
|
||||
highlightStartOffset = startOffset;
|
||||
highlightEndOffset = endOffset;
|
||||
}
|
||||
|
||||
final GrExpression initializer = parameters[i].getDefaultInitializer();
|
||||
if (initializer != null) {
|
||||
buffer.append(" = ").append(initializer.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
type = ((GrVariable)element).getTypeGroovy();
|
||||
buffer.append("no parameters");
|
||||
}
|
||||
generateForClosureType(buffer, type);
|
||||
}
|
||||
else if (element instanceof GrClosureType) {
|
||||
generateForClosureType(buffer, (GrClosureType)element);
|
||||
}
|
||||
|
||||
final boolean isDeprecated = o instanceof PsiDocCommentOwner && ((PsiDocCommentOwner) o).isDeprecated();
|
||||
@@ -466,31 +489,6 @@ public class GroovyParameterInfoHandler implements ParameterInfoHandlerWithTabAc
|
||||
);
|
||||
}
|
||||
|
||||
private static void generateForClosureType(StringBuilder buffer, PsiType type) {
|
||||
if (type instanceof GrClosureType) {
|
||||
GrClosureParameter[] parameters = ((GrClosureType)type).getSignature().getParameters();
|
||||
if (parameters.length > 0) {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
if (i > 0) buffer.append(", ");
|
||||
final PsiType psiType = parameters[i].getType();
|
||||
if (psiType == null) {
|
||||
buffer.append("def");
|
||||
}
|
||||
else {
|
||||
buffer.append(psiType.getPresentableText());
|
||||
}
|
||||
final GrExpression initializer = parameters[i].getDefaultInitializer();
|
||||
if (initializer != null) {
|
||||
buffer.append(" = ").append(initializer.getText());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer.append("no parameters");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendParameterText(PsiParameter param, PsiSubstitutor substitutor, StringBuilder buffer) {
|
||||
if (param instanceof GrParameter) {
|
||||
GrParameter grParam = (GrParameter)param;
|
||||
|
||||
+1
-1
@@ -29,6 +29,7 @@ import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocReferenceElement
|
||||
import org.jetbrains.plugins.groovy.lang.groovydoc.psi.api.GrDocTag;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
@@ -45,7 +46,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEn
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
|
||||
|
||||
+6
-5
@@ -13,17 +13,19 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.types;
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.signatures;
|
||||
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
public interface GrClosureSignature {
|
||||
public interface GrClosureSignature extends GrSignature {
|
||||
|
||||
@NotNull PsiSubstitutor getSubstitutor();
|
||||
|
||||
@NotNull
|
||||
@@ -36,8 +38,7 @@ public interface GrClosureSignature {
|
||||
@Nullable
|
||||
PsiType getReturnType();
|
||||
|
||||
@Nullable
|
||||
GrCurriedClosureSignature curry(PsiType[] args, int position);
|
||||
GrClosureSignature[] EMPTY_ARRAY = new GrClosureSignature[0];
|
||||
|
||||
boolean isValid();
|
||||
boolean isCurried();
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.signatures;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public interface GrMultiSignature extends GrSignature {
|
||||
GrClosureSignature[] getAllSignatures();
|
||||
|
||||
GrMultiSignature EMPTY_SIGNATURE = new GrMultiSignature() {
|
||||
@Override
|
||||
public GrClosureSignature[] getAllSignatures() {
|
||||
return GrClosureSignature.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GrSignatureVisitor visitor) {
|
||||
visitor.visitMultiSignature(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
+11
-16
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,23 +13,18 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.types;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.signatures;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public interface GrCurriedClosureSignature extends GrClosureSignature{
|
||||
|
||||
PsiType[] getCurriedArgs();
|
||||
|
||||
/**
|
||||
*
|
||||
* @return position or -1 if position is right
|
||||
*/
|
||||
int getCurriedPosition();
|
||||
|
||||
GrClosureSignature getOriginalSignature();
|
||||
public abstract class GrRecursiveSignatureVisitor extends GrSignatureVisitor {
|
||||
@Override
|
||||
public void visitMultiSignature(GrMultiSignature signature) {
|
||||
super.visitMultiSignature(signature);
|
||||
|
||||
for (GrClosureSignature s : signature.getAllSignatures()) {
|
||||
s.accept(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.signatures;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public interface GrSignature {
|
||||
boolean isValid();
|
||||
|
||||
@Nullable
|
||||
GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context);
|
||||
|
||||
void accept(GrSignatureVisitor visitor);
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.api.signatures;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public abstract class GrSignatureVisitor {
|
||||
public void visitClosureSignature(GrClosureSignature signature){
|
||||
visitSignature(signature);
|
||||
}
|
||||
|
||||
public void visitSignature(GrSignature signature){}
|
||||
|
||||
public void visitMultiSignature(GrMultiSignature signature){
|
||||
visitSignature(signature);
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -22,18 +22,18 @@ import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.MixinTypeInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil.createSignature;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil.createSignature;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
|
||||
+1
-1
@@ -42,8 +42,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
|
||||
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.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
@@ -23,24 +23,29 @@ import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GroovyCommonClassNames;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ven
|
||||
*/
|
||||
public class GrClosureType extends GrLiteralClassType {
|
||||
private final @NotNull GrClosureSignature mySignature;
|
||||
private final @NotNull GrSignature mySignature;
|
||||
private PsiType[] myTypeArgs = null;
|
||||
|
||||
private GrClosureType(LanguageLevel languageLevel,
|
||||
GlobalSearchScope scope,
|
||||
JavaPsiFacade facade,
|
||||
@NotNull GrClosureSignature closureSignature,
|
||||
@NotNull GrSignature closureSignature,
|
||||
boolean shouldInferTypeParameters) {
|
||||
super(languageLevel, scope, facade);
|
||||
mySignature = closureSignature;
|
||||
@@ -67,7 +72,8 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
if (myTypeArgs == null) {
|
||||
final PsiClass psiClass = resolve();
|
||||
if (psiClass != null && psiClass.getTypeParameters().length == 1) {
|
||||
myTypeArgs = new PsiType[]{TypesUtil.boxPrimitiveType(mySignature.getReturnType(), getPsiManager(), getResolveScope(), true)};
|
||||
final PsiType type = GrClosureSignatureUtil.getReturnType(mySignature);
|
||||
myTypeArgs = new PsiType[]{TypesUtil.boxPrimitiveType(type, getPsiManager(), getResolveScope(), true)};
|
||||
}
|
||||
else {
|
||||
myTypeArgs = PsiType.EMPTY_ARRAY;
|
||||
@@ -76,6 +82,8 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
return myTypeArgs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected String getJavaClassName() {
|
||||
@@ -108,7 +116,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public boolean isAssignableFrom(@NotNull PsiType type) {
|
||||
/*public boolean isAssignableFrom(@NotNull PsiType type) {
|
||||
if (type instanceof GrClosureType) {
|
||||
GrClosureType other = (GrClosureType)type;
|
||||
GrClosureSignature otherSignature = other.mySignature;
|
||||
@@ -137,7 +145,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
return true;
|
||||
}
|
||||
return super.isAssignableFrom(type);
|
||||
}
|
||||
}*/
|
||||
|
||||
public boolean equalsToText(@NonNls String text) {
|
||||
return text.equals(GroovyCommonClassNames.GROOVY_LANG_CLOSURE);
|
||||
@@ -150,6 +158,25 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static GrClosureType create(GroovyResolveResult[] results, GroovyPsiElement context) {
|
||||
List<GrClosureSignature> signatures = new ArrayList<GrClosureSignature>();
|
||||
for (GroovyResolveResult result : results) {
|
||||
if (result.getElement() instanceof PsiMethod) {
|
||||
signatures.add(GrClosureSignatureUtil.createSignature((PsiMethod)result.getElement(), result.getSubstitutor()));
|
||||
}
|
||||
}
|
||||
|
||||
final GlobalSearchScope resolveScope = context.getResolveScope();
|
||||
final JavaPsiFacade facade = JavaPsiFacade.getInstance(context.getProject());
|
||||
if (signatures.size() == 1) {
|
||||
return create(signatures.get(0), resolveScope, facade, LanguageLevel.JDK_1_5, true);
|
||||
}
|
||||
else {
|
||||
return create(GrClosureSignatureUtil.createMultiSignature(signatures.toArray(new GrClosureSignature[signatures.size()])),
|
||||
resolveScope, facade, LanguageLevel.JDK_1_5, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static GrClosureType create(@NotNull GrClosableBlock closure, boolean shouldInferTypeParameters) {
|
||||
final GrClosureSignature signature = GrClosureSignatureUtil.createSignature(closure);
|
||||
final GlobalSearchScope resolveScope = closure.getResolveScope();
|
||||
@@ -172,7 +199,7 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
return create(GrClosureSignatureUtil.createSignature(parameters, returnType), scope, facade, languageLevel, true);
|
||||
}
|
||||
|
||||
public static GrClosureType create(@NotNull GrClosureSignature signature,
|
||||
public static GrClosureType create(@NotNull GrSignature signature,
|
||||
GlobalSearchScope scope,
|
||||
JavaPsiFacade facade,
|
||||
LanguageLevel languageLevel,
|
||||
@@ -181,8 +208,8 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiType curry(PsiType[] args, int position) {
|
||||
final GrClosureSignature newSignature = mySignature.curry(args, position);
|
||||
public PsiType curry(PsiType[] args, int position, GroovyPsiElement context) {
|
||||
final GrSignature newSignature = mySignature.curry(args, position, context);
|
||||
if (newSignature == null) return null;
|
||||
final GrClosureType result = create(newSignature, myScope, myFacade, myLanguageLevel, true);
|
||||
result.myTypeArgs = this.myTypeArgs;
|
||||
@@ -190,16 +217,16 @@ public class GrClosureType extends GrLiteralClassType {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public GrClosureSignature getSignature() {
|
||||
public GrSignature getSignature() {
|
||||
return mySignature;
|
||||
}
|
||||
|
||||
public PsiType[] getClosureParameterTypes() {
|
||||
/*public PsiType[] getClosureParameterTypes() {
|
||||
final GrClosureParameter[] parameters = mySignature.getParameters();
|
||||
final PsiType[] types = new PsiType[parameters.length];
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
types[i] = parameters[i].getType();
|
||||
}
|
||||
return types;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
+5
-1
@@ -40,6 +40,7 @@ import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrLabel;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
@@ -55,7 +56,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMe
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.GrTopStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClassTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
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.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GrStringUtil;
|
||||
|
||||
|
||||
+62
-8
@@ -13,22 +13,30 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.types;
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.signatures;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.psi.*;
|
||||
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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignatureVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureParameterImpl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
public class GrClosureSignatureImpl implements GrClosureSignature {
|
||||
private final boolean myIsVarargs;
|
||||
private final boolean myCurried;
|
||||
@Nullable private final PsiType myReturnType;
|
||||
@NotNull private final GrClosureParameter[] myParameters;
|
||||
@NotNull private final PsiSubstitutor mySubstitutor;
|
||||
@@ -47,20 +55,21 @@ public class GrClosureSignatureImpl implements GrClosureSignature {
|
||||
myIsVarargs = false;
|
||||
}
|
||||
mySubstitutor = substitutor;
|
||||
myCurried = false;
|
||||
}
|
||||
|
||||
public GrClosureSignatureImpl(PsiParameter[] parameters, @Nullable PsiType returnType) {
|
||||
this(parameters, returnType, PsiSubstitutor.EMPTY);
|
||||
}
|
||||
|
||||
GrClosureSignatureImpl(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs) {
|
||||
GrClosureSignatureImpl(@NotNull GrClosureParameter[] params, @Nullable PsiType returnType, boolean isVarArgs, boolean isCurried) {
|
||||
myParameters = params;
|
||||
myReturnType = returnType;
|
||||
myIsVarargs = isVarArgs;
|
||||
myCurried = isCurried;
|
||||
mySubstitutor = PsiSubstitutor.EMPTY;
|
||||
}
|
||||
|
||||
|
||||
public boolean isVarargs() {
|
||||
return myIsVarargs;
|
||||
}
|
||||
@@ -89,8 +98,44 @@ public class GrClosureSignatureImpl implements GrClosureSignature {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public GrCurriedClosureSignature curry(PsiType[] args, int position) {
|
||||
return new GrCurriedClosureSignatureImpl(this, args, position);
|
||||
public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) {
|
||||
GrClosureParameter[] params = myParameters;
|
||||
|
||||
List<GrClosureParameter> newParams = new ArrayList<GrClosureParameter>(params.length);
|
||||
List<GrClosureParameter> opts = new ArrayList<GrClosureParameter>(params.length);
|
||||
List<Integer> optInds = new ArrayList<Integer>(params.length);
|
||||
|
||||
if (position == -1) {
|
||||
position = params.length - args.length;
|
||||
}
|
||||
|
||||
if (position < 0 || position >= params.length) return GrMultiSignature.EMPTY_SIGNATURE;
|
||||
|
||||
for (int i = 0; i < params.length; i++) {
|
||||
if (params[i].isOptional()) {
|
||||
opts.add(params[i]);
|
||||
optInds.add(i);
|
||||
}
|
||||
else {
|
||||
newParams.add(params[i]);
|
||||
}
|
||||
}
|
||||
|
||||
final PsiType rtype = getReturnType();
|
||||
final ArrayList<GrClosureSignature> result = new ArrayList<GrClosureSignature>();
|
||||
GrClosureSignatureUtil.checkAndAddSignature(result, args, position, newParams, rtype, context);
|
||||
|
||||
for (int i = 0; i < opts.size(); i++) {
|
||||
newParams.add(optInds.get(i), opts.get(i));
|
||||
GrClosureSignatureUtil.checkAndAddSignature(result, args, position, newParams, rtype, context);
|
||||
}
|
||||
|
||||
if (result.size() == 1) {
|
||||
return result.get(0);
|
||||
}
|
||||
else {
|
||||
return new GrMultiSignatureImpl(result.toArray(new GrClosureSignature[result.size()]));
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isValid() {
|
||||
@@ -110,6 +155,10 @@ public class GrClosureSignatureImpl implements GrClosureSignature {
|
||||
return super.equals(obj);
|
||||
}
|
||||
|
||||
public boolean isCurried() {
|
||||
return myCurried;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GrClosureSignature getLeastUpperBound(@NotNull GrClosureSignature signature1,
|
||||
@NotNull GrClosureSignature signature2,
|
||||
@@ -131,10 +180,15 @@ public class GrClosureSignatureImpl implements GrClosureSignature {
|
||||
returnType = TypesUtil.getLeastUpperBound(s1type, s2type, manager);
|
||||
}
|
||||
boolean isVarArgs = signature1.isVarargs() && signature2.isVarargs();
|
||||
return new GrClosureSignatureImpl(params, returnType, isVarArgs);
|
||||
return new GrClosureSignatureImpl(params, returnType, isVarArgs, false);
|
||||
}
|
||||
return null; //todo
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GrSignatureVisitor visitor) {
|
||||
visitor.visitClosureSignature(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+218
-84
@@ -13,9 +13,10 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.types;
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.signatures;
|
||||
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
@@ -30,6 +31,10 @@ 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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
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.GrCall;
|
||||
@@ -39,12 +44,11 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExp
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
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.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureParameterImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
import java.util.*;
|
||||
@@ -57,13 +61,24 @@ public class GrClosureSignatureUtil {
|
||||
private GrClosureSignatureUtil() {
|
||||
}
|
||||
|
||||
public static GrMultiSignature createMultiSignature(GrClosureSignature[] signatures) {
|
||||
return new GrMultiSignatureImpl(signatures);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static GrClosureSignature createSignature(GrCall call) {
|
||||
if (call instanceof GrMethodCall) {
|
||||
final GrExpression invokedExpression = ((GrMethodCall)call).getInvokedExpression();
|
||||
final PsiType type = invokedExpression.getType();
|
||||
if (type instanceof GrClosureType) return ((GrClosureType)type).getSignature();
|
||||
if (type instanceof GrClosureType) {
|
||||
final GrSignature signature = ((GrClosureType)type).getSignature();
|
||||
final Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult> trinity =
|
||||
getApplicableSignature(signature, PsiUtil.getArgumentTypes(invokedExpression, true), call);
|
||||
if (trinity != null) {
|
||||
return trinity.first;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final GroovyResolveResult resolveResult = call.advancedResolve();
|
||||
@@ -105,7 +120,7 @@ public class GrClosureSignatureUtil {
|
||||
|
||||
public static GrClosureSignature removeParam(final GrClosureSignature signature, int i) {
|
||||
final GrClosureParameter[] newParams = ArrayUtil.remove(signature.getParameters(), i);
|
||||
return new GrClosureSignatureImpl(newParams, null, newParams.length > 0 && signature.isVarargs()) {
|
||||
return new GrClosureSignatureImpl(newParams, null, newParams.length > 0 && signature.isVarargs(), false) {
|
||||
@Override
|
||||
public PsiType getReturnType() {
|
||||
return signature.getReturnType();
|
||||
@@ -127,7 +142,7 @@ public class GrClosureSignatureUtil {
|
||||
closureParams[i] = new GrClosureParameterImpl(type, GrClosureParameterImpl.isParameterOptional(param),
|
||||
GrClosureParameterImpl.getDefaultInitializer(param));
|
||||
}
|
||||
return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams)) {
|
||||
return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams), false) {
|
||||
@Override
|
||||
public PsiType getReturnType() {
|
||||
return PsiUtil.getSmartReturnType(method);
|
||||
@@ -149,7 +164,7 @@ public class GrClosureSignatureUtil {
|
||||
closureParams[i] = new GrClosureParameterImpl(type, GrClosureParameterImpl.isParameterOptional(param),
|
||||
GrClosureParameterImpl.getDefaultInitializer(param));
|
||||
}
|
||||
return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams)) {
|
||||
return new GrClosureSignatureImpl(closureParams, null, GrClosureParameterImpl.isVararg(closureParams), false) {
|
||||
@Override
|
||||
public PsiType getReturnType() {
|
||||
return closure.getReturnType();
|
||||
@@ -167,26 +182,131 @@ public class GrClosureSignatureUtil {
|
||||
return new GrClosureSignatureImpl(parameters, returnType);
|
||||
}
|
||||
|
||||
public static boolean isSignatureApplicable(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
|
||||
@Nullable
|
||||
public static PsiType getReturnType(@NotNull final GrSignature signature, @NotNull GrMethodCall expr) {
|
||||
return getReturnType(signature, PsiUtil.getArgumentTypes(expr.getInvokedExpression(), true), expr);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType getReturnType(@NotNull final GrSignature signature, @Nullable PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
if (signature instanceof GrClosureSignature) return ((GrClosureSignature)signature).getReturnType();
|
||||
|
||||
if (args == null) {
|
||||
return TypesUtil.getLeastUpperBoundNullable(new Iterable<PsiType>() {
|
||||
|
||||
@Override
|
||||
public Iterator<PsiType> iterator() {
|
||||
return new Iterator<PsiType>() {
|
||||
private final Iterator<GrClosureSignature> it = Arrays.asList(((GrMultiSignature)signature).getAllSignatures()).iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType next() {
|
||||
return it.next().getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}, context.getManager());
|
||||
}
|
||||
|
||||
final List<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> results =
|
||||
getSignatureApplicabilities(signature, args, context);
|
||||
|
||||
if (results.size() == 1) return results.get(0).first.getReturnType();
|
||||
|
||||
return TypesUtil.getLeastUpperBoundNullable(new Iterable<PsiType>() {
|
||||
@Override
|
||||
public Iterator<PsiType> iterator() {
|
||||
return new Iterator<PsiType>() {
|
||||
private final Iterator<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> myIterator = results.iterator();
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return myIterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType next() {
|
||||
return myIterator.next().first.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
}, context.getManager());
|
||||
}
|
||||
|
||||
public static boolean isSignatureApplicable(@NotNull GrSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
return isSignatureApplicableConcrete(signature, args, context) != ApplicabilityResult.inapplicable;
|
||||
}
|
||||
|
||||
public static ApplicabilityResult isSignatureApplicableConcrete(@NotNull GrClosureSignature signature, @NotNull PsiType[] args, @NotNull GroovyPsiElement context) {
|
||||
ArgInfo<PsiType>[] map = mapArgTypesToParameters(signature, args, context, false);
|
||||
if (map != null) return isSignatureApplicableInner(map, signature);
|
||||
public static ApplicabilityResult isSignatureApplicableConcrete(@NotNull GrSignature signature, @NotNull final PsiType[] args, @NotNull final GroovyPsiElement context) {
|
||||
final List<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> results =
|
||||
getSignatureApplicabilities(signature, args, context);
|
||||
|
||||
// check for the case foo([1, 2, 3]) if foo(int, int, int)
|
||||
if (args.length == 1 && PsiUtil.isInMethodCallContext(context)) {
|
||||
final GrClosureParameter[] parameters = signature.getParameters();
|
||||
if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) return ApplicabilityResult.inapplicable;
|
||||
PsiType arg = args[0];
|
||||
if (arg instanceof GrTupleType) {
|
||||
args = ((GrTupleType)arg).getComponentTypes();
|
||||
map = mapArgTypesToParameters(signature, args, context, false);
|
||||
if (map != null) return isSignatureApplicableInner(map, signature);
|
||||
if (results.isEmpty()) return ApplicabilityResult.inapplicable;
|
||||
else if (results.size()==1) return results.get(0).third;
|
||||
else return ApplicabilityResult.ambiguous;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult> getApplicableSignature(@NotNull GrSignature signature,
|
||||
@Nullable final PsiType[] args,
|
||||
@NotNull final GroovyPsiElement context) {
|
||||
if (args == null) return null;
|
||||
final List<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> results = getSignatureApplicabilities(signature, args, context);
|
||||
|
||||
if (results.size() == 1) return results.get(0);
|
||||
else return null;
|
||||
}
|
||||
|
||||
private static List<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> getSignatureApplicabilities(@NotNull GrSignature signature,
|
||||
@NotNull final PsiType[] args,
|
||||
@NotNull final GroovyPsiElement context) {
|
||||
final List<Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>> results =
|
||||
new ArrayList<Trinity<GrClosureSignature, GrClosureSignatureUtil.ArgInfo<PsiType>[], ApplicabilityResult>>();
|
||||
signature.accept(new GrRecursiveSignatureVisitor() {
|
||||
@Override
|
||||
public void visitClosureSignature(GrClosureSignature signature) {
|
||||
ArgInfo<PsiType>[] map = mapArgTypesToParameters(signature, args, context, false);
|
||||
if (map != null) {
|
||||
results.add(new Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>(signature, map, isSignatureApplicableInner(map, signature)));
|
||||
return;
|
||||
}
|
||||
|
||||
// check for the case foo([1, 2, 3]) if foo(int, int, int)
|
||||
if (args.length == 1 && PsiUtil.isInMethodCallContext(context)) {
|
||||
final GrClosureParameter[] parameters = signature.getParameters();
|
||||
if (parameters.length == 1 && parameters[0].getType() instanceof PsiArrayType) {
|
||||
return;
|
||||
}
|
||||
PsiType arg = args[0];
|
||||
if (arg instanceof GrTupleType) {
|
||||
PsiType[] _args = ((GrTupleType)arg).getComponentTypes();
|
||||
map = mapArgTypesToParameters(signature, _args, context, false);
|
||||
if (map != null) {
|
||||
results.add(new Trinity<GrClosureSignature, ArgInfo<PsiType>[], ApplicabilityResult>(signature, map,
|
||||
isSignatureApplicableInner(map,
|
||||
signature)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ApplicabilityResult.inapplicable;
|
||||
});
|
||||
return results;
|
||||
}
|
||||
|
||||
private static ApplicabilityResult isSignatureApplicableInner(@NotNull ArgInfo<PsiType>[] infos, @NotNull GrClosureSignature signature) {
|
||||
@@ -206,10 +326,10 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
|
||||
public enum ApplicabilityResult {
|
||||
applicable, inapplicable, canBeApplicable;
|
||||
applicable, inapplicable, canBeApplicable, ambiguous;
|
||||
|
||||
public static boolean isApplicable(ApplicabilityResult r) {
|
||||
return r != inapplicable;
|
||||
return r != inapplicable && r!= ambiguous;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,61 +360,12 @@ public class GrClosureSignatureUtil {
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <Arg> ArgWrapper<Arg>[] getActualArgs(@NotNull GrCurriedClosureSignature signature,
|
||||
@NotNull Arg[] args,
|
||||
@NotNull Function<Arg, PsiType> typeComputer) {
|
||||
List<ArgWrapper<Arg>> actual = new ArrayList<ArgWrapper<Arg>>(signature.getParameterCount());
|
||||
for (Arg arg : args) {
|
||||
actual.add(new ArgWrapper<Arg>(typeComputer.fun(arg), arg));
|
||||
}
|
||||
GrCurriedClosureSignature curried = signature;
|
||||
while (true) {
|
||||
final PsiType[] curriedArgs = curried.getCurriedArgs();
|
||||
int curriedPosition = curried.getCurriedPosition();
|
||||
if (curriedPosition == -1) curriedPosition = actual.size();
|
||||
if (curriedPosition > actual.size()) return null;
|
||||
|
||||
for (int i = 0; i < curriedArgs.length; i++, curriedPosition++) {
|
||||
actual.add(curriedPosition, new ArgWrapper<Arg>(curriedArgs[i], null));
|
||||
}
|
||||
if (!(curried.getOriginalSignature() instanceof GrCurriedClosureSignature)) break;
|
||||
curried = (GrCurriedClosureSignature)curried.getOriginalSignature();
|
||||
}
|
||||
return actual.toArray(new ArgWrapper[args.length]);
|
||||
}
|
||||
|
||||
public static GrClosureSignature getOriginalSignature(GrClosureSignature signature) {
|
||||
if (signature instanceof GrCurriedClosureSignature) {
|
||||
return getOriginalSignature(((GrCurriedClosureSignature)signature).getOriginalSignature());
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static <Arg> ArgInfo<Arg>[] mapParametersToArguments(@NotNull GrClosureSignature signature,
|
||||
@NotNull Arg[] args,
|
||||
@NotNull Function<Arg, PsiType> typeComputer,
|
||||
@NotNull GroovyPsiElement context,
|
||||
boolean partial) {
|
||||
if (signature instanceof GrCurriedClosureSignature) {
|
||||
final ArgWrapper<Arg>[] actualArgs = getActualArgs((GrCurriedClosureSignature)signature, args, typeComputer);
|
||||
if (actualArgs == null) return null;
|
||||
final ArgInfo<ArgWrapper<Arg>>[] argInfos =
|
||||
mapParametersToArguments(getOriginalSignature(signature), actualArgs, GrClosureSignatureUtil.<Arg>ARG_WRAPPER_COMPUTER(), context, partial);
|
||||
if (argInfos == null) return null;
|
||||
|
||||
final ArgInfo<Arg>[] result = new ArgInfo[argInfos.length];
|
||||
for (int i = 0; i < argInfos.length; i++) {
|
||||
ArgInfo<ArgWrapper<Arg>> info = argInfos[i];
|
||||
List<Arg> list = new ArrayList<Arg>();
|
||||
for (ArgWrapper<Arg> arg : info.args) {
|
||||
if (arg.arg != null) list.add(arg.arg);
|
||||
}
|
||||
result[i] = new ArgInfo<Arg>(list, info.isMultiArg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
if (checkForOnlyMapParam(signature, args.length)) return ArgInfo.empty_array();
|
||||
GrClosureParameter[] params = signature.getParameters();
|
||||
if (args.length > params.length && !signature.isVarargs()) return null;
|
||||
@@ -313,7 +384,7 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
|
||||
private static boolean checkForOnlyMapParam(@NotNull GrClosureSignature signature, final int argCount) {
|
||||
if (argCount > 0) return false;
|
||||
if (argCount > 0 || signature.isCurried()) return false;
|
||||
final GrClosureParameter[] parameters = signature.getParameters();
|
||||
if (parameters.length != 1) return false;
|
||||
final PsiType type = parameters[0].getType();
|
||||
@@ -352,6 +423,33 @@ public class GrClosureSignatureUtil {
|
||||
return TypesUtil.isAssignableByMethodCallConversion(paramType, argType, context);
|
||||
}
|
||||
|
||||
public static void checkAndAddSignature(List<GrClosureSignature> list,
|
||||
PsiType[] args,
|
||||
int position,
|
||||
List<GrClosureParameter> params,
|
||||
PsiType returnType,
|
||||
@NotNull GroovyPsiElement context) {
|
||||
final int last = position + args.length;
|
||||
if (last > params.size()) return;
|
||||
|
||||
for (int i = position; i < last; i++) {
|
||||
final GrClosureParameter p = params.get(i);
|
||||
final PsiType type = p.getType();
|
||||
if (!isAssignableByConversion(type, args[i - position], context)) return;
|
||||
}
|
||||
GrClosureParameter[] _p = new GrClosureParameter[params.size() - args.length];
|
||||
int j = 0;
|
||||
for (int i = 0; i < position; i++) {
|
||||
_p[j++] = params.get(i);
|
||||
}
|
||||
for (int i = position + args.length; i < params.size(); i++) {
|
||||
_p[j++] = params.get(i);
|
||||
}
|
||||
|
||||
list.add(new GrClosureSignatureImpl(_p, returnType, _p.length > 0 && _p[_p.length - 1].getType() instanceof PsiArrayType, true));
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
public static GrClosureSignature createSignature(GroovyResolveResult resolveResult) {
|
||||
final PsiElement resolved = resolveResult.getElement();
|
||||
@@ -626,7 +724,9 @@ public class GrClosureSignatureUtil {
|
||||
String name = method.getName();
|
||||
PsiTypeParameter[] typeParameters = method.getTypeParameters();
|
||||
|
||||
return generateAllMethodSignaturesByClosureSignature(name, signature, typeParameters, substitutor);
|
||||
final ArrayList<MethodSignature> result = new ArrayList<MethodSignature>();
|
||||
generateAllMethodSignaturesByClosureSignature(name, signature, typeParameters, substitutor, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static MultiMap<MethodSignature, PsiMethod> findMethodSignatures(PsiMethod[] methods) {
|
||||
@@ -646,10 +746,11 @@ public class GrClosureSignatureUtil {
|
||||
return MethodSignatureUtil.createMethodSignature(name, paramTypes.toArray(new PsiType[paramTypes.size()]), typeParameters, substitutor);
|
||||
}
|
||||
|
||||
public static List<MethodSignature> generateAllMethodSignaturesByClosureSignature(@NotNull String name,
|
||||
@NotNull GrClosureSignature signature,
|
||||
@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiSubstitutor substitutor) {
|
||||
public static void generateAllMethodSignaturesByClosureSignature(@NotNull String name,
|
||||
@NotNull GrClosureSignature signature,
|
||||
@NotNull PsiTypeParameter[] typeParameters,
|
||||
@NotNull PsiSubstitutor substitutor,
|
||||
List<MethodSignature> result) {
|
||||
GrClosureParameter[] params = signature.getParameters();
|
||||
|
||||
ArrayList<PsiType> newParams = new ArrayList<PsiType>(params.length);
|
||||
@@ -666,18 +767,24 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
}
|
||||
|
||||
List<MethodSignature> result = new ArrayList<MethodSignature>(opts.size() + 1);
|
||||
result.add(generateSignature(name, newParams, typeParameters, substitutor));
|
||||
for (int i = 0; i < opts.size(); i++) {
|
||||
newParams.add(optInds.get(i), opts.get(i).getType());
|
||||
result.add(generateSignature(name, newParams, typeParameters, substitutor));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static List<MethodSignature> generateAllMethodSignaturesByClosureSignature(@NotNull String name,
|
||||
@NotNull GrClosureSignature signature) {
|
||||
return generateAllMethodSignaturesByClosureSignature(name, signature, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
|
||||
public static List<MethodSignature> generateAllMethodSignaturesBySignature(@NotNull final String name,
|
||||
@NotNull final GrSignature signature) {
|
||||
|
||||
final ArrayList<MethodSignature> result = new ArrayList<MethodSignature>();
|
||||
signature.accept(new GrRecursiveSignatureVisitor() {
|
||||
@Override
|
||||
public void visitClosureSignature(GrClosureSignature signature) {
|
||||
generateAllMethodSignaturesByClosureSignature(name, signature, PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, result);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -713,4 +820,31 @@ public class GrClosureSignatureUtil {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param signature
|
||||
* @return return type or null if there is some different return types
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiType getReturnType(GrSignature signature) {
|
||||
if (signature instanceof GrClosureSignature) {
|
||||
return ((GrClosureSignature)signature).getReturnType();
|
||||
}
|
||||
else if (signature instanceof GrMultiSignature) {
|
||||
final GrClosureSignature[] signatures = ((GrMultiSignature)signature).getAllSignatures();
|
||||
if (signatures.length == 0) return null;
|
||||
final PsiType type = signatures[0].getReturnType();
|
||||
if (type == null) return null;
|
||||
String firstType = type.getCanonicalText();
|
||||
for (int i = 1; i < signatures.length; i++) {
|
||||
final PsiType _type = signatures[i].getReturnType();
|
||||
if (_type == null) return null;
|
||||
if (!firstType.equals(_type.getCanonicalText())) return null;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.signatures;
|
||||
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrMultiSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignatureVisitor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrMultiSignatureImpl implements GrMultiSignature {
|
||||
private final GrClosureSignature[] mySignatures;
|
||||
|
||||
public GrMultiSignatureImpl(GrClosureSignature[] signatures) {
|
||||
mySignatures = signatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrClosureSignature[] getAllSignatures() {
|
||||
return mySignatures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
for (GrClosureSignature signature : mySignatures) {
|
||||
if (!signature.isValid()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrSignature curry(@NotNull PsiType[] args, int position, @NotNull GroovyPsiElement context) {
|
||||
List<GrClosureSignature> newClosures = new ArrayList<GrClosureSignature>();
|
||||
|
||||
for (GrClosureSignature old : mySignatures) {
|
||||
final GrSignature curried = old.curry(args, position, context);
|
||||
if (curried instanceof GrClosureSignature) {
|
||||
newClosures.add((GrClosureSignature)curried);
|
||||
}
|
||||
else if (curried instanceof GrMultiSignature) {
|
||||
newClosures.addAll(Arrays.asList(((GrMultiSignature)curried).getAllSignatures()));
|
||||
}
|
||||
}
|
||||
return new GrMultiSignatureImpl(newClosures.toArray(new GrClosureSignature[newClosures.size()]));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(GrSignatureVisitor visitor) {
|
||||
visitor.visitMultiSignature(this);
|
||||
}
|
||||
}
|
||||
+7
-3
@@ -62,7 +62,7 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs
|
||||
PsiType returnType = null;
|
||||
final PsiManager manager = assignment.getManager();
|
||||
for (GroovyResolveResult result : results) {
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result, assignment);
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(result, assignment, new PsiType[]{getRValueType(assignment)});
|
||||
returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager);
|
||||
}
|
||||
return returnType;
|
||||
@@ -218,12 +218,16 @@ public class GrAssignmentExpressionImpl extends GrExpressionImpl implements GrAs
|
||||
}
|
||||
if (lType == null) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
final GrExpression rightOperand = assignmentExpression.getRValue();
|
||||
PsiType rType = rightOperand == null ? null : rightOperand.getType();
|
||||
PsiType rType = getRValueType(assignmentExpression);
|
||||
|
||||
final IElementType operatorToken = TokenSets.ASSIGNMENTS_TO_OPERATORS.get(opType);
|
||||
return TypesUtil.getOverloadedOperatorCandidates(lType, operatorToken, assignmentExpression, new PsiType[]{rType});
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
private static PsiType getRValueType(GrAssignmentExpressionImpl assignmentExpression) {
|
||||
final GrExpression rightOperand = assignmentExpression.getRValue();
|
||||
return rightOperand == null ? null : rightOperand.getType();
|
||||
}
|
||||
}
|
||||
|
||||
+8
-3
@@ -51,12 +51,17 @@ public abstract class GrBinaryExpressionImpl extends GrExpressionImpl implements
|
||||
final PsiType lType = binary.getLeftOperand().getType();
|
||||
if (lType == null) return GroovyResolveResult.EMPTY_ARRAY;
|
||||
|
||||
final GrExpression rightOperand = binary.getRightOperand();
|
||||
PsiType rType = rightOperand == null ? null : rightOperand.getType();
|
||||
PsiType rType = getRightType(binary);
|
||||
return TypesUtil.getOverloadedOperatorCandidates(lType, opType, binary, new PsiType[]{rType});
|
||||
}
|
||||
};
|
||||
|
||||
@Nullable
|
||||
private static PsiType getRightType(GrBinaryExpressionImpl binary) {
|
||||
final GrExpression rightOperand = binary.getRightOperand();
|
||||
return rightOperand == null ? null : rightOperand.getType();
|
||||
}
|
||||
|
||||
private static final Function<GrBinaryExpressionImpl,PsiType> TYPE_CALCULATOR = new Function<GrBinaryExpressionImpl, PsiType>() {
|
||||
@Nullable
|
||||
@Override
|
||||
@@ -68,7 +73,7 @@ public abstract class GrBinaryExpressionImpl extends GrExpressionImpl implements
|
||||
}
|
||||
|
||||
final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(binary.multiResolve(false));
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, binary);
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, binary, new PsiType[]{getRightType(binary)});
|
||||
return TypesUtil.boxPrimitiveType(substituted, binary.getManager(), binary.getResolveScope());
|
||||
}
|
||||
};
|
||||
|
||||
+1
-4
@@ -487,10 +487,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
}
|
||||
|
||||
if (dotType == mMEMBER_POINTER) {
|
||||
if (resolved instanceof PsiMethod) {
|
||||
return GrClosureType.create((PsiMethod) resolved, resolveResult.getSubstitutor());
|
||||
}
|
||||
return TypesUtil.createTypeByFQClassName(GroovyCommonClassNames.GROOVY_LANG_CLOSURE, this);
|
||||
return GrClosureType.create(multiResolve(false), this);
|
||||
}
|
||||
PsiType result = null;
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(getProject());
|
||||
|
||||
+14
-10
@@ -35,11 +35,12 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrTypeConverter;
|
||||
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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.util.LightCacheKey;
|
||||
@@ -482,15 +483,18 @@ public class TypesUtil {
|
||||
else if (type1 instanceof GrClosureType && type2 instanceof GrClosureType) {
|
||||
GrClosureType clType1 = (GrClosureType)type1;
|
||||
GrClosureType clType2 = (GrClosureType)type2;
|
||||
GrClosureSignature signature1 = clType1.getSignature();
|
||||
GrClosureSignature signature2 = clType2.getSignature();
|
||||
GrSignature signature1 = clType1.getSignature();
|
||||
GrSignature signature2 = clType2.getSignature();
|
||||
|
||||
if (signature1.getParameterCount() == signature2.getParameterCount()) {
|
||||
final GrClosureSignature signature = GrClosureSignatureImpl.getLeastUpperBound(signature1, signature2, manager);
|
||||
if (signature != null) {
|
||||
GlobalSearchScope scope = clType1.getResolveScope().intersectWith(clType2.getResolveScope());
|
||||
final LanguageLevel languageLevel = ComparatorUtil.max(clType1.getLanguageLevel(), clType2.getLanguageLevel());
|
||||
return GrClosureType.create(signature, scope, JavaPsiFacade.getInstance(manager.getProject()), languageLevel, true);
|
||||
if (signature1 instanceof GrClosureSignature && signature2 instanceof GrClosureSignature) {
|
||||
if (((GrClosureSignature)signature1).getParameterCount() == ((GrClosureSignature)signature2).getParameterCount()) {
|
||||
final GrClosureSignature signature = GrClosureSignatureImpl.getLeastUpperBound(((GrClosureSignature)signature1),
|
||||
((GrClosureSignature)signature2), manager);
|
||||
if (signature != null) {
|
||||
GlobalSearchScope scope = clType1.getResolveScope().intersectWith(clType2.getResolveScope());
|
||||
final LanguageLevel languageLevel = ComparatorUtil.max(clType1.getLanguageLevel(), clType2.getLanguageLevel());
|
||||
return GrClosureType.create(signature, scope, JavaPsiFacade.getInstance(manager.getProject()), languageLevel, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ public class GrUnaryExpressionImpl extends GrExpressionImpl implements GrUnaryEx
|
||||
if (opType == null) return null;
|
||||
|
||||
final GroovyResolveResult resolveResult = PsiImplUtil.extractUniqueResult(unary.multiResolve(false));
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, unary);
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(resolveResult, unary, PsiType.EMPTY_ARRAY);
|
||||
if (substituted != null) {
|
||||
return TypesUtil.boxPrimitiveType(substituted, unary.getManager(), unary.getResolveScope());
|
||||
}
|
||||
|
||||
+7
-6
@@ -31,6 +31,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrRefere
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.typeEnhancers.GrCallExpressionTypeCalculator;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
@@ -99,7 +100,7 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
private static PsiType extractReturnTypeFromType(PsiType type, boolean returnTypeIfFail, GrMethodCall callExpression) {
|
||||
PsiType returnType = returnTypeIfFail ? type: null;
|
||||
if (type instanceof GrClosureType) {
|
||||
returnType = ((GrClosureType) type).getSignature().getReturnType();
|
||||
returnType = GrClosureSignatureUtil.getReturnType(((GrClosureType)type).getSignature(), callExpression);
|
||||
}
|
||||
else if (isPsiClassTypeToClosure(type)) {
|
||||
assert type instanceof PsiClassType;
|
||||
@@ -114,7 +115,7 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
returnType = null;
|
||||
final PsiManager manager = callExpression.getManager();
|
||||
for (GroovyResolveResult call : calls) {
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(call, callExpression);
|
||||
final PsiType substituted = ResolveUtil.extractReturnTypeFromCandidate(call, callExpression, PsiUtil.getArgumentTypes(callExpression.getInvokedExpression(), true));
|
||||
returnType = TypesUtil.getLeastUpperBoundNullable(returnType, substituted, manager);
|
||||
}
|
||||
}
|
||||
@@ -154,16 +155,16 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
if (!(qType instanceof GrClosureType)) return null;
|
||||
|
||||
if ("call".equals(resolved.getName())) {
|
||||
return ((GrClosureType)qType).getSignature().getReturnType();
|
||||
return GrClosureSignatureUtil.getReturnType(((GrClosureType)qType).getSignature(), callExpression);
|
||||
}
|
||||
else if ("curry".equals(resolved.getName()) || "trampoline".equals(resolved.getName())) {
|
||||
return ((GrClosureType)qType).curry(PsiUtil.getArgumentTypes(refExpr, false), 0);
|
||||
return ((GrClosureType)qType).curry(PsiUtil.getArgumentTypes(refExpr, false), 0, callExpression);
|
||||
}
|
||||
else if ("memoize".equals(resolved.getName())) {
|
||||
return qType;
|
||||
}
|
||||
else if ("rcurry".equals(resolved.getName())) {
|
||||
return ((GrClosureType)qType).curry(PsiUtil.getArgumentTypes(refExpr, false), -1);
|
||||
return ((GrClosureType)qType).curry(PsiUtil.getArgumentTypes(refExpr, false), -1, callExpression);
|
||||
}
|
||||
else if ("ncurry".equals(resolved.getName())) {
|
||||
final GrArgumentList argList = callExpression.getArgumentList();
|
||||
@@ -176,7 +177,7 @@ public class DefaultCallExpressionTypeCalculator extends GrCallExpressionTypeCal
|
||||
if (value instanceof Integer) {
|
||||
final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false);
|
||||
if (argTypes != null) {
|
||||
return ((GrClosureType)qType).curry(ArrayUtil.remove(argTypes, 0), (Integer)value);
|
||||
return ((GrClosureType)qType).curry(ArrayUtil.remove(argTypes, 0), (Integer)value, callExpression);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+14
-2
@@ -101,9 +101,21 @@ public class GrIndexPropertyImpl extends GrExpressionImpl implements GrIndexProp
|
||||
}
|
||||
|
||||
final GroovyResolveResult[] candidates = index.multiResolve(false);
|
||||
PsiType overloadedOperatorType = ResolveUtil.extractReturnTypeFromCandidate(PsiImplUtil.extractUniqueResult(candidates), index);
|
||||
|
||||
PsiType componentType = extractMapValueType(thisType, argTypes, manager, resolveScope);
|
||||
|
||||
PsiType[] args = PsiUtil
|
||||
.getArgumentTypes(argList.getNamedArguments(), argList.getExpressionArguments(), GrClosableBlock.EMPTY_ARRAY, true, null);
|
||||
final GroovyResolveResult candidate = PsiImplUtil.extractUniqueResult(candidates);
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiNamedElement) {
|
||||
final String name = ((PsiNamedElement)element).getName();
|
||||
if ("putAt".equals(name) && args != null) {
|
||||
args = ArrayUtil.append(args, TypeInferenceHelper.getInitializerFor(index), PsiType.class);
|
||||
}
|
||||
}
|
||||
PsiType overloadedOperatorType = ResolveUtil.extractReturnTypeFromCandidate(candidate, index, args);
|
||||
|
||||
PsiType componentType = extractMapValueType(thisType, args, manager, resolveScope);
|
||||
|
||||
if (overloadedOperatorType != null &&
|
||||
(componentType == null || !TypesUtil.isAssignable(overloadedOperatorType, componentType, manager, resolveScope))) {
|
||||
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.impl.types;
|
||||
|
||||
import com.intellij.psi.PsiSubstitutor;
|
||||
import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCurriedClosureSignature;
|
||||
|
||||
public class GrCurriedClosureSignatureImpl implements GrCurriedClosureSignature {
|
||||
|
||||
private final GrClosureSignature myOriginal;
|
||||
private final PsiType[] myArgs;
|
||||
private final int myPosition;
|
||||
|
||||
public GrCurriedClosureSignatureImpl(GrClosureSignature original, PsiType[] args, int position) {
|
||||
myOriginal = original;
|
||||
myArgs = args;
|
||||
myPosition = position;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType getReturnType() {
|
||||
return myOriginal.getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiType[] getCurriedArgs() {
|
||||
return myArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCurriedPosition() {
|
||||
return myPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrClosureSignature getOriginalSignature() {
|
||||
return myOriginal;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiSubstitutor getSubstitutor() {
|
||||
return myOriginal.getSubstitutor();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrClosureParameter[] getParameters() {
|
||||
return myOriginal.getParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getParameterCount() {
|
||||
return myOriginal.getParameterCount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVarargs() {
|
||||
return myOriginal.isVarargs();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrCurriedClosureSignature curry(PsiType[] args, int position) {
|
||||
return new GrCurriedClosureSignatureImpl(this, args, position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myOriginal.isValid();
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.Trinity;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
@@ -51,6 +52,8 @@ import org.jetbrains.plugins.groovy.lang.psi.*;
|
||||
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.auxiliary.modifiers.GrModifierList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
@@ -70,14 +73,13 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrMemberOwne
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrNamedArgumentsOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.JavaIdentifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor;
|
||||
|
||||
@@ -194,7 +196,7 @@ public class PsiUtil {
|
||||
GroovyPsiElement context) {
|
||||
if (argumentTypes == null) return GrClosureSignatureUtil.ApplicabilityResult.canBeApplicable;
|
||||
|
||||
GrClosureSignature signature = type.getSignature();
|
||||
GrSignature signature = type.getSignature();
|
||||
return GrClosureSignatureUtil.isSignatureApplicableConcrete(signature, argumentTypes, context);
|
||||
}
|
||||
|
||||
@@ -603,8 +605,7 @@ public class PsiUtil {
|
||||
final GrExpression expression = call.getInvokedExpression();
|
||||
if (expression instanceof GrReferenceExpression && result.isInvokedOnProperty()) {
|
||||
if (returnType instanceof GrClosureType) {
|
||||
final GrClosureSignature signature = ((GrClosureType)returnType).getSignature();
|
||||
return isRawType(signature.getReturnType(), TypesUtil.composeSubstitutors(signature.getSubstitutor(), result.getSubstitutor()));
|
||||
return isRawClosureCall(call, result, (GrClosureType)returnType);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -614,14 +615,31 @@ public class PsiUtil {
|
||||
if (element instanceof PsiVariable) {
|
||||
final PsiType type = call.getInvokedExpression().getType();
|
||||
if (type instanceof GrClosureType) {
|
||||
final GrClosureSignature signature = ((GrClosureType)type).getSignature();
|
||||
return isRawType(signature.getReturnType(), TypesUtil.composeSubstitutors(signature.getSubstitutor(), result.getSubstitutor()));
|
||||
return isRawClosureCall(call, result, (GrClosureType)type);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isRawClosureCall(GrMethodCallExpression call, GroovyResolveResult result, GrClosureType returnType) {
|
||||
final GrSignature signature = returnType.getSignature();
|
||||
GrClosureSignature _signature;
|
||||
if (signature instanceof GrClosureSignature) {
|
||||
_signature = (GrClosureSignature)signature;
|
||||
}
|
||||
else {
|
||||
final PsiType[] types = getArgumentTypes(call.getInvokedExpression(), true);
|
||||
final Trinity<GrClosureSignature, GrClosureSignatureUtil.ArgInfo<PsiType>[], GrClosureSignatureUtil.ApplicabilityResult>
|
||||
resultTrinity = types != null ? GrClosureSignatureUtil.getApplicableSignature(signature, types, call) : null;
|
||||
_signature = resultTrinity != null ? resultTrinity.first : null;
|
||||
}
|
||||
if (_signature != null) {
|
||||
return isRawType(_signature.getReturnType(), TypesUtil.composeSubstitutors(_signature.getSubstitutor(), result.getSubstitutor()));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isRawFieldAccess(GrReferenceExpression ref) {
|
||||
PsiElement element = null;
|
||||
final GroovyResolveResult[] resolveResults = ref.multiResolve(false);
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
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.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrNamedArgument;
|
||||
@@ -51,11 +52,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousC
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GdkMethodUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
@@ -679,12 +679,12 @@ public class ResolveUtil {
|
||||
private static boolean isApplicableClosureType(PsiType type, PsiType[] argTypes, GroovyPsiElement place) {
|
||||
if (!(type instanceof GrClosureType)) return false;
|
||||
|
||||
final GrClosureSignature signature = ((GrClosureType)type).getSignature();
|
||||
final GrSignature signature = ((GrClosureType)type).getSignature();
|
||||
return GrClosureSignatureUtil.isSignatureApplicable(signature, argTypes, place);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PsiType extractReturnTypeFromCandidate(GroovyResolveResult candidate, GrExpression expression) {
|
||||
public static PsiType extractReturnTypeFromCandidate(GroovyResolveResult candidate, GrExpression expression, @Nullable PsiType[] args) {
|
||||
final PsiElement element = candidate.getElement();
|
||||
if (element instanceof PsiMethod && !candidate.isInvokedOnProperty()) {
|
||||
return TypesUtil.substituteBoxAndNormalizeType(getSmartReturnType((PsiMethod)element), candidate.getSubstitutor(), expression);
|
||||
@@ -701,7 +701,8 @@ public class ResolveUtil {
|
||||
return null;
|
||||
}
|
||||
if (type instanceof GrClosureType) {
|
||||
PsiType returnType = ((GrClosureType)type).getSignature().getReturnType();
|
||||
final GrSignature signature = ((GrClosureType)type).getSignature();
|
||||
PsiType returnType = GrClosureSignatureUtil.getReturnType(signature, args, expression);
|
||||
return TypesUtil.substituteBoxAndNormalizeType(returnType, candidate.getSubstitutor(), expression);
|
||||
}
|
||||
return null;
|
||||
|
||||
+2
-2
@@ -27,12 +27,12 @@ import org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider;
|
||||
import org.jetbrains.plugins.groovy.gpp.GppTypeConverter;
|
||||
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.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyResolveResultImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
|
||||
+2
-2
@@ -26,6 +26,7 @@ import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrClassInitializer;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
@@ -37,9 +38,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GdkMethodUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
|
||||
+1
-1
@@ -68,8 +68,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefini
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
|
||||
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.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.DefaultGroovyVariableNameValidator;
|
||||
|
||||
+2
-2
@@ -27,11 +27,11 @@ import com.intellij.refactoring.changeSignature.PossiblyIncorrectUsage;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrEnumConstant;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
/**
|
||||
|
||||
+31
-24
@@ -20,14 +20,15 @@ import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.refactoring.util.RefactoringUIUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.plugins.groovy.lang.documentation.GroovyPresentationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrRecursiveSignatureVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrClosureType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
|
||||
|
||||
@@ -45,18 +46,18 @@ public class GrMethodConflictUtil {
|
||||
GrMethod refactoredMethod,
|
||||
final MultiMap<PsiElement, String> conflicts, boolean excludeJavaConflicts) {
|
||||
List<MethodSignature> prototypeSignatures = GrClosureSignatureUtil.generateAllSignaturesForMethod(prototype, PsiSubstitutor.EMPTY);
|
||||
checkForClosurePropertySignatrureOverload(clazz, prototype, refactoredMethod, conflicts, prototypeSignatures);
|
||||
checkForClosurePropertySignatureOverload(clazz, prototype, refactoredMethod, conflicts, prototypeSignatures);
|
||||
checkForMethodSignatureOverload(clazz, prototype, refactoredMethod, conflicts, excludeJavaConflicts, prototypeSignatures);
|
||||
|
||||
checkForAccessorOverloading(clazz, prototype, conflicts);
|
||||
}
|
||||
|
||||
private static void checkForClosurePropertySignatrureOverload(PsiClass clazz,
|
||||
GrMethod prototype,
|
||||
GrMethod refactoredMethod,
|
||||
MultiMap<PsiElement, String> conflicts,
|
||||
List<MethodSignature> prototypeSignatures) {
|
||||
final boolean isStatic = prototype.hasModifierProperty(GrModifier.STATIC);
|
||||
private static void checkForClosurePropertySignatureOverload(PsiClass clazz,
|
||||
GrMethod prototype,
|
||||
final GrMethod refactoredMethod,
|
||||
final MultiMap<PsiElement, String> conflicts,
|
||||
final List<MethodSignature> prototypeSignatures) {
|
||||
final boolean isStatic = prototype.hasModifierProperty(PsiModifier.STATIC);
|
||||
final String name = prototype.getName();
|
||||
if (!GroovyPropertyUtils.isProperty(clazz, name, isStatic)) return;
|
||||
|
||||
@@ -74,20 +75,26 @@ public class GrMethodConflictUtil {
|
||||
}
|
||||
if (!(returnType instanceof GrClosureType)) return;
|
||||
|
||||
final GrClosureSignature signature = ((GrClosureType)returnType).getSignature();
|
||||
|
||||
NextSignature:
|
||||
for (MethodSignature prototypeSignature : prototypeSignatures) {
|
||||
final GrClosureParameter[] params = signature.getParameters();
|
||||
final PsiType[] types = prototypeSignature.getParameterTypes();
|
||||
if (types.length != params.length) continue;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (!TypesUtil.isAssignableByMethodCallConversion(types[i], params[i].getType(), refactoredMethod.getParameterList())) {
|
||||
continue NextSignature;
|
||||
final GrSignature signature = ((GrClosureType)returnType).getSignature();
|
||||
signature.accept(new GrRecursiveSignatureVisitor() {
|
||||
@Override
|
||||
public void visitClosureSignature(GrClosureSignature signature) {
|
||||
NextSignature:
|
||||
for (MethodSignature prototypeSignature : prototypeSignatures) {
|
||||
final GrClosureParameter[] params = signature.getParameters();
|
||||
final PsiType[] types = prototypeSignature.getParameterTypes();
|
||||
if (types.length != params.length) continue;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
if (!TypesUtil.isAssignableByMethodCallConversion(types[i], params[i].getType(), refactoredMethod.getParameterList())) {
|
||||
continue NextSignature;
|
||||
}
|
||||
}
|
||||
conflicts.putValue(getter, GroovyRefactoringBundle.message("refactored.method.will.cover.closure.property", name, RefactoringUIUtil.getDescription(getter.getContainingClass(), false)));
|
||||
}
|
||||
}
|
||||
conflicts.putValue(getter, GroovyRefactoringBundle.message("refactored.method.will.cover.closure.property", name, RefactoringUIUtil.getDescription(getter.getContainingClass(), false)));
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static void checkForMethodSignatureOverload(PsiClass clazz,
|
||||
@@ -121,13 +128,13 @@ public class GrMethodConflictUtil {
|
||||
if (GroovyPropertyUtils.isSimplePropertySetter(prototype)) {
|
||||
String propertyName = GroovyPropertyUtils.getPropertyNameBySetter(prototype);
|
||||
PsiMethod setter =
|
||||
GroovyPropertyUtils.findPropertySetter(clazz, propertyName, prototype.hasModifierProperty(GrModifier.STATIC), false);
|
||||
GroovyPropertyUtils.findPropertySetter(clazz, propertyName, prototype.hasModifierProperty(PsiModifier.STATIC), false);
|
||||
if (setter instanceof GrAccessorMethod) {
|
||||
conflicts.putValue(setter, GroovyRefactoringBundle.message("replace.setter.for.property", propertyName));
|
||||
}
|
||||
}
|
||||
else if (GroovyPropertyUtils.isSimplePropertyGetter(prototype)) {
|
||||
boolean isStatic = prototype.hasModifierProperty(GrModifier.STATIC);
|
||||
boolean isStatic = prototype.hasModifierProperty(PsiModifier.STATIC);
|
||||
String propertyName = GroovyPropertyUtils.getPropertyNameByGetter(prototype);
|
||||
PsiMethod getter = GroovyPropertyUtils.findPropertyGetter(clazz, propertyName, isStatic, false);
|
||||
if (getter instanceof GrAccessorMethod) {
|
||||
|
||||
+3
-3
@@ -18,22 +18,22 @@ package org.jetbrains.plugins.groovy.refactoring.convertToJava;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
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.blocks.GrCodeBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.plugins.groovy.refactoring.convertToJava.ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT;
|
||||
import static org.jetbrains.plugins.groovy.refactoring.convertToJava.GenerationUtil.writeType;
|
||||
import static org.jetbrains.plugins.groovy.refactoring.convertToJava.ModifierListGenerator.JAVA_MODIFIERS_WITHOUT_ABSTRACT;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
|
||||
+2
-2
@@ -24,13 +24,13 @@ import com.intellij.psi.PsiType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
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.types.GrClosureParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
+2
-2
@@ -30,6 +30,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrDefaultAnnotationValue;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
@@ -41,9 +42,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpres
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrEnumConstantInitializer;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
+1
-1
@@ -49,8 +49,8 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.GroovyCommonClassNames;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
+2
-2
@@ -32,6 +32,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
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.formatter.GrControlStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
@@ -48,7 +49,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrAnonymousClassDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrArrayTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
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.api.util.GrStatementOwner;
|
||||
@@ -58,9 +58,9 @@ import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrLiteralClassType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrRangeType;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.ClosureSyntheticParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
|
||||
+2
-2
@@ -23,6 +23,7 @@ import com.intellij.util.containers.HashMap;
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntProcedure;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
@@ -30,10 +31,9 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
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.psi.util.PsiUtil;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
+2
-2
@@ -49,6 +49,7 @@ import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.TokenSets;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.arguments.GrArgumentList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
@@ -59,11 +60,10 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.util.GrStatementOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.Instruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.controlFlow.ReadWriteVariableInstruction;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
+2
-2
@@ -41,6 +41,7 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrParametersOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
@@ -55,8 +56,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrThisRe
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError;
|
||||
|
||||
+2
-2
@@ -39,6 +39,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
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.arguments.GrArgumentList;
|
||||
@@ -51,8 +52,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrM
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameterList;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.parameter.GroovyIntroduceParameterUtil;
|
||||
|
||||
|
||||
+2
-2
@@ -31,6 +31,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.signatures.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrStatement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
@@ -38,8 +39,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrAccessorMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.signatures.GrClosureSignatureUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyPropertyUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
@@ -888,4 +888,40 @@ Date d = <warning descr="Cannot assign 'Object' to 'Date'">a.cl()</warning>
|
||||
myFixture.enableInspections(inspections)
|
||||
myFixture.testHighlighting(true, false, true)
|
||||
}
|
||||
|
||||
void testMethodRefs1() {
|
||||
myFixture.configureByText('_.groovy', '''\
|
||||
class A {
|
||||
int foo(){2}
|
||||
|
||||
Date foo(int x) {null}
|
||||
}
|
||||
|
||||
def foo = new A().&foo
|
||||
|
||||
int i = foo()
|
||||
int i2 = <warning descr="Cannot assign 'Date' to 'int'">foo(2)</warning>
|
||||
Date d = foo(2)
|
||||
Date d2 = <warning descr="Cannot assign 'Integer' to 'Date'">foo()</warning>
|
||||
''')
|
||||
testHighlighting(GroovyAssignabilityCheckInspection)
|
||||
}
|
||||
|
||||
void testMethodRefs2() {
|
||||
myFixture.configureByText('_.groovy', '''\
|
||||
class Bar {
|
||||
def foo(int i, String s2) {s2}
|
||||
def foo(int i, int i2) {i2}
|
||||
}
|
||||
|
||||
def cl = new Bar<error descr="'(' expected">.</error>&foo
|
||||
cl = cl.curry(1)
|
||||
String s = cl("2")
|
||||
int s2 = <warning descr="Cannot assign 'String' to 'int'">cl("2")</warning>
|
||||
int i = cl(3)
|
||||
String i2 = cl(3)
|
||||
''')
|
||||
testHighlighting(GroovyAssignabilityCheckInspection)
|
||||
}
|
||||
|
||||
}
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
groovy.lang.Closure a = new org.codehaus.groovy.runtime.MethodClosure(new java.util.ArrayList<java.lang.String>(), "add");
|
||||
groovy.lang.Closure<java.lang.Object> a = new org.codehaus.groovy.runtime.MethodClosure(new java.util.ArrayList<java.lang.String>(), "add");
|
||||
a.call("2");
|
||||
|
||||
Reference in New Issue
Block a user