Fix: IDEA-66718 (Domain class property name completion in the addTo*(Map) call argument list)

This commit is contained in:
Sergey Evdokimov
2011-03-21 15:09:34 +03:00
parent bdb57eea2b
commit 7e13bd6f2c
4 changed files with 69 additions and 14 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.plugins.groovy.codeInspection.assignment;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.InheritanceUtil;
@@ -316,16 +317,16 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
if (namedArguments.length == 0) return;
MultiMap<String, String> map = new MultiMapBasedOnSet<String, String>();
MultiMap<String, Condition<PsiType>> map = new MultiMap<String, Condition<PsiType>>();
GroovyResolveResult[] callVariants = call.getCallVariants(null);
for (GroovyResolveResult callVariant : callVariants) {
PsiElement element = callVariant.getElement();
if (element instanceof PsiMethod) {
Map<String, String[]> arguments = GroovyNamedArgumentProvider.getNamedArguments(call, (PsiMethod)element);
Map<String, Condition<PsiType>> arguments = GroovyNamedArgumentProvider.getNamedArguments(call, (PsiMethod)element);
for (Map.Entry<String, String[]> entry : arguments.entrySet()) {
map.putValues(entry.getKey(), Arrays.asList(entry.getValue()));
for (Map.Entry<String, Condition<PsiType>> entry : arguments.entrySet()) {
map.putValue(entry.getKey(), entry.getValue());
}
}
}
@@ -333,9 +334,9 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
for (GrNamedArgument namedArgument : namedArguments) {
String labelName = namedArgument.getLabelName();
Collection<String> allowTypes = map.get(labelName);
Collection<Condition<PsiType>> conditions = map.get(labelName);
if (allowTypes.isEmpty()) continue;
if (conditions.isEmpty()) continue;
GrExpression namedArgumentExpression = namedArgument.getExpression();
if (namedArgumentExpression == null) continue;
@@ -349,8 +350,8 @@ public class GroovyAssignabilityCheckInspection extends BaseInspection {
boolean correct = false;
for (String typeName : allowTypes) {
if (InheritanceUtil.isInheritor(expressionType, typeName)) {
for (Condition<PsiType> condition : conditions) {
if (condition.value(expressionType)) {
correct = true;
break;
}
@@ -16,10 +16,15 @@
package org.jetbrains.plugins.groovy.extensions;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.psi.util.InheritanceUtil;
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.statements.expressions.GrCall;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import java.util.HashMap;
import java.util.Map;
@@ -31,10 +36,10 @@ public abstract class GroovyNamedArgumentProvider {
public static final ExtensionPointName<GroovyNamedArgumentProvider> EP_NAME = ExtensionPointName.create("org.intellij.groovy.namedArgumentProvider");
public abstract void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map<String, String[]> result);
public abstract void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map<String, Condition<PsiType>> result);
public static Map<String, String[]> getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method) {
Map<String, String[]> namedArguments = new HashMap<String, String[]>();
public static Map<String, Condition<PsiType>> getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method) {
Map<String, Condition<PsiType>> namedArguments = new HashMap<String, Condition<PsiType>>();
for (GroovyNamedArgumentProvider namedArgumentProvider : GroovyNamedArgumentProvider.EP_NAME.getExtensions()) {
namedArgumentProvider.getNamedArguments(call, method, namedArguments);
@@ -43,4 +48,50 @@ public abstract class GroovyNamedArgumentProvider {
return namedArguments;
}
protected static class StringTypeCondition implements Condition<PsiType> {
private final String myTypeName;
public StringTypeCondition(String typeName) {
this.myTypeName = typeName;
}
@Override
public boolean value(PsiType psiType) {
return InheritanceUtil.isInheritor(psiType, myTypeName);
}
}
protected static class StringArrayTypeCondition implements Condition<PsiType> {
private final String[] myTypeNames;
public StringArrayTypeCondition(String ... typeNames) {
this.myTypeNames = typeNames;
}
@Override
public boolean value(PsiType psiType) {
for (String typeName : myTypeNames) {
if (InheritanceUtil.isInheritor(psiType, typeName)) {
return true;
}
}
return false;
}
}
protected static class TypeCondition implements Condition<PsiType> {
private final PsiType myType;
private final GroovyPsiElement myContext;
public TypeCondition(PsiType type, GroovyPsiElement context) {
myType = type;
myContext = context;
}
@Override
public boolean value(PsiType psiType) {
return TypesUtil.isAssignable(myType, psiType, myContext);
}
}
}
@@ -15,7 +15,9 @@
*/
package org.jetbrains.plugins.groovy.lang;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiType;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,10 +32,10 @@ import java.util.Map;
*/
public class GroovySourceCodeNamedArgumentProvider extends GroovyNamedArgumentProvider {
@Override
public void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map<String, String[]> result) {
public void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map<String, Condition<PsiType>> result) {
if (method instanceof GrMethod) {
for (String parameter : ((GrMethod)method).getNamedParametersArray()) {
result.put(parameter, ArrayUtil.EMPTY_STRING_ARRAY);
result.put(parameter, Condition.TRUE);
}
}
}
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.util.Condition;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.InitialPatternCondition;
import com.intellij.patterns.StandardPatterns;
@@ -146,7 +147,7 @@ class MapArgumentCompletionProvider extends CompletionProvider<CompletionParamet
addPropertiesForClass(result, usedClasses, usedNames, containingClass, call);
}
Map<String, String[]> namedArguments = GroovyNamedArgumentProvider.getNamedArguments(call, method);
Map<String, Condition<PsiType>> namedArguments = GroovyNamedArgumentProvider.getNamedArguments(call, method);
for (String namedArgumentName : namedArguments.keySet()) {
if (!usedNames.contains(namedArgumentName)) {