groovy dsl for categories and gdk methods

This commit is contained in:
Maxim Medvedev
2010-08-04 16:54:12 +04:00
parent 8eae15b4cd
commit ddd0df0f0b
15 changed files with 203 additions and 276 deletions
@@ -0,0 +1,43 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package standardDsls
import com.intellij.util.Function
import org.jetbrains.plugins.groovy.gpp.GppGdkMethod
/**
* @author Maxim.Medvedev
*/
def gppCategory(def className, def isStatic = false) {
def staticConverter = new Function() {def fun(def m) {new GppGdkMethod(m, true)}};
def nonStaticConverter = new Function() {def fun(def m) {new GppGdkMethod(m, false)}};
category className, isStatic ? staticConverter : nonStaticConverter
}
gppCategory "groovy.util.Conversions"
gppCategory "groovy.util.Files"
gppCategory "groovy.util.Filters"
gppCategory "groovy.util.Iterations"
gppCategory "groovy.util.Mappers"
gppCategory "groovy.util.Sort"
gppCategory "groovy.util.Strings"
gppCategory "groovy.util.With"
gppCategory "groovy.util.concurrent.Atomics"
gppCategory "org.mbte.groovypp.runtime.ArraysMethods"
gppCategory "org.mbte.groovypp.runtime.DefaultGroovyPPMethods"
gppCategory "org.mbte.groovypp.runtime.DefaultGroovyPPStaticMethods", true
@@ -17,44 +17,16 @@
package standardDsls
import com.intellij.psi.PsiParameter
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl
/**
* @author Maxim.Medvedev
*//*
*/
*/
def extension(def className, boolean isStatic = false) {
contributor(context()) {
if (!classType) return;
def categoryClass = findClass(className)
if (!categoryClass) return;
def myPlace = PsiTreeUtil.getParentOfType(place, GroovyPsiElement, false)
if (myPlace == null) return;
categoryClass.methods.each {m ->
def params = m.parameterList.parameters as List<PsiParameter>
if (!params) return;
def targetType = params[0].type
if (!TypesUtil.isAssignableByMethodCallConversion(TypeConversionUtil.erasure(targetType), classType, myPlace)) return;
add new GrGdkMethodImpl(m, isStatic)
}
}
}
extension "org.codehaus.groovy.runtime.DefaultGroovyMethods"
extension "org.codehaus.groovy.runtime.DefaultGroovyStaticMethods", true
extension "org.codehaus.groovy.runtime.DateGroovyMethods"
extension "org.codehaus.groovy.runtime.EncodingGroovyMethods"
extension "org.codehaus.groovy.runtime.SqlGroovyMethods"
extension "org.codehaus.groovy.runtime.SwingGroovyMethods"
extension "org.codehaus.groovy.runtime.XmlGroovyMethods"
category "org.codehaus.groovy.runtime.DefaultGroovyMethods"
category "org.codehaus.groovy.runtime.DefaultGroovyStaticMethods", true
category "org.codehaus.groovy.runtime.DateGroovyMethods"
category "org.codehaus.groovy.runtime.EncodingGroovyMethods"
category "org.codehaus.groovy.runtime.SqlGroovyMethods"
category "org.codehaus.groovy.runtime.SwingGroovyMethods"
category "org.codehaus.groovy.runtime.XmlGroovyMethods"
@@ -22,6 +22,9 @@ contributor([gdslScriptContext]) {
method name: "contributor", params: [contexts: "java.util.Map", body: {}], type: void
method name: "contributor", params: [contexts: "java.lang.Object", body: {}], type: void
method name: "category", params: [categoryClass: "java.lang.String", isStatic:"java.lang.Boolean", body: {}], type: void
method name: "category", params: [categoryClass: "java.lang.String", body: {}], type: void
method name: "supportsVersion", params: [version: "java.lang.String"], type: boolean
// scopes
@@ -54,8 +57,9 @@ contributor([contributorBody]) {
method name: "enclosingClass", type: "com.intellij.psi.PsiClass"
property name: "place", type: "com.intellij.psi.PsiElement"
property name: "classType", type: "com.intellij.psi.PsiType"
property name: "classType", type: "com.intellij.psi.PsiClass"
property name: "psiClass", type: "com.intellij.psi.PsiClass"
property name: "psiType", type: "com.intellij.psi.PsiType"
}
}
-1
View File
@@ -77,7 +77,6 @@
<expectedTypesContributor implementation="org.jetbrains.plugins.groovy.gpp.GppExpectedTypesContributor"/>
<variableEnhancer implementation="org.jetbrains.plugins.groovy.gpp.GppClosureParameterTypeProvider"/>
<classSubstitutor implementation="org.jetbrains.plugins.groovy.gpp.GppClassSubstitutor"/>
<membersContributor implementation="org.jetbrains.plugins.groovy.gpp.GppStdLibSupport"/>
<positionManagerDelegate implementation="org.jetbrains.plugins.groovy.gpp.GppPositionManager"/>
</extensions>
@@ -16,7 +16,7 @@ public class DynamicMembersContributor extends NonCodeMembersContributor {
PsiElement place,
ResolveState state) {
final DynamicManager manager = DynamicManager.getInstance(place.getProject());
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place).keySet()) {
for (String qName : ResolveUtil.getAllSuperTypes(qualifierType, place.getProject()).keySet()) {
for (PsiMethod method : manager.getMethods(qName)) {
if (!ResolveUtil.processElement(processor, method, state)) return;
}
@@ -2,7 +2,6 @@ package org.jetbrains.plugins.groovy.dsl;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.util.IncorrectOperationException;
import groovy.lang.Closure;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.holders.CompoundMembersHolder;
@@ -21,7 +20,6 @@ import java.util.Set;
public class CustomMembersGenerator implements GdslMembersHolderConsumer {
private final Set<Map> myMethods = new HashSet<Map>();
private final Project myProject;
private final String myTypeText;
private final CompoundMembersHolder myDepot = new CompoundMembersHolder();
private final GroovyClassDescriptor myDescriptor;
private final String myQualifiedName;
@@ -29,7 +27,6 @@ public class CustomMembersGenerator implements GdslMembersHolderConsumer {
public CustomMembersGenerator(GroovyClassDescriptor descriptor) {
myDescriptor = descriptor;
myProject = descriptor.getProject();
myTypeText = descriptor.getTypeText();
final PsiType type = descriptor.getPsiType();
if (type instanceof PsiClassType) {
final PsiClass psiClass = ((PsiClassType)type).resolve();
@@ -48,16 +45,12 @@ public class CustomMembersGenerator implements GdslMembersHolderConsumer {
}
@Nullable
public PsiType getClassType() {
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(myProject);
try {
return factory.createTypeFromText(myTypeText, getPlace());
}
catch (IncorrectOperationException e) {
final PsiClass psiClass = getPsiClass();
if (psiClass != null) return factory.createType(psiClass);
}
return null;
public PsiClass getClassType() {
return getPsiClass();
}
public PsiType getPsiType() {
return myDescriptor.getPsiType();
}
@Nullable
@@ -30,7 +30,8 @@ public interface GdslMembersHolderConsumer {
void addMemberHolder(CustomMembersHolder holder);
Project getProject();
PsiElement getPlace();
PsiType getClassType();
PsiClass getClassType();
PsiType getPsiType();
@Nullable
PsiClass getPsiClass();
}
@@ -17,7 +17,6 @@ import com.intellij.openapi.project.Project
public class GroovyDslExecutor {
static final def cats = PsiEnhancerCategory.EP_NAME.extensions.collect { it.class }
final List<Pair<ContextFilter, Closure>> enhancers = []
final List<Pair<Closure>> categoryEnhancers = []
private final String myFileName;
static final String ideaVersion
@@ -59,10 +58,6 @@ public class GroovyDslExecutor {
enhancers << Pair.create(CompositeContextFilter.compose(cts, false), toDo)
}
def addCategoryEnhancer(Closure toDo) {
categoryEnhancers << toDo
}
def processVariants(GroovyClassDescriptor descriptor, consumer, ProcessingContext ctx) {
for (pair in enhancers) {
if (pair.first.isApplicable(descriptor, ctx)) {
@@ -77,18 +72,6 @@ public class GroovyDslExecutor {
}
}
def processCategoryVariants(Project project, consumer) {
for (enhancer in categoryEnhancers) {
Closure f = enhancer.clone()
f.delegate = consumer
f.resolveStrategy = Closure.DELEGATE_FIRST
use(cats) {
f.call()
}
}
}
def String toString() {
return "${super.toString()}; file = $myFileName";
}
@@ -126,8 +126,8 @@ public class GroovyDslScript {
}
private boolean handleDslError(Throwable e) {
LOG.error(e);
if (project.isDisposed() || ApplicationManager.getApplication().isUnitTestMode()) {
LOG.error(e);
return true;
}
GroovyDslFileIndex.invokeDslErrorPopup(e, project, file);
@@ -7,6 +7,19 @@ import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.AnnotatedScope
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ClassScope
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ClosureScope
import org.jetbrains.plugins.groovy.dsl.toplevel.scopes.ScriptScope
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil
import com.intellij.psi.util.CachedValuesManager
import com.intellij.openapi.util.Key
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGdkMethod
import com.intellij.psi.util.CachedValue
import com.intellij.psi.util.CachedValueProvider
import com.intellij.psi.util.CachedValueProvider.Result
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl
import com.intellij.psi.util.PsiModificationTracker
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.psi.PsiMethod
import com.intellij.util.Function
/**
* @author ilyas
@@ -42,8 +55,57 @@ class GdslMetaClassProperties {
}
}
Closure staticContributor = { Closure toDo ->
myExecutor.addCategoryEnhancer toDo
Closure category = {Object[] params ->
if (params.length == 1) {
processCategoryMethods(params[0], new Function() {def fun(def param) {new GrGdkMethodImpl(param, false)}})
}
else if (params.length == 2) {
if (params[1] instanceof Boolean) {
processCategoryMethods(params[0], new Function() {def fun(def param) {new GrGdkMethodImpl(param, params[1])}})
}
else {
processCategoryMethods(params[0], params[1])
}
}
else throw new IllegalArgumentException("Incorrect aruments in method 'category': $params")
}
private def processCategoryMethods (def className, Function<PsiMethod, PsiMethod> converter) {
contributor(context()) {
if (!psiType) return;
def categoryClass = findClass(className)
if (!categoryClass) return;
categoryClass.methods.each {m ->
def params = m.parameterList.parameters
if (!params) return;
def targetType = TypeConversionUtil.erasure(params[0].type)
if (!ResolveUtil.isInheritor(psiType, targetType.getCanonicalText(), project)) return;
add CachedValuesManager.getManager(project).
getCachedValue(m, CategoryMethodProvider.CATEGORY_METHOD, new CategoryMethodProvider(m, converter), false)
}
}
}
static class CategoryMethodProvider implements CachedValueProvider<GrGdkMethod> {
static final Key<CachedValue<GrGdkMethod>> CATEGORY_METHOD = Key.create("category method");
def method
def converter
def CategoryMethodProvider(def method, def converter) {
this.method = method;
this.converter = converter
}
Result<GrGdkMethod> compute() {
return Result.create(
converter.fun(method),
PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT,
ProjectRootManager.getInstance(method.project));
}
}
/**
@@ -38,7 +38,7 @@ public class GantMemberContributor extends NonCodeMembersContributor {
PsiScopeProcessor processor,
PsiElement place,
ResolveState state) {
if (ResolveUtil.isInheritor(qualifierType, "groovy.util.AntBuilder", place)) {
if (ResolveUtil.isInheritor(qualifierType, "groovy.util.AntBuilder", place.getProject())) {
processAntTasks(processor, place, state);
return;
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.plugins.groovy.gpp;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiSubstitutor;
import com.intellij.psi.PsiType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.resolve.DominanceAwareMethod;
/**
* @author Maxim.Medvedev
*/
public class GppGdkMethod extends GrGdkMethodImpl implements DominanceAwareMethod {
public GppGdkMethod(PsiMethod method, final boolean isStatic) {
super(method, isStatic);
}
public boolean isMoreConcreteThan(@NotNull final PsiSubstitutor substitutor,
@NotNull PsiMethod another,
@NotNull PsiSubstitutor anotherSubstitutor,
@NotNull GroovyPsiElement context) {
if (another instanceof GrGdkMethodImpl && another.getName().equals(getName())) {
final PsiParameter[] plusParameters = getParameterList().getParameters();
final PsiParameter[] defParameters = another.getParameterList().getParameters();
final PsiType[] paramTypes = new PsiType[plusParameters.length];
for (int i = 0; i < paramTypes.length; i++) {
paramTypes[i] = eliminateOneMethodInterfaces(plusParameters[i], defParameters, i);
}
final GrClosureSignature gdkSignature = GrClosureSignatureUtil.createSignature(another, anotherSubstitutor);
if (GrClosureSignatureUtil.isSignatureApplicable(gdkSignature, paramTypes, context)) {
return true;
}
}
return false;
}
private static PsiType eliminateOneMethodInterfaces(PsiParameter plusParameter, PsiParameter[] gdkParameters, int i) {
PsiType type = plusParameter.getType();
if (i < gdkParameters.length &&
gdkParameters[i].getType().equalsToText(GrClosableBlock.GROOVY_LANG_CLOSURE) &&
GppClosureParameterTypeProvider.findSingleAbstractMethodSignature(type) != null) {
return gdkParameters[i].getType();
}
return type;
}
}
@@ -1,127 +0,0 @@
package org.jetbrains.plugins.groovy.gpp;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.Key;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.CachedValue;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.NotNullFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrClosureSignature;
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.impl.types.GrClosureSignatureUtil;
import org.jetbrains.plugins.groovy.lang.resolve.DominanceAwareMethod;
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author peter
*/
public class GppStdLibSupport extends NonCodeMembersContributor {
private static final Key<CachedValue<Map<String, List<PsiMethod>>>> CACHED_STDLIB = Key.create("GppStdLib");
private static final String[] STDLIB_CLASSES = {
"groovy.util.Conversions",
"groovy.util.Files", "groovy.util.Filters",
"groovy.util.Iterations", "groovy.util.Mappers",
"groovy.util.Sort", "groovy.util.Strings",
"groovy.util.With",
"groovy.util.concurrent.Atomics",
"org.mbte.groovypp.runtime.ArraysMethods",
"org.mbte.groovypp.runtime.DefaultGroovyPPMethods"};
@Override
public void processDynamicElements(@NotNull PsiType type, PsiScopeProcessor processor, PsiElement place, ResolveState state) {
if (!(type instanceof PsiClassType) && !(type instanceof PsiArrayType)) {
return;
}
if (!GppTypeConverter.hasTypedContext(place)) {
return;
}
final Project project = place.getProject();
final Map<String, List<PsiMethod>> map = CachedValuesManager.getManager(project).getCachedValue(project, CACHED_STDLIB, new CachedValueProvider<Map<String, List<PsiMethod>>>() {
public Result<Map<String, List<PsiMethod>>> compute() {
final GroovyPsiManager manager = GroovyPsiManager.getInstance(project);
final Map<String, List<PsiMethod>> result = new HashMap<String, List<PsiMethod>>();
final NotNullFunction<PsiMethod, PsiMethod> nonStaticConverter = new NotNullFunction<PsiMethod, PsiMethod>() {
@NotNull
public PsiMethod fun(PsiMethod method) {
return new GppGdkMethod(method, false);
}
};
for (String qname : STDLIB_CLASSES) {
manager.addCategoryMethods(qname, result, nonStaticConverter);
}
manager.addCategoryMethods("org.mbte.groovypp.runtime.DefaultGroovyPPStaticMethods", result, new NotNullFunction<PsiMethod, PsiMethod>() {
@NotNull
public PsiMethod fun(PsiMethod method) {
return new GppGdkMethod(method, true);
}
});
return Result.create(result, ProjectRootManager.getInstance(project));
}
}, false);
for (String className : ResolveUtil.getAllSuperTypes(type, place).keySet()) {
final List<PsiMethod> methods = map.get(className);
if (methods != null) {
for (PsiMethod method : methods) {
if (!ResolveUtil.processElement(processor, method, state)) {
return;
}
}
}
}
}
private static class GppGdkMethod extends GrGdkMethodImpl implements DominanceAwareMethod {
public GppGdkMethod(PsiMethod method, final boolean isStatic) {
super(method, isStatic);
}
public boolean isMoreConcreteThan(@NotNull final PsiSubstitutor substitutor,
@NotNull PsiMethod another,
@NotNull PsiSubstitutor anotherSubstitutor,
@NotNull GroovyPsiElement context) {
if (another instanceof GrGdkMethodImpl && another.getName().equals(getName())) {
final PsiParameter[] plusParameters = getParameterList().getParameters();
final PsiParameter[] defParameters = another.getParameterList().getParameters();
final PsiType[] paramTypes = new PsiType[plusParameters.length];
for (int i = 0; i < paramTypes.length; i++) {
paramTypes[i] = eliminateOneMethodInterfaces(plusParameters[i], defParameters, i);
}
final GrClosureSignature gdkSignature = GrClosureSignatureUtil.createSignature(another, anotherSubstitutor);
if (GrClosureSignatureUtil.isSignatureApplicable(gdkSignature, paramTypes, context)) {
return true;
}
}
return false;
}
private static PsiType eliminateOneMethodInterfaces(PsiParameter plusParameter, PsiParameter[] gdkParameters, int i) {
PsiType type = plusParameter.getType();
if (i < gdkParameters.length &&
gdkParameters[i].getType().equalsToText(GrClosableBlock.GROOVY_LANG_CLOSURE) &&
GppClosureParameterTypeProvider.findSingleAbstractMethodSignature(type) != null) {
return gdkParameters[i].getType();
}
return type;
}
}
}
@@ -25,25 +25,16 @@ import com.intellij.openapi.roots.ModuleRootListener;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.Function;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.NotNullFunction;
import com.intellij.util.containers.ConcurrentWeakHashMap;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import com.intellij.util.containers.HashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.dsl.GroovyDslExecutor;
import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.stubs.GroovyShortNamesCache;
import java.util.*;
@@ -54,12 +45,10 @@ import java.util.*;
public class GroovyPsiManager {
private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager");
private final Project myProject;
private Map<String, List<PsiMethod>> myDefaultMethods;
private GrTypeDefinition myArrayClass;
private final ConcurrentWeakHashMap<GroovyPsiElement, PsiType> myCalculatedTypes = new ConcurrentWeakHashMap<GroovyPsiElement, PsiType>();
private volatile boolean myRebuildGdkPending = true;
private final GroovyShortNamesCache myCache;
private final TypeInferenceHelper myTypeInferenceHelper;
@@ -84,7 +73,6 @@ public class GroovyPsiManager {
public void rootsChanged(ModuleRootEvent event) {
dropTypesCache();
myRebuildGdkPending = true;
}
});
}
@@ -98,65 +86,6 @@ public class GroovyPsiManager {
}
public List<PsiMethod> getDefaultMethods(String qName) {
if (myRebuildGdkPending) {
final Map<String, List<PsiMethod>> gdk = buildGDK();
if (myRebuildGdkPending) {
myDefaultMethods = gdk;
myRebuildGdkPending = false;
}
}
List<PsiMethod> methods = myDefaultMethods.get(qName);
if (methods == null) return Collections.emptyList();
return methods;
}
private Map<String, List<PsiMethod>> buildGDK() {
return null; //To change body of created methods use File | Settings | File Templates.
}
public List<PsiMethod> getDefaultMethods(PsiClass psiClass) {
List<PsiMethod> list = new ArrayList<PsiMethod>();
getDefaultMethodsInner(psiClass, new HashSet<PsiClass>(), list);
return list;
}
public void getDefaultMethodsInner(PsiClass psiClass, Set<PsiClass> watched, List<PsiMethod> methods) {
if (watched.contains(psiClass)) return;
watched.add(psiClass);
methods.addAll(getDefaultMethods(psiClass.getQualifiedName()));
for (PsiClass aClass : psiClass.getSupers()) {
getDefaultMethodsInner(aClass, watched, methods);
}
}
public void addCategoryMethods(String fromClass, Map<String, List<PsiMethod>> toMap, NotNullFunction<PsiMethod, PsiMethod> converter) {
PsiClass categoryClass = JavaPsiFacade.getInstance(myProject).findClass(fromClass, GlobalSearchScope.allScope(myProject));
if (categoryClass != null) {
for (PsiMethod method : categoryClass.getMethods()) {
if (method.isConstructor()) continue;
if (!method.hasModifierProperty(PsiModifier.STATIC) || !method.hasModifierProperty(PsiModifier.PUBLIC)) continue;
addDefaultMethod(method, toMap, converter);
}
}
}
private static void addDefaultMethod(PsiMethod method, Map<String, List<PsiMethod>> map, NotNullFunction<PsiMethod, PsiMethod> converter) {
if (!method.hasModifierProperty(PsiModifier.PUBLIC)) return;
PsiParameter[] parameters = method.getParameterList().getParameters();
LOG.assertTrue(parameters.length > 0, method.getName());
PsiType thisType = TypeConversionUtil.erasure(parameters[0].getType());
String thisCanonicalText = thisType.getCanonicalText();
LOG.assertTrue(thisCanonicalText != null);
List<PsiMethod> hisMethods = map.get(thisCanonicalText);
if (hisMethods == null) {
hisMethods = new ArrayList<PsiMethod>();
map.put(thisCanonicalText, hisMethods);
}
hisMethods.add(converter.fun(method));
}
public static GroovyPsiManager getInstance(Project project) {
return ServiceManager.getService(project, GroovyPsiManager.class);
@@ -161,8 +161,7 @@ public class ResolveUtil {
}
public static Map<String, PsiType> getAllSuperTypes(PsiType base, final PsiElement place) {
final Project project = place.getProject();
public static Map<String, PsiType> getAllSuperTypes(PsiType base, final Project project) {
final Map<String, Map<String, PsiType>> cache =
CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider<Map<String, Map<String, PsiType>>>() {
@Override
@@ -184,8 +183,8 @@ public class ResolveUtil {
return result;
}
public static boolean isInheritor(PsiType type, @NotNull String baseClass, PsiElement place) {
return getAllSuperTypes(type, place).keySet().contains(baseClass);
public static boolean isInheritor(PsiType type, @NotNull String baseClass, Project project) {
return getAllSuperTypes(type, project).keySet().contains(baseClass);
}