mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
move functionality of GrClassEnhancer to NonCodeMembersContributor.
This commit is contained in:
@@ -29,7 +29,6 @@
|
||||
|
||||
<extensionPoints>
|
||||
<extensionPoint name="membersContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor"/>
|
||||
<extensionPoint name="classEnhancer" interface="org.jetbrains.plugins.groovy.lang.resolve.GrClassEnhancer"/>
|
||||
<extensionPoint name="astTransformContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.AstTransformContributor"/>
|
||||
<extensionPoint name="closureMissingMethodContributor" interface="org.jetbrains.plugins.groovy.lang.resolve.ClosureMissingMethodContributor"/>
|
||||
<extensionPoint name="variableEnhancer" interface="org.jetbrains.plugins.groovy.lang.psi.GrVariableEnhancer"/>
|
||||
@@ -70,12 +69,10 @@
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.annotator.intentions.dynamic.DynamicMembersContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.ConstructorAnnotationsProcessor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.GrInheritConstructorContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.GrCollectionTypeMembersProvider"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.LoggingContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.spock.SpockMemberContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.MixinMemberContributor"/>
|
||||
<membersContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.GrClassNonCodeMembersContributor"/>
|
||||
|
||||
<classEnhancer implementation="org.jetbrains.plugins.groovy.lang.resolve.noncode.GrCollectionTypeMembersProvider"/>
|
||||
<classEnhancer implementation="org.jetbrains.plugins.groovy.spock.SpockMemberContributor"/>
|
||||
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.DelegatedMethodsContributor"/>
|
||||
<astTransformContributor implementation="org.jetbrains.plugins.groovy.lang.resolve.ast.AutoExternalizeContributor"/>
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
*/
|
||||
public abstract class GrClassEnhancer {
|
||||
|
||||
private static final ExtensionPointName<GrClassEnhancer> EP_NAME = ExtensionPointName.create("org.intellij.groovy.classEnhancer");
|
||||
|
||||
private static volatile MultiMap<String, GrClassEnhancer> ourEnhancers;
|
||||
|
||||
@NotNull
|
||||
public abstract String getQualifiedName();
|
||||
|
||||
public abstract boolean processDynamicElements(@NotNull PsiType qualifierType,
|
||||
@NotNull PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
GroovyPsiElement place,
|
||||
ResolveState state);
|
||||
|
||||
public static MultiMap<String, GrClassEnhancer> getEnhancers() {
|
||||
MultiMap<String, GrClassEnhancer> res = ourEnhancers;
|
||||
if (ourEnhancers == null) {
|
||||
res = new MultiMap<String, GrClassEnhancer>();
|
||||
|
||||
for (GrClassEnhancer enhancer : EP_NAME.getExtensions()) {
|
||||
res.putValue(enhancer.getQualifiedName(), enhancer);
|
||||
}
|
||||
|
||||
ourEnhancers = res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
-56
@@ -1,56 +0,0 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.util.LightCacheKey;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
*/
|
||||
public class GrClassNonCodeMembersContributor extends NonCodeMembersContributor {
|
||||
|
||||
private static final LightCacheKey<String[]> KEY = LightCacheKey.create();
|
||||
|
||||
@Override
|
||||
public void processDynamicElements(@NotNull final PsiType qualifierType,
|
||||
final PsiScopeProcessor processor,
|
||||
final GroovyPsiElement place,
|
||||
final ResolveState state) {
|
||||
final PsiClass aClass = PsiTypesUtil.getPsiClass(qualifierType);
|
||||
if (aClass == null) return;
|
||||
|
||||
String[] superClassNames = KEY.getCachedValue(aClass);
|
||||
if (superClassNames == null) {
|
||||
Set<PsiClass> superClasses = new HashSet<PsiClass>();
|
||||
superClasses.add(aClass);
|
||||
InheritanceUtil.getSuperClasses(aClass, superClasses, true);
|
||||
|
||||
|
||||
superClassNames = new String[superClasses.size()];
|
||||
int i = 0;
|
||||
for (PsiClass superClass : superClasses) {
|
||||
superClassNames[i++] = superClass.getQualifiedName();
|
||||
}
|
||||
|
||||
superClassNames = KEY.putCachedValue(aClass, superClassNames);
|
||||
}
|
||||
|
||||
final MultiMap<String, GrClassEnhancer> enhancers = GrClassEnhancer.getEnhancers();
|
||||
|
||||
for (String superClassName : superClassNames) {
|
||||
for (GrClassEnhancer enhancer : enhancers.get(superClassName)) {
|
||||
if (!enhancer.processDynamicElements(qualifierType, aClass, processor, place, state)) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+81
-4
@@ -17,14 +17,22 @@
|
||||
package org.jetbrains.plugins.groovy.lang.resolve;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.DelegatingScopeProcessor;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.InheritanceUtil;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.dsl.GroovyDslFileIndex;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.util.LightCacheKey;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author peter
|
||||
@@ -32,11 +40,45 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
public abstract class NonCodeMembersContributor {
|
||||
private static final ExtensionPointName<NonCodeMembersContributor> EP_NAME = ExtensionPointName.create("org.intellij.groovy.membersContributor");
|
||||
|
||||
public abstract void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
private static final LightCacheKey<String[]> KEY = LightCacheKey.create();
|
||||
|
||||
private static volatile MultiMap<String, NonCodeMembersContributor> ourClassSpecifiedContributors;
|
||||
private static NonCodeMembersContributor[] ourAllTypeContributors;
|
||||
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
GroovyPsiElement place,
|
||||
ResolveState state);
|
||||
ResolveState state) {
|
||||
throw new RuntimeException("One of two 'processDynamicElements()' methods must be implemented");
|
||||
}
|
||||
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
GroovyPsiElement place,
|
||||
ResolveState state) {
|
||||
processDynamicElements(qualifierType, processor, place, state);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected String getParentClassName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void ensureInit() {
|
||||
if (ourClassSpecifiedContributors != null) return;
|
||||
|
||||
MultiMap<String, NonCodeMembersContributor> contributorMap = new MultiMap<String, NonCodeMembersContributor>();
|
||||
|
||||
for (final NonCodeMembersContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributorMap.putValue(contributor.getParentClassName(), contributor);
|
||||
}
|
||||
|
||||
Collection<NonCodeMembersContributor> allTypeContributors = contributorMap.remove(null);
|
||||
ourAllTypeContributors = allTypeContributors.toArray(new NonCodeMembersContributor[allTypeContributors.size()]);
|
||||
ourClassSpecifiedContributors = contributorMap;
|
||||
}
|
||||
|
||||
public static boolean runContributors(@NotNull final PsiType qualifierType,
|
||||
PsiScopeProcessor processor,
|
||||
final GroovyPsiElement place,
|
||||
@@ -44,15 +86,50 @@ public abstract class NonCodeMembersContributor {
|
||||
|
||||
MyDelegatingScopeProcessor delegatingProcessor = new MyDelegatingScopeProcessor(processor);
|
||||
|
||||
for (final NonCodeMembersContributor contributor : EP_NAME.getExtensions()) {
|
||||
contributor.processDynamicElements(qualifierType, delegatingProcessor, place, state);
|
||||
ensureInit();
|
||||
|
||||
final PsiClass aClass = PsiTypesUtil.getPsiClass(qualifierType);
|
||||
|
||||
if (aClass != null) {
|
||||
for (String superClassName : getParentClassNames(aClass)) {
|
||||
for (NonCodeMembersContributor enhancer : ourClassSpecifiedContributors.get(superClassName)) {
|
||||
enhancer.processDynamicElements(qualifierType, aClass, delegatingProcessor, place, state);
|
||||
if (!delegatingProcessor.wantMore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (NonCodeMembersContributor contributor : ourAllTypeContributors) {
|
||||
contributor.processDynamicElements(qualifierType, aClass, delegatingProcessor, place, state);
|
||||
if (!delegatingProcessor.wantMore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return GroovyDslFileIndex.processExecutors(qualifierType, place, processor, state);
|
||||
}
|
||||
|
||||
protected static String[] getParentClassNames(PsiClass aClass) {
|
||||
String[] superClassNames = KEY.getCachedValue(aClass);
|
||||
if (superClassNames == null) {
|
||||
Set<PsiClass> superClasses = new HashSet<PsiClass>();
|
||||
superClasses.add(aClass);
|
||||
InheritanceUtil.getSuperClasses(aClass, superClasses, true);
|
||||
|
||||
superClassNames = new String[superClasses.size()];
|
||||
int i = 0;
|
||||
for (PsiClass superClass : superClasses) {
|
||||
superClassNames[i++] = superClass.getQualifiedName();
|
||||
}
|
||||
|
||||
superClassNames = KEY.putCachedValue(aClass, superClassNames);
|
||||
}
|
||||
|
||||
return superClassNames;
|
||||
}
|
||||
|
||||
private static class MyDelegatingScopeProcessor extends DelegatingScopeProcessor {
|
||||
public boolean wantMore = true;
|
||||
|
||||
|
||||
+7
-8
@@ -24,32 +24,31 @@ import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.GrClassEnhancer;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
*/
|
||||
public class GrCollectionTypeMembersProvider extends GrClassEnhancer {
|
||||
public class GrCollectionTypeMembersProvider extends NonCodeMembersContributor {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
public String getParentClassName() {
|
||||
return CommonClassNames.JAVA_UTIL_COLLECTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDynamicElements(final @NotNull PsiType qualifierType,
|
||||
@NotNull PsiClass aClass,
|
||||
public void processDynamicElements(final @NotNull PsiType qualifierType,
|
||||
PsiClass aClass,
|
||||
final PsiScopeProcessor processor,
|
||||
final GroovyPsiElement place,
|
||||
final ResolveState state) {
|
||||
final PsiType collectionType = PsiUtil.extractIterableTypeParameter(qualifierType, true);
|
||||
if (collectionType == null) return true;
|
||||
if (collectionType == null) return;
|
||||
|
||||
final PsiScopeProcessor fieldSearcher = new FieldSearcher(processor, JavaPsiFacade.getInstance(place.getProject()).findClass(CommonClassNames.JAVA_UTIL_COLLECTION, place.getResolveScope()));
|
||||
return ResolveUtil.processAllDeclarations(collectionType, fieldSearcher, state, place);
|
||||
ResolveUtil.processAllDeclarations(collectionType, fieldSearcher, state, place);
|
||||
}
|
||||
|
||||
private static class FieldSearcher implements PsiScopeProcessor, ClassHint, ElementClassHint {
|
||||
|
||||
@@ -8,7 +8,7 @@ import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.GrClassEnhancer;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.NonCodeMembersContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
|
||||
@@ -17,43 +17,40 @@ import java.util.Map;
|
||||
/**
|
||||
* @author Sergey Evdokimov
|
||||
*/
|
||||
public class SpockMemberContributor extends GrClassEnhancer {
|
||||
public class SpockMemberContributor extends NonCodeMembersContributor {
|
||||
|
||||
@Override
|
||||
public boolean processDynamicElements(@NotNull PsiType qualifierType,
|
||||
@NotNull PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
GroovyPsiElement place,
|
||||
ResolveState state) {
|
||||
public void processDynamicElements(@NotNull PsiType qualifierType,
|
||||
PsiClass aClass,
|
||||
PsiScopeProcessor processor,
|
||||
GroovyPsiElement place,
|
||||
ResolveState state) {
|
||||
ClassHint classHint = processor.getHint(ClassHint.KEY);
|
||||
if (classHint != null && !classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) return true;
|
||||
if (classHint != null && !classHint.shouldProcess(ClassHint.ResolveKind.PROPERTY)) return;
|
||||
|
||||
GrMethod method = PsiTreeUtil.getParentOfType(place, GrMethod.class);
|
||||
if (method == null) return true;
|
||||
if (method == null) return;
|
||||
|
||||
if (aClass != method.getContainingClass()) return true;
|
||||
if (aClass != method.getContainingClass()) return;
|
||||
|
||||
Map<String, SpockVariableDescriptor> cachedValue = SpockUtils.getVariableMap(method);
|
||||
|
||||
String nameHint = ResolveUtil.getNameHint(processor);
|
||||
if (nameHint == null) {
|
||||
for (SpockVariableDescriptor spockVar : cachedValue.values()) {
|
||||
if (!processor.execute(spockVar.getVariable(), state)) return false;
|
||||
if (!processor.execute(spockVar.getVariable(), state)) return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SpockVariableDescriptor spockVar = cachedValue.get(nameHint);
|
||||
if (spockVar != null && spockVar.getNavigationElement() != place) {
|
||||
if (!processor.execute(spockVar.getVariable(), state)) return false;
|
||||
if (!processor.execute(spockVar.getVariable(), state)) return;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getQualifiedName() {
|
||||
public String getParentClassName() {
|
||||
return SpockUtils.SPEC_CLASS_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user