mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
mixin origin info & navigation
This commit is contained in:
@@ -46,6 +46,7 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.PsiImplUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.GrReferenceResolveUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.noncode.MixinMemberContributor;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint;
|
||||
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessor;
|
||||
|
||||
@@ -218,19 +219,7 @@ public class GdkMethodUtil {
|
||||
final GrReferenceExpression qualifier = result.second;
|
||||
final PsiClass mixin = result.third;
|
||||
|
||||
final DelegatingScopeProcessor delegate = new DelegatingScopeProcessor(processor) {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, ResolveState delegateState) {
|
||||
if (element instanceof PsiMethod && isCategoryMethod((PsiMethod)element, subjectType, qualifier, null)) {
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
return processor.execute(GrGdkMethodImpl.createGdkMethod(method, false, generateOriginInfo(method)), delegateState);
|
||||
}
|
||||
else if (element instanceof PsiMethod && ((PsiMethod)element).hasModifierProperty(PsiModifier.PUBLIC)) {
|
||||
super.execute(element, delegateState);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final DelegatingScopeProcessor delegate = new MixinMemberContributor.MixinProcessor(processor, subjectType, qualifier);
|
||||
mixin.processDeclarations(delegate, state, null, place);
|
||||
}
|
||||
}
|
||||
|
||||
+60
-14
@@ -15,10 +15,14 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.resolve.noncode;
|
||||
|
||||
import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.light.LightMethod;
|
||||
import com.intellij.psi.scope.DelegatingScopeProcessor;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationArrayInitializer;
|
||||
@@ -66,26 +70,15 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
|
||||
}
|
||||
}
|
||||
|
||||
final MixinProcessor delegate = new MixinProcessor(processor, qualifierType, place);
|
||||
for (PsiClass mixin : mixins) {
|
||||
if (!mixin.processDeclarations(new DelegatingScopeProcessor(processor) {
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, ResolveState state) {
|
||||
if (element instanceof PsiMethod && GdkMethodUtil.isCategoryMethod((PsiMethod)element, qualifierType, place, state.get(PsiSubstitutor.KEY))) {
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
String originInfo = getOriginInfo(method);
|
||||
return super.execute(GrGdkMethodImpl.createGdkMethod(method, false, originInfo), state);
|
||||
}
|
||||
else {
|
||||
return super.execute(element, state);
|
||||
}
|
||||
}
|
||||
}, state, null, place)) {
|
||||
if (!mixin.processDeclarations(delegate, state, null, place)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getOriginInfo(PsiMethod element) {
|
||||
public static String getOriginInfoForCategory(PsiMethod element) {
|
||||
PsiClass aClass = element.getContainingClass();
|
||||
if (aClass != null && aClass.getName() != null) {
|
||||
return "mixed in from " + aClass.getName();
|
||||
@@ -93,6 +86,10 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
|
||||
return "mixed in";
|
||||
}
|
||||
|
||||
public static String getOriginInfoForMixin(@NotNull PsiType subjectType) {
|
||||
return "mixed in " + subjectType.getPresentableText();
|
||||
}
|
||||
|
||||
private static List<PsiAnnotation> getAllMixins(PsiModifierList modifierList) {
|
||||
final ArrayList<PsiAnnotation> result = new ArrayList<PsiAnnotation>();
|
||||
for (PsiAnnotation annotation : modifierList.getApplicableAnnotations()) {
|
||||
@@ -115,4 +112,53 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class MixinedMethod extends LightMethod implements OriginInfoAwareElement, PsiMirrorElement {
|
||||
private final String myOriginInfo;
|
||||
private final PsiMethod myPrototype;
|
||||
|
||||
public MixinedMethod(@NotNull PsiMethod method, String originInfo) {
|
||||
super(method.getManager(), method, ObjectUtils.assertNotNull(method.getContainingClass()));
|
||||
myOriginInfo = originInfo;
|
||||
myPrototype = method;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getOriginInfo() {
|
||||
return myOriginInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getPrototype() {
|
||||
return myPrototype;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MixinProcessor extends DelegatingScopeProcessor {
|
||||
private final PsiType myType;
|
||||
private final PsiElement myPlace;
|
||||
|
||||
public MixinProcessor(PsiScopeProcessor delegate, @NotNull PsiType qualifierType, @Nullable PsiElement place) {
|
||||
super(delegate);
|
||||
myType = qualifierType;
|
||||
myPlace = place;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiElement element, ResolveState state) {
|
||||
if (element instanceof PsiMethod && GdkMethodUtil.isCategoryMethod((PsiMethod)element, myType, myPlace, state.get(PsiSubstitutor.KEY))) {
|
||||
PsiMethod method = (PsiMethod)element;
|
||||
String originInfo = getOriginInfoForCategory(method);
|
||||
return super.execute(GrGdkMethodImpl.createGdkMethod(method, false, originInfo), state);
|
||||
}
|
||||
else if (element instanceof PsiMethod) {
|
||||
return super.execute(new MixinedMethod((PsiMethod)element, getOriginInfoForMixin(myType)), state);
|
||||
}
|
||||
else {
|
||||
return super.execute(element, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -783,8 +783,7 @@ print new B().f<caret>oo()
|
||||
""")
|
||||
|
||||
def resolved = ref.resolve()
|
||||
assertInstanceOf(resolved, GrMethod)
|
||||
assertTrue(resolved.physical)
|
||||
assertInstanceOf(resolved, PsiMethod)
|
||||
}
|
||||
|
||||
void testTwoMixinsInModifierList() {
|
||||
@@ -812,8 +811,7 @@ class OtherPersonMixin {
|
||||
""")
|
||||
|
||||
def resolved = ref.resolve()
|
||||
assertInstanceOf(resolved, GrMethod)
|
||||
assertTrue(resolved.physical)
|
||||
assertInstanceOf(resolved, PsiMethod)
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user