[groovy] collect contributed class members separately of each other

This commit is contained in:
Daniil Ovchinnikov
2015-08-29 17:03:48 +03:00
parent c23736efa0
commit 5d05780b15
8 changed files with 105 additions and 40 deletions
@@ -123,7 +123,7 @@ public class GrTypeDefinitionMembersCache {
final List<PsiClass> result = ContainerUtil.newArrayList();
final GrTypeDefinitionBody body = myDefinition.getBody();
if (body != null) ContainerUtil.addAll(result, body.getInnerClasses());
result.addAll(AstTransformContributor.runContributors(myDefinition).getClasses());
result.addAll(AstTransformContributor.runContributorsForClasses(myDefinition));
return Result.create(result.toArray(new PsiClass[result.size()]), myTreeChangeTracker);
}
});
@@ -153,7 +153,7 @@ public class GrTypeDefinitionMembersCache {
@Nullable
@Override
public Result<Collection<GrField>> compute() {
return Result.create(AstTransformContributor.runContributors(myDefinition).getFields(), myTreeChangeTracker,
return Result.create(AstTransformContributor.runContributorsForFields(myDefinition), myTreeChangeTracker,
PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
}
});
@@ -167,7 +167,7 @@ public class GrTypeDefinitionMembersCache {
GrClassImplUtil.collectMethodsFromBody(myDefinition, result);
result.addAll(new TraitCollector().collectMethods(result));
for (PsiMethod method : AstTransformContributor.runContributors(myDefinition).getMethods()) {
for (PsiMethod method : AstTransformContributor.runContributorsForMethods(myDefinition)) {
GrClassImplUtil.addExpandingReflectedMethods(result, method);
}
@@ -141,7 +141,7 @@ public class GrClassImplUtil {
final PsiClassType[] implementsTypes = getReferenceListTypes(grType.getImplementsClause());
final PsiClassType[] extendsTypes = getReferenceListTypes(grType.getExtendsClause());
result.addAll(Arrays.asList(implementsTypes));
result.addAll(AstTransformContributor.runContributors(grType).getImplementsTypes());
result.addAll(AstTransformContributor.runContributorsForImplementsTypes(grType));
if (!grType.isInterface() && !ContainerUtil.or(implementsTypes, IS_GROOVY_OBJECT) && !ContainerUtil.or(extendsTypes, IS_GROOVY_OBJECT)) {
result.add(getGroovyObjectType(grType));
}
@@ -18,12 +18,17 @@ package org.jetbrains.plugins.groovy.lang.resolve.ast;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiClassType;
import com.intellij.psi.PsiMethod;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
/**
* @author Max Medvedev
@@ -32,40 +37,71 @@ public abstract class AstTransformContributor {
public static final ExtensionPointName<AstTransformContributor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.astTransformContributor");
@Deprecated
public void collectMethods(@NotNull final GrTypeDefinition clazz, Collection<PsiMethod> collector) {
}
@Deprecated
public void collectFields(@NotNull final GrTypeDefinition clazz, Collection<GrField> collector) {
}
/**
* Subclasses should override this method.
*/
@NotNull
@SuppressWarnings("deprecation")
public Members collect(@NotNull final GrTypeDefinition clazz) {
final Members members = Members.create();
collectMethods(clazz, members.getMethods());
collectFields(clazz, members.getFields());
return members;
public void collectClasses(@NotNull final GrTypeDefinition clazz, Collection<PsiClass> collector) {
}
@NotNull
public static Members runContributors(@NotNull final GrTypeDefinition clazz) {
Members result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Members>() {
public void collectImplementsTypes(GrTypeDefinition clazz, Collection<PsiClassType> collector) {
}
public static Collection<PsiMethod> runContributorsForMethods(final GrTypeDefinition clazz) {
Collection<PsiMethod> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<PsiMethod>>() {
@Override
public Members compute() {
Members members = Members.create();
public Collection<PsiMethod> compute() {
final ArrayList<PsiMethod> result = ContainerUtil.newArrayList();
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
members.addFrom(contributor.collect(clazz));
contributor.collectMethods(clazz, result);
}
return members;
return result;
}
});
return result == null ? Members.EMPTY : result;
return result == null ? Collections.<PsiMethod>emptyList() : result;
}
public static Collection<GrField> runContributorsForFields(final GrTypeDefinition clazz) {
Collection<GrField> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<GrField>>() {
@Override
public Collection<GrField> compute() {
final ArrayList<GrField> result = ContainerUtil.newArrayList();
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
contributor.collectFields(clazz, result);
}
return result;
}
});
return result == null ? Collections.<GrField>emptyList() : result;
}
public static Collection<PsiClass> runContributorsForClasses(final GrTypeDefinition clazz) {
Collection<PsiClass> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<PsiClass>>() {
@Override
public Collection<PsiClass> compute() {
final ArrayList<PsiClass> result = ContainerUtil.newArrayList();
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
contributor.collectClasses(clazz, result);
}
return result;
}
});
return result == null ? Collections.<PsiClass>emptyList() : result;
}
public static Collection<PsiClassType> runContributorsForImplementsTypes(final GrTypeDefinition clazz) {
Collection<PsiClassType> result = RecursionManager.doPreventingRecursion(clazz, true, new Computable<Collection<PsiClassType>>() {
@Override
public Collection<PsiClassType> compute() {
final ArrayList<PsiClassType> result = ContainerUtil.newArrayList();
for (final AstTransformContributor contributor : EP_NAME.getExtensions()) {
contributor.collectImplementsTypes(clazz, result);
}
return result;
}
});
return result == null ? Collections.<PsiClassType>emptyList() : result;
}
}
@@ -50,16 +50,8 @@ import java.util.*;
*/
public class DelegatedMethodsContributor extends AstTransformContributor {
@NotNull
@Override
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) {
public void collectMethods(@NotNull final GrTypeDefinition clazz, @NotNull Collection<PsiMethod> collector) {
Set<PsiClass> processed = new HashSet<PsiClass>();
if (!checkForDelegate(clazz)) return;
@@ -344,7 +336,8 @@ 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) {
@Override
public void collectImplementsTypes(GrTypeDefinition grType, Collection<PsiClassType> result) {
final GrField[] fields = grType.getCodeFields();
for (GrField field : fields) {
final PsiAnnotation delegate = PsiImplUtil.getAnnotation(field, GroovyCommonClassNames.GROOVY_LANG_DELEGATE);
@@ -30,12 +30,23 @@ import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderHelperLightPsiClass;
import java.util.Collection;
public class DefaultBuilderStrategySupport extends BuilderAnnotationContributor {
public static final String DEFAULT_STRATEGY_NAME = "DefaultStrategy";
@NotNull
@Override
public void collectClasses(@NotNull GrTypeDefinition clazz, Collection<PsiClass> collector) {
collector.addAll(collect(clazz).getClasses());
}
@Override
public void collectMethods(@NotNull GrTypeDefinition clazz, Collection<PsiMethod> collector) {
collector.addAll(collect(clazz).getMethods());
}
@NotNull
public Members collect(@NotNull final GrTypeDefinition typeDefinition) {
return new DefaultBuilderStrategyHandler(typeDefinition).doProcess();
}
@@ -18,6 +18,7 @@ package org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
@@ -25,6 +26,8 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
import java.util.Collection;
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.createBuildMethod;
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.createFieldSetter;
@@ -32,8 +35,12 @@ public class ExternalBuilderStrategySupport extends BuilderAnnotationContributor
public static final String EXTERNAL_STRATEGY_NAME = "ExternalStrategy";
@NotNull
@Override
public void collectMethods(@NotNull GrTypeDefinition clazz, Collection<PsiMethod> collector) {
collector.addAll(collect(clazz).getMethods());
}
@NotNull
public Members collect(@NotNull GrTypeDefinition builderClass) {
Pair<PsiAnnotation, GrTypeDefinition> definitionPair = getConstructedClass(builderClass);
if (definitionPair == null) return Members.EMPTY;
@@ -30,6 +30,8 @@ import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderHelperLightPsiClass;
import java.util.Collection;
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.getBuilderClassName;
import static org.jetbrains.plugins.groovy.lang.resolve.ast.builder.strategy.DefaultBuilderStrategySupport.getFieldMethodName;
@@ -39,8 +41,17 @@ public class InitializerBuilderStrategySupport extends BuilderAnnotationContribu
public static final String SET_FQN = "groovy.transform.builder.InitializerStrategy.SET";
public static final String UNSET_FQN = "groovy.transform.builder.InitializerStrategy.UNSET";
@NotNull
@Override
public void collectClasses(@NotNull GrTypeDefinition clazz, Collection<PsiClass> collector) {
collector.addAll(collect(clazz).getClasses());
}
@Override
public void collectMethods(@NotNull GrTypeDefinition clazz, Collection<PsiMethod> collector) {
collector.addAll(collect(clazz).getMethods());
}
@NotNull
public Members collect(@NotNull GrTypeDefinition clazz) {
return new InitializerBuilderStrategyHandler(clazz).doProcess();
}
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiAnnotation;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiModifier;
import com.intellij.psi.impl.light.LightMethodBuilder;
import org.jetbrains.annotations.NotNull;
@@ -29,12 +30,18 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
import org.jetbrains.plugins.groovy.lang.resolve.ast.Members;
import org.jetbrains.plugins.groovy.lang.resolve.ast.builder.BuilderAnnotationContributor;
import java.util.Collection;
public class SimpleBuilderStrategySupport extends BuilderAnnotationContributor {
public static final String SIMPLE_STRATEGY_NAME = "SimpleStrategy";
@NotNull
@Override
public void collectMethods(@NotNull GrTypeDefinition clazz, Collection<PsiMethod> collector) {
collector.addAll(collect(clazz).getMethods());
}
@NotNull
public Members collect(@NotNull GrTypeDefinition typeDefinition) {
final PsiAnnotation annotation = PsiImplUtil.getAnnotation(typeDefinition, BUILDER_FQN);
if (!isApplicable(annotation, SIMPLE_STRATEGY_NAME)) return Members.EMPTY;