From 7e13bd6f2c0caf139320e467e48a4eb70d41a084 Mon Sep 17 00:00:00 2001 From: Sergey Evdokimov Date: Mon, 21 Mar 2011 15:08:28 +0300 Subject: [PATCH] Fix: IDEA-66718 (Domain class property name completion in the addTo*(Map) call argument list) --- .../GroovyAssignabilityCheckInspection.java | 17 +++--- .../GroovyNamedArgumentProvider.java | 57 ++++++++++++++++++- ...GroovySourceCodeNamedArgumentProvider.java | 6 +- .../MapArgumentCompletionProvider.java | 3 +- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java index 61c9f6e6ce00..9d5c3138b955 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/codeInspection/assignment/GroovyAssignabilityCheckInspection.java @@ -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 map = new MultiMapBasedOnSet(); + MultiMap> map = new MultiMap>(); GroovyResolveResult[] callVariants = call.getCallVariants(null); for (GroovyResolveResult callVariant : callVariants) { PsiElement element = callVariant.getElement(); if (element instanceof PsiMethod) { - Map arguments = GroovyNamedArgumentProvider.getNamedArguments(call, (PsiMethod)element); + Map> arguments = GroovyNamedArgumentProvider.getNamedArguments(call, (PsiMethod)element); - for (Map.Entry entry : arguments.entrySet()) { - map.putValues(entry.getKey(), Arrays.asList(entry.getValue())); + for (Map.Entry> 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 allowTypes = map.get(labelName); + Collection> 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 condition : conditions) { + if (condition.value(expressionType)) { correct = true; break; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java index 495b226602d7..8efd918823f4 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/extensions/GroovyNamedArgumentProvider.java @@ -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 EP_NAME = ExtensionPointName.create("org.intellij.groovy.namedArgumentProvider"); - public abstract void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map result); + public abstract void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map> result); - public static Map getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method) { - Map namedArguments = new HashMap(); + public static Map> getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method) { + Map> namedArguments = new HashMap>(); 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 { + 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 { + 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 { + 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); + } + } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java index 282de8ab7e0f..faa0467936b1 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/GroovySourceCodeNamedArgumentProvider.java @@ -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 result) { + public void getNamedArguments(@Nullable GrCall call, @NotNull PsiMethod method, Map> result) { if (method instanceof GrMethod) { for (String parameter : ((GrMethod)method).getNamedParametersArray()) { - result.put(parameter, ArrayUtil.EMPTY_STRING_ARRAY); + result.put(parameter, Condition.TRUE); } } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java index 682ed1ce2e51..b412661e52b0 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/MapArgumentCompletionProvider.java @@ -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 namedArguments = GroovyNamedArgumentProvider.getNamedArguments(call, method); + Map> namedArguments = GroovyNamedArgumentProvider.getNamedArguments(call, method); for (String namedArgumentName : namedArguments.keySet()) { if (!usedNames.contains(namedArgumentName)) {