IDEA-73394 (Grails: Completion for named arguments of methods 'findAllWhere', 'findOrSaveWhere', ... in Domain classes)

This commit is contained in:
Sergey Evdokimov
2011-08-23 20:17:55 +04:00
parent b0ecc8023f
commit 71f3dd18f2
3 changed files with 46 additions and 10 deletions
@@ -1,11 +1,14 @@
package org.jetbrains.plugins.groovy.extensions;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiMethod;
import com.intellij.util.xmlb.annotations.AbstractCollection;
import com.intellij.util.xmlb.annotations.Attribute;
import com.intellij.util.xmlb.annotations.Property;
import com.intellij.util.xmlb.annotations.Tag;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall;
import java.util.*;
@@ -41,6 +44,9 @@ public class GroovyMethodDescriptor {
@Attribute("namedArgs")
public String namedArgs;
@Attribute("namedArgsProvider")
public String namedArgsProvider;
@Attribute("namedArgsShowFirst")
public Boolean isNamedArgsShowFirst;
@@ -91,6 +97,8 @@ public class GroovyMethodDescriptor {
return null;
}
assert namedArgsProvider == null;
Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> res =
new HashMap<String, GroovyNamedArgumentProvider.ArgumentDescriptor>();
@@ -148,4 +156,7 @@ public class GroovyMethodDescriptor {
return descriptor;
}
public interface NamedArgumentProvider {
void collectNamedArguments(Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> res, @NotNull GrCall callExpression, @NotNull PsiMethod method);
}
}
@@ -6,6 +6,7 @@ import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiParameterList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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.*;
@@ -23,6 +24,9 @@ public class GroovyMethodInfo {
private Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> myNamedArguments;
private GroovyMethodDescriptor.NamedArgumentProvider myNamedArgProviderInstance;
private String myNamedArgProviderClassName;
public static Map<String, Map<String, List<GroovyMethodInfo>>> getMethodMap() {
Map<String, Map<String, List<GroovyMethodInfo>>> res = MAP;
@@ -97,9 +101,14 @@ public class GroovyMethodInfo {
Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> namedArgumentsMap = method.getArgumentsMap();
if (namedArgumentsMap != null) {
assert info.myNamedArguments == null;
assert !info.isProvideNamedArguments();
info.myNamedArguments = namedArgumentsMap;
}
if (method.namedArgsProvider != null) {
assert !info.isProvideNamedArguments();
info.myNamedArgProviderClassName = method.namedArgsProvider;
}
}
@Nullable
@@ -107,9 +116,26 @@ public class GroovyMethodInfo {
return myReturnType;
}
@Nullable
public Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> getNamedArguments() {
return myNamedArguments;
public void addNamedArguments(Map<String, GroovyNamedArgumentProvider.ArgumentDescriptor> res, @NotNull GrCall call, @NotNull PsiMethod method) {
if (myNamedArguments != null) {
res.putAll(myNamedArguments);
}
else if (myNamedArgProviderClassName != null) {
if (myNamedArgProviderInstance == null) {
try {
myNamedArgProviderInstance = (GroovyMethodDescriptor.NamedArgumentProvider)Class.forName(myNamedArgProviderClassName).newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
myNamedArgProviderInstance.collectNamedArguments(res, call, method);
}
}
public boolean isProvideNamedArguments() {
return myNamedArguments != null || myNamedArgProviderClassName != null;
}
public boolean isApplicable(@NotNull PsiMethod method) {
@@ -90,7 +90,7 @@ public abstract class GroovyNamedArgumentProvider {
if (!method.isConstructor() && !canBeMap(parameters[0])) continue;
collectVariantsFromSimpleDescriptors(namedArguments, method);
collectVariantsFromSimpleDescriptors(namedArguments, call, method);
}
for (GroovyNamedArgumentProvider namedArgumentProvider : EP_NAME.getExtensions()) {
@@ -102,11 +102,10 @@ public abstract class GroovyNamedArgumentProvider {
return namedArguments;
}
private static void collectVariantsFromSimpleDescriptors(Map<String, ArgumentDescriptor> res, PsiMethod method) {
private static void collectVariantsFromSimpleDescriptors(Map<String, ArgumentDescriptor> res, @NotNull GrCall call, @NotNull PsiMethod method) {
for (GroovyMethodInfo methodInfo : GroovyMethodInfo.getInfos(method)) {
Map<String, ArgumentDescriptor> namedArguments = methodInfo.getNamedArguments();
if (namedArguments != null && methodInfo.isApplicable(method)) {
res.putAll(namedArguments);
if (methodInfo.isProvideNamedArguments() && methodInfo.isApplicable(method)) {
methodInfo.addNamedArguments(res, call, method);
break;
}
}
@@ -253,7 +252,7 @@ public abstract class GroovyNamedArgumentProvider {
}
}
protected static class TypeCondition extends ArgumentDescriptor {
public static class TypeCondition extends ArgumentDescriptor {
private final PsiType myType;
public TypeCondition(PsiType type, PsiElement navigationElement) {