mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[groovy] contribute to implements list while processing @Delegate transformation (simultaneously with contributing to methods)
This commit is contained in:
+6
-59
@@ -51,7 +51,6 @@ import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrGd
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrReflectedMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiManager;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
@@ -59,6 +58,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.statements.typedef.GrTypeDefin
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrScriptField;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.CollectClassMembersUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ast.AstTransformContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
|
||||
import java.util.*;
|
||||
@@ -137,63 +137,15 @@ public class GrClassImplUtil {
|
||||
|
||||
@NotNull
|
||||
public static PsiClassType[] getImplementsListTypes(GrTypeDefinition grType) {
|
||||
Set<PsiClass> visited = new HashSet<PsiClass>();
|
||||
List<PsiClassType> result = new ArrayList<PsiClassType>();
|
||||
getImplementListsInner(grType, result, visited);
|
||||
return result.toArray(new PsiClassType[result.size()]);
|
||||
}
|
||||
|
||||
private static void getImplementListsInner(GrTypeDefinition grType, List<PsiClassType> result, Set<PsiClass> visited) {
|
||||
if (!visited.add(grType)) return;
|
||||
|
||||
final Collection<PsiClassType> result = ContainerUtil.newLinkedHashSet();
|
||||
final PsiClassType[] implementsTypes = getReferenceListTypes(grType.getImplementsClause());
|
||||
List<PsiClassType> fromDelegates = getImplementsFromDelegate(grType, visited);
|
||||
if (fromDelegates != null) {
|
||||
result.addAll(fromDelegates);
|
||||
}
|
||||
final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
|
||||
result.addAll(Arrays.asList(implementsTypes));
|
||||
|
||||
if (!grType.isInterface() &&
|
||||
!ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) &&
|
||||
!ContainerUtil.or(getReferenceListTypes(grType.getExtendsClause()), IS_GROOVY_OBJECT)) {
|
||||
result.addAll(AstTransformContributor.runContributors(grType).getImplementsTypes());
|
||||
if (!grType.isInterface() && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) && !ContainerUtil.or(extendsTypes, IS_GROOVY_OBJECT)) {
|
||||
result.add(getGroovyObjectType(grType));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<PsiClassType> getImplementsFromDelegate(@NotNull final GrTypeDefinition grType, final Set<PsiClass> visited) {
|
||||
return RecursionManager.doPreventingRecursion(grType, true, new Computable<List<PsiClassType>>() {
|
||||
@Override
|
||||
public List<PsiClassType> compute() {
|
||||
List<PsiClassType> result = new ArrayList<PsiClassType>();
|
||||
final GrField[] fields = grType.getCodeFields();
|
||||
for (GrField field : fields) {
|
||||
final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
|
||||
if (delegate == null) continue;
|
||||
|
||||
final boolean shouldImplement = shouldImplementDelegatedInterfaces(delegate);
|
||||
if (!shouldImplement) continue;
|
||||
|
||||
final PsiType type = field.getDeclaredType();
|
||||
if (!(type instanceof PsiClassType)) continue;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) continue;
|
||||
|
||||
if (psiClass instanceof GrTypeDefinition) {
|
||||
getImplementListsInner((GrTypeDefinition)psiClass, result, visited);
|
||||
}
|
||||
else {
|
||||
result.addAll(Arrays.asList(psiClass.getImplementsListTypes()));
|
||||
}
|
||||
if (psiClass.isInterface()) {
|
||||
result.add((PsiClassType)type);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
});
|
||||
return result.toArray(new PsiClassType[result.size()]);
|
||||
}
|
||||
|
||||
public static PsiClassType getGroovyObjectType(@NotNull PsiElement context) {
|
||||
@@ -641,11 +593,6 @@ public class GrClassImplUtil {
|
||||
return PsiClassImplUtil.isClassEquivalentTo(definition, another);
|
||||
}
|
||||
|
||||
private static boolean shouldImplementDelegatedInterfaces(PsiAnnotation delegate) {
|
||||
final Boolean result = GrAnnotationUtil.inferBooleanAttribute(delegate, "interfaces");
|
||||
return result == null || result.booleanValue();
|
||||
}
|
||||
|
||||
public static void addExpandingReflectedMethods(Collection<PsiMethod> result, PsiMethod method) {
|
||||
if (method instanceof GrMethod) {
|
||||
final GrReflectedMethod[] reflectedMethods = ((GrMethod)method).getReflectedMethods();
|
||||
|
||||
+38
-2
@@ -49,12 +49,21 @@ import java.util.*;
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class DelegatedMethodsContributor extends AstTransformContributor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public void collectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
|
||||
public Members collect(@NotNull GrTypeDefinition clazz) {
|
||||
final Members result = Members.create();
|
||||
doCollectMethods(clazz, result.getMethods());
|
||||
doCollectImplementsTypes(clazz, result.getImplementsTypes());
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void doCollectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
|
||||
Set<PsiClass> processed = new HashSet<PsiClass>();
|
||||
|
||||
if (!checkForDelegate(clazz)) return;
|
||||
|
||||
|
||||
Map<MethodSignature, PsiMethod> signatures = new THashMap<MethodSignature, PsiMethod>(MethodSignatureUtil.METHOD_PARAMETERS_ERASURE_EQUALITY);
|
||||
initializeSignatures(clazz, PsiSubstitutor.EMPTY, signatures, processed);
|
||||
|
||||
@@ -334,4 +343,31 @@ public class DelegatedMethodsContributor extends AstTransformContributor {
|
||||
|
||||
private static final Set<String> OBJECT_METHODS = ContainerUtil.newHashSet("equals", "hashCode", "getClass", "clone", "toString", "notify", "notifyAll", "wait", "finalize");
|
||||
private static final Set<String> GROOVY_OBJECT_METHODS = ContainerUtil.newHashSet("invokeMethod", "getProperty", "setProperty", "getMetaClass", "setMetaClass");
|
||||
|
||||
private static void doCollectImplementsTypes(GrTypeDefinition grType, Collection<PsiClassType> result) {
|
||||
final GrField[] fields = grType.getCodeFields();
|
||||
for (GrField field : fields) {
|
||||
final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
|
||||
if (delegate == null) continue;
|
||||
|
||||
final boolean shouldImplement = shouldImplementDelegatedInterfaces(delegate);
|
||||
if (!shouldImplement) continue;
|
||||
|
||||
final PsiType type = field.getDeclaredType();
|
||||
if (!(type instanceof PsiClassType)) continue;
|
||||
|
||||
final PsiClass psiClass = ((PsiClassType)type).resolve();
|
||||
if (psiClass == null) continue;
|
||||
|
||||
result.addAll(Arrays.asList(psiClass.getImplementsListTypes()));
|
||||
if (psiClass.isInterface()) {
|
||||
result.add((PsiClassType)type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean shouldImplementDelegatedInterfaces(PsiAnnotation delegate) {
|
||||
final Boolean result = GrAnnotationUtil.inferBooleanAttribute(delegate, "interfaces");
|
||||
return result == null || result.booleanValue();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user