revive commented g++ tests

This commit is contained in:
peter
2010-07-12 11:56:39 +01:00
parent 2f6dde646a
commit 99324b612f
18 changed files with 264 additions and 181 deletions
@@ -44,18 +44,17 @@ public class GppTypeConverter extends GrTypeConverter {
@Override
public Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context) {
if (rType instanceof GrTupleType) {
final PsiType type = PsiUtil.extractIterableTypeParameter(lType, false);
if (type == null || TypesUtil.isAssignable(type, ((GrTupleType)rType).getParameters()[0], context)) {
final PsiType[] componentTypes = ((GrTupleType)rType).getComponentTypes();
final GrTupleType tupleType = (GrTupleType)rType;
final PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(lType, false);
if (expectedComponent != null && hasDefaultConstructor(lType)) {
return true;
}
final PsiType expectedComponent = PsiUtil.extractIterableTypeParameter(lType, false);
if (expectedComponent != null &&
isMethodCallConversion(context) && TypesUtil.isAssignable(expectedComponent, tupleType.getParameters()[0], context) &&
hasDefaultConstructor(lType)) {
return true;
}
if (lType instanceof PsiClassType && hasConstructor((PsiClassType)lType, componentTypes, context)) {
return true;
}
if (lType instanceof PsiClassType && hasConstructor((PsiClassType)lType, tupleType.getComponentTypes(), context)) {
return true;
}
}
else if (rType instanceof GrMapType) {
@@ -261,7 +261,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
else if (call instanceof GrCallExpression) {
GrCallExpression constructorCall = (GrCallExpression)call;
ContainerUtil.addAll(results, constructorCall.getMethodVariants());
ContainerUtil.addAll(results, constructorCall.getMethodVariants(null));
final PsiType type = ((GrCallExpression)call).getType();
if (type instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)type).resolve();
@@ -5,6 +5,7 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
/**
* @author peter
@@ -12,7 +13,11 @@ import org.jetbrains.annotations.Nullable;
public abstract class GrTypeConverter {
public static final ExtensionPointName<GrTypeConverter> EP_NAME = ExtensionPointName.create("org.intellij.groovy.typeConverter");
protected static boolean isMethodCallConversion(GroovyPsiElement context) {
return context.getParent() instanceof GrMethodCall;
}
@Nullable
public abstract Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context);
}
}
@@ -43,7 +43,7 @@ public interface GrCallExpression extends GrExpression, GrCall {
PsiMethod resolveMethod();
@NotNull
GroovyResolveResult[] getMethodVariants();
GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument);
//PsiElement addNamedArgument(GrNamedArgument argument);
}
@@ -127,7 +127,7 @@ public class GroovyExpectedTypesProvider {
final int closureIndex = closureArgs.indexOf(myExpression);
if (closureIndex >= 0) {
List<TypeConstraint> constraints = new ArrayList<TypeConstraint>();
for (GroovyResolveResult variant : methodCall.getMethodVariants()) {
for (GroovyResolveResult variant : ResolveUtil.getMethodVariants(myExpression)) {
PsiParameter[] parameters = getCallParameters(variant);
if (parameters == null || parameters.length == 0) continue;
@@ -32,6 +32,10 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUt
public class GrContainerTypeConverter extends GrTypeConverter {
@Override
public Boolean isConvertible(@NotNull PsiType lType, @NotNull PsiType rType, @NotNull GroovyPsiElement context) {
if (isMethodCallConversion(context)) {
return null;
}
if (!isCollectionOrArray(lType) || !isCollectionOrArray(rType)) return null;
final PsiType lComponentType = extractComponentType(lType);
@@ -115,7 +115,9 @@ public class GrMapType extends GrLiteralClassType {
for (Pair<PsiType, PsiType> entry : myOtherEntries) {
components.add(getInternalCanonicalText(entry.first) + ":" + getInternalCanonicalText(entry.second));
}
return "[" + StringUtil.join(components, ", ") + "]";
boolean tooMany = components.size() > 2;
final List<String> theFirst = components.subList(0, Math.min(2, components.size()));
return "[" + StringUtil.join(theFirst, ", ") + (tooMany ? ",..." : "") + "]";
}
public boolean isValid() {
@@ -59,6 +59,11 @@ public class GrTupleType extends GrLiteralClassType {
StringBuilder builder = new StringBuilder();
builder.append("[");
for (int i = 0; i < myComponentTypes.length; i++) {
if (i >= 2) {
builder.append(",...");
break;
}
if (i > 0) builder.append(", ");
builder.append(getInternalCanonicalText(myComponentTypes[i]));
}
@@ -42,7 +42,6 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
@@ -183,7 +182,7 @@ public class GrNewExpressionImpl extends GrCallExpressionImpl implements GrNewEx
}
@NotNull
public GroovyResolveResult[] getMethodVariants() {
public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) {
final GrCodeReferenceElement referenceElement = getReferenceElement();
if (referenceElement == null) return GroovyResolveResult.EMPTY_ARRAY;
final GroovyResolveResult[] classResults = referenceElement.multiResolve(false);
@@ -28,7 +28,10 @@ import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PropertyUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -61,7 +64,6 @@ import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
@@ -413,7 +415,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
Kind kind = refExpr.getKind();
if (incompleteCode) {
ResolverProcessor processor = CompletionProcessor.createRefSameNameProcessor(refExpr, name);
resolveImpl(refExpr, processor);
refExpr.resolveImpl(processor);
GroovyResolveResult[] propertyCandidates = processor.getCandidates();
if (propertyCandidates.length > 0) return propertyCandidates;
}
@@ -436,7 +438,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
GroovyResolveResult[] classCandidates = GroovyResolveResult.EMPTY_ARRAY;
if (!hasAt) {
ResolverProcessor classProcessor = new ClassResolverProcessor(refExpr.getReferenceName(), refExpr, kinds);
resolveImpl(refExpr, classProcessor);
refExpr.resolveImpl(classProcessor);
classCandidates = classProcessor.getCandidates();
for (GroovyResolveResult classCandidate : classCandidates) {
final PsiElement element = classCandidate.getElement();
@@ -447,7 +449,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
}
ResolverProcessor processor = new PropertyResolverProcessor(name, refExpr);
resolveImpl(refExpr, processor);
refExpr.resolveImpl(processor);
final GroovyResolveResult[] fieldCandidates = processor.getCandidates();
if (refExpr.hasAt()) {
@@ -471,7 +473,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
for (String getterName : names) {
AccessorResolverProcessor accessorResolver = new AccessorResolverProcessor(getterName, refExpr, !isLValue);
resolveImpl(refExpr, accessorResolver);
refExpr.resolveImpl(accessorResolver);
final GroovyResolveResult[] candidates = accessorResolver.getCandidates(); //can be only one candidate
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
return candidates;
@@ -488,18 +490,15 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
private static GroovyResolveResult[] resolveMethodOrProperty(GrReferenceExpressionImpl refExpr, String name) {
final PsiType[] argTypes = PsiUtil.getArgumentTypes(refExpr, false);
PsiType thisType = getThisType(refExpr);
MethodResolverProcessor methodResolver =
new MethodResolverProcessor(name, refExpr, false, thisType, argTypes, refExpr.getTypeArguments());
resolveImpl(refExpr, methodResolver);
MethodResolverProcessor methodResolver = refExpr.runMethodResolverProcessor(argTypes, false);
assert methodResolver != null;
if (methodResolver.hasApplicableCandidates()) return methodResolver.getCandidates();
final String[] names = GroovyPropertyUtils.suggestGettersName(name);
List<GroovyResolveResult> list = new ArrayList<GroovyResolveResult>();
for (String getterName : names) {
AccessorResolverProcessor getterResolver = new AccessorResolverProcessor(getterName, refExpr, true);
resolveImpl(refExpr, getterResolver);
refExpr.resolveImpl(getterResolver);
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
if (candidates.length == 1 && candidates[0].isStaticsOK()) {
refExpr.putUserData(IS_RESOLVED_TO_GETTER, true);
@@ -511,7 +510,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
}
PropertyResolverProcessor propertyResolver = new PropertyResolverProcessor(name, refExpr);
resolveImpl(refExpr, propertyResolver);
refExpr.resolveImpl(propertyResolver);
if (propertyResolver.hasCandidates()) return propertyResolver.getCandidates();
if (methodResolver.hasCandidates()) {
@@ -525,144 +524,158 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl implements
return GroovyResolveResult.EMPTY_ARRAY;
}
}
private static void resolveImpl(GrReferenceExpressionImpl refExpr, ResolverProcessor processor) {
GrExpression qualifier = refExpr.getQualifierExpression();
if (qualifier == null) {
ResolveUtil.treeWalkUp(refExpr, processor, true);
if (!processor.hasCandidates()) {
qualifier = PsiImplUtil.getRuntimeQualifier(refExpr);
if (qualifier != null) {
processQualifier(refExpr, processor, qualifier);
}
private void resolveImpl(ResolverProcessor processor) {
GrExpression qualifier = getQualifierExpression();
if (qualifier == null) {
ResolveUtil.treeWalkUp(this, processor, true);
if (!processor.hasCandidates()) {
qualifier = PsiImplUtil.getRuntimeQualifier(this);
if (qualifier != null) {
processQualifier(processor, qualifier);
}
}
} else {
if (getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
processQualifier(processor, qualifier);
} else {
if (refExpr.getDotTokenType() != GroovyTokenTypes.mSPREAD_DOT) {
processQualifier(refExpr, processor, qualifier);
} else {
processQualifierForSpreadDot(refExpr, processor, qualifier);
}
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName())) {
processIfJavaLangClass(refExpr, processor, qualifier.getType());
} else if (qualifier instanceof GrThisReferenceExpression) {
processIfJavaLangClass(refExpr, processor, qualifier.getType());
}
}
}
private static void processIfJavaLangClass(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, PsiType type) {
if (type instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)type).resolve();
if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
final PsiType[] params = ((PsiClassType)type).getParameters();
if (params.length == 1) {
processClassQualifierType(refExpr, processor, params[0]);
}
}
}
}
private static void processQualifierForSpreadDot(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult result = ((PsiClassType) qualifierType).resolveGenerics();
PsiClass clazz = result.getElement();
if (clazz != null) {
PsiClass listClass = ResolveUtil.findListClass(refExpr.getManager(), refExpr.getResolveScope());
if (listClass != null && listClass.getTypeParameters().length == 1) {
PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(listClass, clazz, result.getSubstitutor());
if (substitutor != null) {
PsiType componentType = substitutor.substitute(listClass.getTypeParameters()[0]);
if (componentType != null) {
processClassQualifierType(refExpr, processor, componentType);
}
}
}
}
} else if (qualifierType instanceof PsiArrayType) {
processClassQualifierType(refExpr, processor, ((PsiArrayType) qualifierType).getComponentType());
}
}
private static void processQualifier(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType == null) {
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiPackage) {
if (!resolved.processDeclarations(processor, ResolveState.initial(), null, refExpr)) //noinspection UnnecessaryReturnStatement
return;
}
else {
qualifierType = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory()
.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, refExpr.getResolveScope());
processClassQualifierType(refExpr, processor, qualifierType);
}
}
} else {
if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
processClassQualifierType(refExpr, processor, conjunct);
}
} else {
processClassQualifierType(refExpr, processor, qualifierType);
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiClass) { //omitted .class
PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, refExpr.getResolveScope());
if (javaLangClass != null) {
ResolveState state = ResolveState.initial();
PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
if (typeParameters.length == 1) {
substitutor = substitutor.put(typeParameters[0], qualifierType);
state = state.put(PsiSubstitutor.KEY, substitutor);
}
if (!javaLangClass.processDeclarations(processor, state, null, refExpr)) return;
PsiType javaLangClassType = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory().createType(javaLangClass, substitutor);
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, refExpr, false);
}
}
}
}
}
}
private static void processClassQualifierType(GrReferenceExpressionImpl refExpr, ResolverProcessor processor, PsiType qualifierType) {
Project project = refExpr.getProject();
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType) qualifierType).resolveGenerics();
PsiClass qualifierClass = qualifierResult.getElement();
if (qualifierClass != null) {
if (!qualifierClass.processDeclarations(processor,
ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, refExpr))
return;
}
if (!ResolveUtil.processCategoryMembers(refExpr, processor)) return;
} else if (qualifierType instanceof PsiArrayType) {
final GrTypeDefinition arrayClass = GroovyPsiManager.getInstance(project).getArrayClass();
if (!arrayClass.processDeclarations(processor, ResolveState.initial(), null, refExpr)) return;
} else if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
processClassQualifierType(refExpr, processor, conjunct);
}
return;
processQualifierForSpreadDot(processor, qualifier);
}
ResolveUtil.processNonCodeMethods(qualifierType, processor, refExpr, false);
if (qualifier instanceof GrReferenceExpression && "class".equals(((GrReferenceExpression)qualifier).getReferenceName())) {
processIfJavaLangClass(processor, qualifier.getType());
} else if (qualifier instanceof GrThisReferenceExpression) {
processIfJavaLangClass(processor, qualifier.getType());
}
}
}
private static PsiType getThisType(GrReferenceExpression refExpr) {
GrExpression qualifier = refExpr.getQualifierExpression();
private void processIfJavaLangClass(ResolverProcessor processor, PsiType type) {
if (type instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)type).resolve();
if (psiClass != null && CommonClassNames.JAVA_LANG_CLASS.equals(psiClass.getQualifiedName())) {
final PsiType[] params = ((PsiClassType)type).getParameters();
if (params.length == 1) {
processClassQualifierType(processor, params[0]);
}
}
}
}
private void processQualifierForSpreadDot(ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult result = ((PsiClassType) qualifierType).resolveGenerics();
PsiClass clazz = result.getElement();
if (clazz != null) {
PsiClass listClass = ResolveUtil.findListClass(getManager(), getResolveScope());
if (listClass != null && listClass.getTypeParameters().length == 1) {
PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(listClass, clazz, result.getSubstitutor());
if (substitutor != null) {
PsiType componentType = substitutor.substitute(listClass.getTypeParameters()[0]);
if (componentType != null) {
processClassQualifierType(processor, componentType);
}
}
}
}
} else if (qualifierType instanceof PsiArrayType) {
processClassQualifierType(processor, ((PsiArrayType) qualifierType).getComponentType());
}
}
private void processQualifier(ResolverProcessor processor, GrExpression qualifier) {
PsiType qualifierType = qualifier.getType();
if (qualifierType == null) {
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiPackage) {
if (!resolved.processDeclarations(processor, ResolveState.initial(), null, this)) //noinspection UnnecessaryReturnStatement
return;
}
else {
qualifierType = JavaPsiFacade.getInstance(getProject()).getElementFactory()
.createTypeByFQClassName(CommonClassNames.JAVA_LANG_OBJECT, getResolveScope());
processClassQualifierType(processor, qualifierType);
}
}
} else {
if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
processClassQualifierType(processor, conjunct);
}
} else {
processClassQualifierType(processor, qualifierType);
if (qualifier instanceof GrReferenceExpression) {
PsiElement resolved = ((GrReferenceExpression) qualifier).resolve();
if (resolved instanceof PsiClass) { //omitted .class
PsiClass javaLangClass = PsiUtil.getJavaLangClass(resolved, getResolveScope());
if (javaLangClass != null) {
ResolveState state = ResolveState.initial();
PsiTypeParameter[] typeParameters = javaLangClass.getTypeParameters();
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
if (typeParameters.length == 1) {
substitutor = substitutor.put(typeParameters[0], qualifierType);
state = state.put(PsiSubstitutor.KEY, substitutor);
}
if (!javaLangClass.processDeclarations(processor, state, null, this)) return;
PsiType javaLangClassType = JavaPsiFacade.getInstance(getProject()).getElementFactory().createType(javaLangClass, substitutor);
ResolveUtil.processNonCodeMethods(javaLangClassType, processor, this, false);
}
}
}
}
}
}
private void processClassQualifierType(ResolverProcessor processor, PsiType qualifierType) {
Project project = getProject();
if (qualifierType instanceof PsiClassType) {
PsiClassType.ClassResolveResult qualifierResult = ((PsiClassType) qualifierType).resolveGenerics();
PsiClass qualifierClass = qualifierResult.getElement();
if (qualifierClass != null) {
if (!qualifierClass.processDeclarations(processor,
ResolveState.initial().put(PsiSubstitutor.KEY, qualifierResult.getSubstitutor()), null, this))
return;
}
if (!ResolveUtil.processCategoryMembers(this, processor)) return;
} else if (qualifierType instanceof PsiArrayType) {
final GrTypeDefinition arrayClass = GroovyPsiManager.getInstance(project).getArrayClass();
if (!arrayClass.processDeclarations(processor, ResolveState.initial(), null, this)) return;
} else if (qualifierType instanceof PsiIntersectionType) {
for (PsiType conjunct : ((PsiIntersectionType) qualifierType).getConjuncts()) {
processClassQualifierType(processor, conjunct);
}
return;
}
ResolveUtil.processNonCodeMethods(qualifierType, processor, this, false);
}
@Nullable
public MethodResolverProcessor runMethodResolverProcessor(PsiType[] argTypes, final boolean allVariants) {
final String name = getReferenceName();
if (name == null) {
return null;
}
PsiType thisType = getThisType();
MethodResolverProcessor methodResolver = new MethodResolverProcessor(name, this, false, thisType, argTypes, getTypeArguments(), allVariants);
resolveImpl(methodResolver);
return methodResolver;
}
private PsiType getThisType() {
GrExpression qualifier = getQualifierExpression();
if (qualifier != null) {
PsiType qType = qualifier.getType();
if (qType != null) return qType;
}
return TypesUtil.getJavaLangObject(refExpr);
return TypesUtil.getJavaLangObject(this);
}
@@ -233,6 +233,23 @@ public class TypesUtil {
}
public static boolean isAssignable(PsiType lType, PsiType rType, GroovyPsiElement context, boolean allowConversion) {
if (rType instanceof PsiIntersectionType) {
for (PsiType child : ((PsiIntersectionType)rType).getConjuncts()) {
if (isAssignable(lType, child, context, allowConversion)) {
return true;
}
}
return false;
}
if (lType instanceof PsiIntersectionType) {
for (PsiType child : ((PsiIntersectionType)lType).getConjuncts()) {
if (!isAssignable(child, rType, context, allowConversion)) {
return false;
}
}
return true;
}
if (allowConversion && lType != null && rType != null) {
for (GrTypeConverter converter : GrTypeConverter.EP_NAME.getExtensions()) {
final Boolean result = converter.isConvertible(lType, rType, context);
@@ -267,7 +284,20 @@ public class TypesUtil {
}
public static boolean isAssignableByMethodCallConversion(PsiType lType, PsiType rType, GroovyPsiElement context) {
return isAssignableByMethodCallConversion(lType, rType, context.getManager(), context.getResolveScope());
if (lType == null || rType == null) return false;
if (isAssignableByMethodCallConversion(lType, rType, context.getManager(), context.getResolveScope())) {
return true;
}
for (GrTypeConverter converter : GrTypeConverter.EP_NAME.getExtensions()) {
final Boolean result = converter.isConvertible(lType, rType, context);
if (result != null) {
return result;
}
}
return false;
}
public static boolean isAssignableByMethodCallConversion(PsiType lType, PsiType rType, PsiManager manager, GlobalSearchScope scope) {
@@ -41,9 +41,9 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrRefer
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.MethodResolverProcessor;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author ilyas
@@ -187,21 +187,17 @@ public class GrMethodCallExpressionImpl extends GrCallExpressionImpl implements
}
@NotNull
public GroovyResolveResult[] getMethodVariants() {
public GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument) {
final GrExpression invoked = getInvokedExpression();
if (!(invoked instanceof GrReferenceExpression)) return GroovyResolveResult.EMPTY_ARRAY;
final ArrayList<GroovyResolveResult> res = new ArrayList<GroovyResolveResult>();
if (!(invoked instanceof GrReferenceExpressionImpl)) return GroovyResolveResult.EMPTY_ARRAY;
for (PsiReference ref : invoked.getReferences()) {
if (ref instanceof PsiPolyVariantReference) {
for (ResolveResult result : ((PsiPolyVariantReference)ref).multiResolve(true)) {
if (result instanceof GroovyResolveResult) {
res.add((GroovyResolveResult)result);
}
}
}
final PsiType[] partialArgs = PsiUtil.getArgumentTypes(invoked, false, upToArgument);
final MethodResolverProcessor processor = ((GrReferenceExpressionImpl)invoked).runMethodResolverProcessor(partialArgs, true);
if (processor != null) {
return processor.getCandidates();
}
return res.toArray(new GroovyResolveResult[res.size()]);
return GroovyResolveResult.EMPTY_ARRAY;
}
}
@@ -42,7 +42,7 @@ public class GroovyExpressionPattern<T extends GrExpression, Self extends Groovy
public GroovyMethodCallPattern methodCall(final ElementPattern<? extends PsiMethod> method) {
return new GroovyMethodCallPattern().and(this).with(new PatternCondition<GrCallExpression>("methodCall") {
public boolean accepts(@NotNull GrCallExpression callExpression, ProcessingContext context) {
final GroovyResolveResult[] results = callExpression.getMethodVariants();
final GroovyResolveResult[] results = callExpression.getMethodVariants(null);
for (GroovyResolveResult result : results) {
if (method.getCondition().accepts(result.getElement(), context)) {
return true;
@@ -72,4 +72,4 @@ public class GroovyExpressionPattern<T extends GrExpression, Self extends Groovy
}
}
}
}
@@ -175,6 +175,10 @@ public class PsiUtil {
@Nullable
public static PsiType[] getArgumentTypes(PsiElement place, boolean nullAsBottom) {
return getArgumentTypes(place, nullAsBottom, null);
}
@Nullable
public static PsiType[] getArgumentTypes(PsiElement place, boolean nullAsBottom, @Nullable GrExpression stopAt) {
PsiElement parent = place.getParent();
if (parent instanceof GrCallExpression) {
List<PsiType> result = new ArrayList<PsiType>();
@@ -193,6 +197,9 @@ public class PsiUtil {
} else {
result.add(type);
}
if (stopAt == expression) {
return result.toArray(new PsiType[result.size()]);
}
}
GrClosableBlock[] closures = call.getClosureArguments();
@@ -201,6 +208,9 @@ public class PsiUtil {
if (closureType != null) {
result.add(closureType);
}
if (stopAt == closure) {
break;
}
}
return result.toArray(new PsiType[result.size()]);
@@ -224,6 +234,9 @@ public class PsiUtil {
} else {
result.add(type);
}
if (stopAt == expression) {
break;
}
}
return result.toArray(new PsiType[result.size()]);
@@ -245,6 +258,10 @@ public class PsiUtil {
else {
result.add(argType);
}
if (stopAt == arg) {
break;
}
}
return result.toArray(new PsiType[result.size()]);
} else if (parent instanceof GrConstructorInvocation || parent instanceof GrEnumConstant) {
@@ -264,6 +281,10 @@ public class PsiUtil {
} else {
result.add(type);
}
if (stopAt == expression) {
break;
}
}
return result.toArray(new PsiType[result.size()]);
@@ -603,7 +624,7 @@ public class PsiUtil {
}
public static boolean isRawMethodCall(GrMethodCallExpression call) {
final GroovyResolveResult[] resolveResults = call.getMethodVariants();
final GroovyResolveResult[] resolveResults = call.getMethodVariants(null);
if (resolveResults.length == 0) return false;
final PsiElement element = resolveResults[0].getElement();
if (element instanceof PsiMethod) {
@@ -444,7 +444,7 @@ public class ResolveUtil {
final PsiElement parent = place.getParent();
GroovyResolveResult[] variants = GroovyResolveResult.EMPTY_ARRAY;
if (parent instanceof GrCallExpression) {
variants = ((GrCallExpression) parent).getMethodVariants();
variants = ((GrCallExpression) parent).getMethodVariants(place instanceof GrExpression ? (GrExpression)place : null);
} else if (parent instanceof GrConstructorInvocation) {
final PsiClass clazz = ((GrConstructorInvocation) parent).getDelegatedClass();
if (clazz != null) {
@@ -50,6 +50,7 @@ public class MethodResolverProcessor extends ResolverProcessor {
@Nullable
private final PsiType[] myArgumentTypes;
private final PsiType[] myTypeArguments;
private final boolean myAllVariants;
private final Set<GroovyResolveResult> myInapplicableCandidates = new LinkedHashSet<GroovyResolveResult>();
private final boolean myIsConstructor;
@@ -57,11 +58,15 @@ public class MethodResolverProcessor extends ResolverProcessor {
private boolean myStopExecuting = false;
public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, PsiType thisType, @Nullable PsiType[] argumentTypes, PsiType[] typeArguments) {
this(name, place, isConstructor, thisType, argumentTypes, typeArguments, false);
}
public MethodResolverProcessor(String name, GroovyPsiElement place, boolean isConstructor, PsiType thisType, @Nullable PsiType[] argumentTypes, PsiType[] typeArguments, boolean allVariants) {
super(name, EnumSet.of(ResolveKind.METHOD, ResolveKind.PROPERTY), place, PsiType.EMPTY_ARRAY);
myIsConstructor = isConstructor;
myThisType = thisType;
myArgumentTypes = argumentTypes;
myTypeArguments = typeArguments;
myAllVariants = allVariants;
}
public boolean execute(PsiElement element, ResolveState state) {
@@ -78,7 +83,7 @@ public class MethodResolverProcessor extends ResolverProcessor {
boolean isAccessible = isAccessible(method);
GroovyPsiElement fileResolveContext = state.get(RESOLVE_CONTEXT);
boolean isStaticsOK = isStaticsOK(method, fileResolveContext);
if (PsiUtil.isApplicable(myArgumentTypes, method, substitutor, fileResolveContext instanceof GrMethodCallExpression, (GroovyPsiElement)myPlace) && isStaticsOK) {
if (!myAllVariants && PsiUtil.isApplicable(myArgumentTypes, method, substitutor, fileResolveContext instanceof GrMethodCallExpression, (GroovyPsiElement)myPlace) && isStaticsOK) {
myCandidates.add(new GroovyResolveResultImpl(method, fileResolveContext, substitutor, isAccessible, isStaticsOK));
} else {
myInapplicableCandidates.add(new GroovyResolveResultImpl(method, fileResolveContext, substitutor, isAccessible, isStaticsOK));
@@ -213,6 +218,10 @@ public class MethodResolverProcessor extends ResolverProcessor {
@NotNull
public GroovyResolveResult[] getCandidates() {
if (myAllVariants) {
return myInapplicableCandidates.toArray(new GroovyResolveResult[myInapplicableCandidates.size()]);
}
if (!myCandidates.isEmpty()) {
return filterCandidates();
}
@@ -36,17 +36,17 @@ class GppFunctionalTest extends LightCodeInsightFixtureTestCase {
super.setUp()
}
public void _testCastListToIterable() throws Exception {
public void testCastListToIterable() throws Exception {
myFixture.addClass("class X extends java.util.ArrayList<Integer> {}")
testAssignability """
X ints = [239, 4.2d]
"""
}
public void _testCastListToAnything() throws Exception {
public void testCastListToAnything() throws Exception {
testAssignability """
File f1 = ['path']
File f2 = <warning descr="Cannot assign 'List' to 'File'">['path', 2, true, 42]</warning>
File f2 = <warning descr="Cannot assign 'List<Serializable>' to 'File'">['path', 2, true, 42]</warning>
"""
}
@@ -323,7 +323,7 @@ class BarImpl extends Bar {}
return myFixture.file.findReferenceAt(myFixture.editor.caretModel.offset).resolve()
}
public void _testMethodTypeParameterInference() throws Exception {
public void testMethodTypeParameterInference() throws Exception {
configureScript """
@Typed package aaa
@@ -334,7 +334,7 @@ r.apply { it.intV<caret>i }
assertSameElements myFixture.getLookupElementStrings(), "intValue"
}
public void _testMethodTypeParameterInference2() throws Exception {
public void testMethodTypeParameterInference2() throws Exception {
configureScript """
@Typed package aaa
@@ -385,4 +385,4 @@ class GppProjectDescriptor extends DefaultLightProjectDescriptor {
modifiableModel.addRoot(JarFileSystem.instance.refreshAndFindFileByPath(TestUtils.mockGroovy1_7LibraryName + "!/"), OrderRootType.CLASSES);
modifiableModel.commit();
}
}
}
@@ -1,3 +1,3 @@
def foo(int... i) {}
def list = [1, 2, 3]
foo<warning descr="'foo' in 'SignatureIsNotApplicableToList' cannot be applied to '([java.lang.Integer, java.lang.Integer, java.lang.Integer])'">(list)</warning>
foo<warning descr="'foo' in 'SignatureIsNotApplicableToList' cannot be applied to '([java.lang.Integer, java.lang.Integer,...])'">(list)</warning>