mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
generics in closure completion
This commit is contained in:
@@ -1,20 +1,20 @@
|
||||
contributor(ctype: 'org.codehaus.groovy.runtime.DefaultGroovyMethods') {
|
||||
closureInMethod(method: [name: 'eachWithIndex', params: ['T', 'groovy.lang.Closure']], params: [entry: null, i: 'int'])
|
||||
closureInMethod(method: [name: 'inject', params: ['java.lang.Object', 'groovy.lang.Closure']], params: [acc: null, val: null])
|
||||
//closureInMethod(method: [name: 'eachWithIndex', params: ['T', 'groovy.lang.Closure']], params: [entry: null, i: 'int'])
|
||||
closureInMethod(method: [name: 'inject', params: ['java.util.Collection<T>', 'groovy.lang.Closure']], params: [acc: null, val: 'T'])
|
||||
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Collection', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Iterator', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Map', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Collection<T>', 'groovy.lang.Closure']], params: [a: 'T', b: "T"])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Iterator<T>', 'groovy.lang.Closure']], params: [a: 'T', b: 'T'])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Map<K, V>', 'groovy.lang.Closure']], params: [a: 'java.util.Map.Entry<K, V>', b: 'java.util.Map.Entry<K, V>'])
|
||||
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Collection', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Iterator', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Map', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Collection<T>', 'groovy.lang.Closure']], params: [a: 'T'])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Iterator<T>', 'groovy.lang.Closure']], params: [a: 'T'])
|
||||
closureInMethod(method: [name: 'min', params: ['java.util.Map<K, V>', 'groovy.lang.Closure']], params: [a: 'java.util.Map.Entry<K, V>'])
|
||||
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Collection', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Iterator', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Map', 'groovy.lang.Closure']], params: [a: null, b: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Collection<T>', 'groovy.lang.Closure']], params: [a: 'T', b: 'T'])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Iterator<T>', 'groovy.lang.Closure']], params: [a: 'T', b: 'T'])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Map<K, V>', 'groovy.lang.Closure']], params: [a: 'java.util.Map.Entry<K, V>', b: 'java.util.Map.Entry<K, V>'])
|
||||
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Collection', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Iterator', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Map', 'groovy.lang.Closure']], params: [a: null])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Collection<T>', 'groovy.lang.Closure']], params: [a: 'T'])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Iterator<T>', 'groovy.lang.Closure']], params: [a: 'T'])
|
||||
closureInMethod(method: [name: 'max', params: ['java.util.Map<K, V>', 'groovy.lang.Closure']], params: [a: 'java.util.Map.Entry<K, V>'])
|
||||
}
|
||||
|
||||
+8
-1
@@ -25,8 +25,10 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.impl.compiled.ClsMethodImpl;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.params.GrParameter;
|
||||
@@ -52,12 +54,16 @@ public class ClosureTemplateBuilder {
|
||||
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
buffer.append("{");
|
||||
|
||||
List<PsiType> paramTypes = ContainerUtil.newArrayList();
|
||||
for (ClosureParameterInfo parameter : parameters) {
|
||||
final String type = parameter.getType();
|
||||
final String name = parameter.getName();
|
||||
if (type != null) {
|
||||
if (method instanceof ClsMethodImpl) method = ((ClsMethodImpl)method).getSourceMirrorMethod();
|
||||
final PsiType fromText = JavaPsiFacade.getElementFactory(project).createTypeFromText(type, method);
|
||||
final PsiType substituted = TypeConversionUtil.erasure(substitutor.substitute(fromText));
|
||||
paramTypes.add(substituted);
|
||||
buffer.append(substituted.getCanonicalText()).append(" ");
|
||||
}
|
||||
else {
|
||||
@@ -78,12 +84,13 @@ public class ClosureTemplateBuilder {
|
||||
|
||||
final TemplateBuilderImpl builder = new TemplateBuilderImpl(templateClosure);
|
||||
|
||||
int i = 0;
|
||||
for (GrParameter p : templateClosure.getParameters()) {
|
||||
final GrTypeElement typeElement = p.getTypeElementGroovy();
|
||||
final PsiElement nameIdentifier = p.getNameIdentifierGroovy();
|
||||
|
||||
if (typeElement != null) {
|
||||
final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(typeElement.getType())};
|
||||
final TypeConstraint[] typeConstraints = {SupertypeConstraint.create(paramTypes.get(i++))};
|
||||
final ChooseTypeExpression expression = new ChooseTypeExpression(typeConstraints, PsiManager.getInstance(project), nameIdentifier.getResolveScope());
|
||||
builder.replaceElement(typeElement, expression);
|
||||
}
|
||||
|
||||
+8
-1
@@ -58,6 +58,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.SubstitutorComputer;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -288,7 +289,7 @@ public class CompleteReferenceExpression {
|
||||
|
||||
private static void addVariantsWithSameQualifier(PrefixMatcher matcher, PsiElement element,
|
||||
GrReferenceExpression patternExpression,
|
||||
GrExpression patternQualifier,
|
||||
@Nullable GrExpression patternQualifier,
|
||||
Set<String> result) {
|
||||
if (element instanceof GrReferenceExpression && element != patternExpression && !PsiUtil.isLValue((GroovyPsiElement)element)) {
|
||||
final GrReferenceExpression refExpr = (GrReferenceExpression)element;
|
||||
@@ -377,6 +378,7 @@ public class CompleteReferenceExpression {
|
||||
private final boolean myMethodPointerOperator;
|
||||
private final boolean myIsMap;
|
||||
private Set<String> myNonDeclaredVars = new com.intellij.util.containers.HashSet<String>();
|
||||
private final SubstitutorComputer mySubstitutorComputer;
|
||||
|
||||
protected CompleteReferenceProcessor(GrReferenceExpression place, Consumer<LookupElement> consumer, @NotNull PrefixMatcher matcher, CompletionParameters parameters) {
|
||||
super(null, EnumSet.allOf(ResolveKind.class), place, PsiType.EMPTY_ARRAY);
|
||||
@@ -391,6 +393,8 @@ public class CompleteReferenceExpression {
|
||||
myFieldPointerOperator = place.hasAt();
|
||||
myMethodPointerOperator = place.getDotTokenType() == GroovyTokenTypes.mMEMBER_POINTER;
|
||||
myIsMap = isMap(place);
|
||||
final PsiType thisType = GrReferenceResolveUtil.getThisType(place);
|
||||
mySubstitutorComputer = new SubstitutorComputer(thisType, PsiType.EMPTY_ARRAY, PsiType.EMPTY_ARRAY, true, place, place.getParent());
|
||||
}
|
||||
|
||||
private static boolean shouldSkipPackages(GrReferenceExpression place) {
|
||||
@@ -416,6 +420,9 @@ public class CompleteReferenceExpression {
|
||||
|
||||
PsiSubstitutor substitutor = state.get(PsiSubstitutor.KEY);
|
||||
if (substitutor == null) substitutor = PsiSubstitutor.EMPTY;
|
||||
if (element instanceof PsiMethod) {
|
||||
substitutor = mySubstitutorComputer.obtainSubstitutor(substitutor, (PsiMethod)element, state);
|
||||
}
|
||||
|
||||
consume(new GroovyResolveResultImpl(namedElement, resolveContext, spreadState, substitutor, isAccessible, isStaticsOK));
|
||||
}
|
||||
|
||||
+3
-13
@@ -189,7 +189,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
List<GroovyResolveResult> accessorResults = new ArrayList<GroovyResolveResult>();
|
||||
for (String accessorName : accessorNames) {
|
||||
AccessorResolverProcessor accessorResolver =
|
||||
new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, getThisType(), getTypeArguments());
|
||||
new AccessorResolverProcessor(accessorName, name, this, !isLValue, false, GrReferenceResolveUtil.getThisType(this), getTypeArguments());
|
||||
GrReferenceResolveUtil.resolveImpl(accessorResolver, this);
|
||||
final GroovyResolveResult[] candidates = accessorResolver.getCandidates();
|
||||
|
||||
@@ -300,7 +300,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
//search for getters
|
||||
for (String getterName : GroovyPropertyUtils.suggestGettersName(name)) {
|
||||
AccessorResolverProcessor getterResolver =
|
||||
new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, getThisType(), getTypeArguments());
|
||||
new AccessorResolverProcessor(getterName, name, this, true, genericsMatter, GrReferenceResolveUtil.getThisType(this), getTypeArguments());
|
||||
GrReferenceResolveUtil.resolveImpl(getterResolver, this);
|
||||
final GroovyResolveResult[] candidates = getterResolver.getCandidates(); //can be only one candidate
|
||||
if (!allVariants && candidates.length == 1) {
|
||||
@@ -358,7 +358,7 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
argTypes[i] = TypeConversionUtil.erasure(argTypes[i]);
|
||||
}
|
||||
}
|
||||
return new MethodResolverProcessor(name, this, false, getThisType(), argTypes, getTypeArguments(), allVariants, byShape);
|
||||
return new MethodResolverProcessor(name, this, false, GrReferenceResolveUtil.getThisType(this), argTypes, getTypeArguments(), allVariants, byShape);
|
||||
}
|
||||
|
||||
public void accept(GroovyElementVisitor visitor) {
|
||||
@@ -676,16 +676,6 @@ public class GrReferenceExpressionImpl extends GrReferenceElementImpl<GrExpressi
|
||||
}
|
||||
}
|
||||
|
||||
private PsiType getThisType() {
|
||||
GrExpression qualifier = getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
PsiType qType = qualifier.getType();
|
||||
if (qType != null) return qType;
|
||||
}
|
||||
|
||||
return TypesUtil.getJavaLangObject(this);
|
||||
}
|
||||
|
||||
enum Kind {
|
||||
TYPE_OR_PROPERTY,
|
||||
METHOD_OR_PROPERTY,
|
||||
|
||||
+11
@@ -255,4 +255,15 @@ public class GrReferenceResolveUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static PsiType getThisType(GrReferenceExpression ref) {
|
||||
GrExpression qualifier = ref.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
PsiType qType = qualifier.getType();
|
||||
if (qType != null) return qType;
|
||||
}
|
||||
|
||||
return TypesUtil.getJavaLangObject(ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user