mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
revive commented g++ tests
This commit is contained in:
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public interface GrCallExpression extends GrExpression, GrCall {
|
||||
PsiMethod resolveMethod();
|
||||
|
||||
@NotNull
|
||||
GroovyResolveResult[] getMethodVariants();
|
||||
GroovyResolveResult[] getMethodVariants(@Nullable GrExpression upToArgument);
|
||||
|
||||
//PsiElement addNamedArgument(GrNamedArgument argument);
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
|
||||
|
||||
+4
@@ -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]));
|
||||
}
|
||||
|
||||
+1
-2
@@ -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);
|
||||
|
||||
+151
-138
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+31
-1
@@ -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) {
|
||||
|
||||
+9
-13
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -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) {
|
||||
|
||||
+10
-1
@@ -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>
|
||||
Reference in New Issue
Block a user