CPP-2814 Rearrange descriptors and avoid overriding of host-IDE components - part 2

* (Java)TargetElementUtil converted to evaluator
This commit is contained in:
Anton Makeev
2015-04-23 14:30:51 +02:00
parent 6a3ed85526
commit 96c8dd942c
12 changed files with 283 additions and 140 deletions
@@ -34,52 +34,52 @@ import org.jetbrains.annotations.Nullable;
import java.util.*;
public class TargetElementUtil extends TargetElementUtilBase {
public class TargetElementUtil extends TargetElementEvaluatorEx2 implements TargetElementUtilExtender{
public static final int NEW_AS_CONSTRUCTOR = 0x04;
public static final int THIS_ACCEPTED = 0x10;
public static final int SUPER_ACCEPTED = 0x20;
@Override
public int getAllAccepted() {
return super.getAllAccepted() | NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED;
public int getAdditionalAccepted() {
return NEW_AS_CONSTRUCTOR | THIS_ACCEPTED | SUPER_ACCEPTED;
}
@Override
public int getDefinitionSearchFlags() {
return super.getDefinitionSearchFlags() | THIS_ACCEPTED | SUPER_ACCEPTED;
public int getAdditionalDefinitionSearchFlags() {
return THIS_ACCEPTED | SUPER_ACCEPTED;
}
@Override
public int getReferenceSearchFlags() {
return super.getReferenceSearchFlags() | NEW_AS_CONSTRUCTOR;
public int getAdditionalReferenceSearchFlags() {
return NEW_AS_CONSTRUCTOR;
}
@Nullable
@Override
public PsiElement findTargetElement(@NotNull final Editor editor, final int flags, final int offset) {
final PsiElement element = super.findTargetElement(editor, flags, offset);
if (element instanceof PsiKeyword) {
if (element.getParent() instanceof PsiThisExpression) {
public PsiElement adjustTargetElement(Editor editor, int offset, int flags, @NotNull PsiElement targetElement) {
if (targetElement instanceof PsiKeyword) {
if (targetElement.getParent() instanceof PsiThisExpression) {
if ((flags & THIS_ACCEPTED) == 0) return null;
PsiType type = ((PsiThisExpression)element.getParent()).getType();
PsiType type = ((PsiThisExpression)targetElement.getParent()).getType();
if (!(type instanceof PsiClassType)) return null;
return ((PsiClassType)type).resolve();
}
if (element.getParent() instanceof PsiSuperExpression) {
if (targetElement.getParent() instanceof PsiSuperExpression) {
if ((flags & SUPER_ACCEPTED) == 0) return null;
PsiType type = ((PsiSuperExpression)element.getParent()).getType();
PsiType type = ((PsiSuperExpression)targetElement.getParent()).getType();
if (!(type instanceof PsiClassType)) return null;
return ((PsiClassType)type).resolve();
}
}
return element;
return super.adjustTargetElement(editor, offset, flags, targetElement);
}
@Override
protected boolean isAcceptableReferencedElement(final PsiElement element, final PsiElement referenceOrReferencedElement) {
return super.isAcceptableReferencedElement(element, referenceOrReferencedElement) &&
!isEnumConstantReference(element, referenceOrReferencedElement);
@NotNull
public Answer isAcceptableReferencedElement(@NotNull final PsiElement element, final PsiElement referenceOrReferencedElement) {
if (isEnumConstantReference(element, referenceOrReferencedElement)) return Answer.NO;
return super.isAcceptableReferencedElement(element, referenceOrReferencedElement);
}
private static boolean isEnumConstantReference(final PsiElement element, final PsiElement referenceOrReferencedElement) {
@@ -89,10 +89,19 @@ public class TargetElementUtil extends TargetElementUtilBase {
((PsiMethod)referenceOrReferencedElement).isConstructor();
}
@Override
@Nullable
protected PsiElement getReferenceOrReferencedElement(PsiFile file, Editor editor, int flags, int offset) {
PsiElement refElement = super.getReferenceOrReferencedElement(file, editor, flags, offset);
@Override
public PsiElement getElementByReference(@NotNull PsiReference ref, int flags) {
return null;
}
@Nullable
@Override
public PsiElement adjustReferenceOrReferencedElement(PsiFile file,
Editor editor,
int offset,
int flags,
@Nullable PsiElement refElement) {
PsiReference ref = null;
if (refElement == null) {
ref = TargetElementUtilBase.findReference(editor, offset);
@@ -144,45 +153,37 @@ public class TargetElementUtil extends TargetElementUtilBase {
}
}
}
return refElement;
return super.adjustReferenceOrReferencedElement(file, editor, offset, flags, refElement);
}
@Nullable
@Override
protected PsiElement getNamedElement(final PsiElement element) {
public PsiElement getNamedElement(@NotNull final PsiElement element) {
PsiElement parent = element.getParent();
if (element instanceof PsiIdentifier) {
if (parent instanceof PsiClass && element.equals(((PsiClass)parent).getNameIdentifier())) {
return parent;
}
else if (parent instanceof PsiVariable && element.equals(((PsiVariable)parent).getNameIdentifier())) {
return parent;
}
else if (parent instanceof PsiMethod && element.equals(((PsiMethod)parent).getNameIdentifier())) {
return parent;
}
else if (parent instanceof PsiLabeledStatement && element.equals(((PsiLabeledStatement)parent).getLabelIdentifier())) {
return parent;
}
}
//TODO: Code below this comment is very similar to parent code. We probably need to use "super()" instead, to prevent copy/paste in inheritors
else if ((parent = PsiTreeUtil.getParentOfType(element, PsiNamedElement.class, false)) != null) {
// A bit hacky depends on navigation offset correctly overridden
if (parent.getTextOffset() == element.getTextRange().getStartOffset() && !(parent instanceof XmlAttribute)
&& !(parent instanceof PsiFile && InjectedLanguageManager.getInstance(parent.getProject()).isInjectedFragment((PsiFile)parent))) {
if (parent instanceof PsiClass && element.equals(((PsiClass)parent).getNameIdentifier())
|| parent instanceof PsiVariable && element.equals(((PsiVariable)parent).getNameIdentifier())
|| parent instanceof PsiMethod && element.equals(((PsiMethod)parent).getNameIdentifier())
|| parent instanceof PsiLabeledStatement && element.equals(((PsiLabeledStatement)parent).getLabelIdentifier())) {
return parent;
}
}
return null;
}
public boolean isAcceptableNamedParent(@NotNull PsiElement parent) {
return !(parent instanceof XmlAttribute)
&& !(parent instanceof PsiFile && InjectedLanguageManager.getInstance(parent.getProject()).isInjectedFragment((PsiFile)parent));
}
@Nullable
public static PsiReferenceExpression findReferenceExpression(Editor editor) {
final PsiReference ref = findReference(editor);
final PsiReference ref = TargetElementUtilBase.findReference(editor);
return ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
}
@Nullable
@Override
public PsiElement adjustReference(@NotNull final PsiReference ref) {
final PsiElement parent = ref.getElement().getParent();
@@ -192,7 +193,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
@Nullable
@Override
public PsiElement adjustElement(final Editor editor, final int flags, final PsiElement element, final PsiElement contextElement) {
public PsiElement adjustElement(Editor editor, int flags, @Nullable PsiElement element, @Nullable PsiElement contextElement) {
if (element != null) {
if (element instanceof PsiAnonymousClass) {
return ((PsiAnonymousClass)element).getBaseClassType().resolve();
@@ -212,9 +213,9 @@ public class TargetElementUtil extends TargetElementUtilBase {
return null;
}
@NotNull
@Override
public Collection<PsiElement> getTargetCandidates(final PsiReference reference) {
@Nullable
public Collection<PsiElement> getTargetCandidates(@NotNull PsiReference reference) {
PsiElement parent = reference.getElement().getParent();
if (parent instanceof PsiMethodCallExpression || parent instanceof PsiNewExpression &&
((PsiNewExpression)parent).getArrayDimensions().length == 0 &&
@@ -251,12 +252,13 @@ public class TargetElementUtil extends TargetElementUtilBase {
}
@Override
public PsiElement getGotoDeclarationTarget(final PsiElement element, final PsiElement navElement) {
@Nullable
public PsiElement getGotoDeclarationTarget(@NotNull final PsiElement element, @Nullable final PsiElement navElement) {
if (navElement == element && element instanceof PsiCompiledElement && element instanceof PsiMethod) {
PsiMethod method = (PsiMethod)element;
if (method.isConstructor() && method.getParameterList().getParametersCount() == 0) {
PsiClass aClass = method.getContainingClass();
PsiElement navClass = aClass.getNavigationElement();
PsiElement navClass = aClass == null ? null : aClass.getNavigationElement();
if (aClass != navClass) return navClass;
}
}
@@ -272,7 +274,7 @@ public class TargetElementUtil extends TargetElementUtilBase {
}
@Override
public boolean acceptImplementationForReference(final PsiReference reference, final PsiElement element) {
public boolean acceptImplementationForReference(@Nullable PsiReference reference, @NotNull PsiElement element) {
if (reference instanceof PsiReferenceExpression && element instanceof PsiMember) {
return getMemberClass(reference, element) != null;
}
@@ -317,8 +319,10 @@ public class TargetElementUtil extends TargetElementUtilBase {
});
}
@Override
public SearchScope getSearchScope(Editor editor, PsiElement element) {
@Nullable
public SearchScope getSearchScope(Editor editor, @NotNull PsiElement element) {
final PsiReferenceExpression referenceExpression = editor != null ? findReferenceExpression(editor) : null;
if (referenceExpression != null && element instanceof PsiMethod) {
final PsiClass[] memberClass = getMemberClass(referenceExpression, element);
@@ -20,7 +20,7 @@
*/
package com.intellij.codeInspection.concurrencyAnnotations;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.daemon.impl.quickfix.OrderEntryFix;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.openapi.diagnostic.Logger;
@@ -57,7 +57,7 @@ public class JCiPOrderEntryFix implements IntentionAction {
public boolean isAvailable(@NotNull final Project project, final Editor editor, final PsiFile file) {
if (!(file instanceof PsiJavaFile)) return false;
final PsiReference reference = TargetElementUtil.findReference(editor);
final PsiReference reference = TargetElementUtilBase.findReference(editor);
if (!(reference instanceof PsiJavaCodeReferenceElement)) return false;
if (reference.resolve() != null) return false;
@NonNls final String referenceName = ((PsiJavaCodeReferenceElement)reference).getReferenceName();
@@ -74,7 +74,7 @@ public class JCiPOrderEntryFix implements IntentionAction {
@Override
public void invoke(@NotNull final Project project, final Editor editor, final PsiFile file) throws IncorrectOperationException {
final PsiJavaCodeReferenceElement reference = (PsiJavaCodeReferenceElement)TargetElementUtil.findReference(editor);
final PsiJavaCodeReferenceElement reference = (PsiJavaCodeReferenceElement)TargetElementUtilBase.findReference(editor);
LOG.assertTrue(reference != null);
String jarPath = PathUtil.getJarPathForClass(GuardedBy.class);
final VirtualFile virtualFile = file.getVirtualFile();
@@ -16,7 +16,7 @@
package com.intellij.codeInsight.completion
import com.intellij.codeInsight.CodeInsightSettings
import com.intellij.codeInsight.TargetElementUtil
import com.intellij.codeInsight.TargetElementUtilBase
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl
import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler
import com.intellij.codeInsight.lookup.Lookup
@@ -1107,17 +1107,17 @@ class Foo {
type('x')
assertContains 'x__foo', 'x__goo'
edt {
assert foo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED)
assert foo == TargetElementUtilBase.instance.findTargetElement(myFixture.editor, TargetElementUtilBase.LOOKUP_ITEM_ACCEPTED)
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN)
assert goo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED)
assert goo == TargetElementUtilBase.instance.findTargetElement(myFixture.editor, TargetElementUtilBase.LOOKUP_ITEM_ACCEPTED)
}
type('_')
myFixture.assertPreferredCompletionItems 1, 'x__foo', 'x__goo'
edt {
assert goo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED)
assert goo == TargetElementUtilBase.instance.findTargetElement(myFixture.editor, TargetElementUtilBase.LOOKUP_ITEM_ACCEPTED)
myFixture.performEditorAction(IdeActions.ACTION_EDITOR_MOVE_CARET_UP)
assert foo == TargetElementUtil.instance.findTargetElement(myFixture.editor, TargetElementUtil.LOOKUP_ITEM_ACCEPTED)
assert foo == TargetElementUtilBase.instance.findTargetElement(myFixture.editor, TargetElementUtilBase.LOOKUP_ITEM_ACCEPTED)
}
}
@@ -15,13 +15,77 @@
*/
package com.intellij.codeInsight;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class TargetElementEvaluatorEx2 implements TargetElementEvaluatorEx {
import java.util.Collection;
public abstract class TargetElementEvaluatorEx2 implements TargetElementEvaluator {
@Nullable
public abstract PsiElement getNamedElement(@NotNull PsiElement element);
public PsiElement getNamedElement(@NotNull PsiElement element) {
return null;
}
public abstract boolean isAcceptableReferencedElement(@Nullable PsiElement element, @Nullable PsiElement referenceOrReferencedElement);
public boolean isAcceptableNamedParent(@NotNull PsiElement parent) {
return true;
}
@Nullable
public PsiElement adjustElement(Editor editor, int flags, @Nullable PsiElement element, @Nullable PsiElement contextElement) {
return element;
}
@Nullable
public PsiElement adjustTargetElement(Editor editor, int offset, int flags, @NotNull PsiElement targetElement) {
return targetElement;
}
@Nullable
public PsiElement adjustReferenceOrReferencedElement(PsiFile file,
Editor editor,
int offset,
int flags,
@Nullable PsiElement refElement) {
return refElement;
}
@Nullable
public PsiElement adjustReference(@NotNull PsiReference ref) {
return null;
}
@Nullable
public Collection<PsiElement> getTargetCandidates(@NotNull PsiReference reference) {
return null;
}
@Nullable
public PsiElement getGotoDeclarationTarget(@NotNull final PsiElement element, @Nullable final PsiElement navElement) {
return null;
}
@NotNull
public Answer isAcceptableReferencedElement(@NotNull PsiElement element, @Nullable PsiElement referenceOrReferencedElement) {
return Answer.DEFAULT;
}
public boolean includeSelfInGotoImplementation(@NotNull final PsiElement element) {
return true;
}
public boolean acceptImplementationForReference(@Nullable PsiReference reference, @NotNull PsiElement element) {
return true;
}
@Nullable
public SearchScope getSearchScope(Editor editor, @NotNull PsiElement element) {
return null;
}
public enum Answer { YES, NO, DEFAULT;}
}
@@ -35,8 +35,8 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.actions.EditorActionUtil;
import com.intellij.openapi.editor.ex.util.EditorUtil;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.TextRange;
import com.intellij.pom.Navigatable;
import com.intellij.pom.PomDeclarationSearcher;
@@ -67,21 +67,33 @@ public class TargetElementUtilBase {
}
public int getAllAccepted() {
return REFERENCED_ELEMENT_ACCEPTED | ELEMENT_NAME_ACCEPTED | LOOKUP_ITEM_ACCEPTED;
int result = REFERENCED_ELEMENT_ACCEPTED | ELEMENT_NAME_ACCEPTED | LOOKUP_ITEM_ACCEPTED;
for (TargetElementUtilExtender each : Extensions.getExtensions(TargetElementUtilExtender.EP_NAME)) {
result |= each.getAdditionalAccepted();
}
return result;
}
/**
* Accepts THIS or SUPER but not NEW_AS_CONSTRUCTOR.
*/
public int getDefinitionSearchFlags() {
return getAllAccepted();
int result = getAllAccepted();
for (TargetElementUtilExtender each : Extensions.getExtensions(TargetElementUtilExtender.EP_NAME)) {
result |= each.getAdditionalDefinitionSearchFlags();
}
return result;
}
/**
* Accepts NEW_AS_CONSTRUCTOR but not THIS or SUPER.
*/
public int getReferenceSearchFlags() {
return getAllAccepted();
int result = getAllAccepted();
for (TargetElementUtilExtender each : Extensions.getExtensions(TargetElementUtilExtender.EP_NAME)) {
result |= each.getAdditionalReferenceSearchFlags();
}
return result;
}
@Nullable
@@ -140,30 +152,12 @@ public class TargetElementUtilBase {
private static boolean isIdentifierPart(@Nullable PsiFile file, CharSequence text, int offset) {
if (file != null) {
for (TargetElementEvaluatorEx evaluator : getInstance().getElementEvaluatorsEx(file.getLanguage())) {
if (evaluator instanceof TargetElementEvaluatorEx && ((TargetElementEvaluatorEx)evaluator).isIdentifierPart(file, text, offset)) {
return true;
}
}
TargetElementEvaluatorEx evaluator = getInstance().getElementEvaluatorsEx(file.getLanguage());
if (evaluator != null && evaluator.isIdentifierPart(file, text, offset)) return true;
}
return Character.isJavaIdentifierPart(text.charAt(offset));
}
@Nullable
public static PsiElement findTargetElement(Editor editor, int flags) {
ApplicationManager.getApplication().assertIsDispatchThread();
final PsiElement result = getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset());
if (result != null) {
return result;
}
final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET);
if (offset != null) {
return getInstance().findTargetElement(editor, flags, offset);
}
return result;
}
public static boolean inVirtualSpace(@NotNull Editor editor, int offset) {
if (offset == editor.getCaretModel().getOffset()) {
return EditorUtil.inVirtualSpace(editor, editor.getCaretModel().getLogicalPosition());
@@ -172,8 +166,32 @@ public class TargetElementUtilBase {
return false;
}
@Nullable
public static PsiElement findTargetElement(Editor editor, int flags) {
ApplicationManager.getApplication().assertIsDispatchThread();
final PsiElement result = getInstance().findTargetElement(editor, flags, editor.getCaretModel().getOffset());
if (result != null) return result;
final Integer offset = editor.getUserData(EditorActionUtil.EXPECTED_CARET_OFFSET);
if (offset != null) {
return getInstance().findTargetElement(editor, flags, offset);
}
return null;
}
@Nullable
public PsiElement findTargetElement(@NotNull Editor editor, int flags, int offset) {
PsiElement result = doFindTargetElement(editor, flags, offset);
TargetElementEvaluatorEx2 evaluator = result != null ? getElementEvaluatorsEx2(result.getLanguage()) : null;
if (evaluator != null) {
result = evaluator.adjustTargetElement(editor, offset, flags, result);
}
return result;
}
@Nullable
private PsiElement doFindTargetElement(@NotNull Editor editor, int flags, int offset) {
Project project = editor.getProject();
if (project == null) return null;
@@ -229,25 +247,33 @@ public class TargetElementUtilBase {
}
protected boolean isAcceptableReferencedElement(@Nullable PsiElement element, @Nullable PsiElement referenceOrReferencedElement) {
if (referenceOrReferencedElement != null && referenceOrReferencedElement.isValid()) return true;
if (referenceOrReferencedElement == null || !referenceOrReferencedElement.isValid()) return false;
if (element != null) {
for (TargetElementEvaluatorEx2 evaluator : getElementEvaluatorsEx2(element.getLanguage())) {
if (evaluator.isAcceptableReferencedElement(element, referenceOrReferencedElement)) return true;
}
TargetElementEvaluatorEx2 evaluator = element != null ? getElementEvaluatorsEx2(element.getLanguage()) : null;
if (evaluator != null) {
TargetElementEvaluatorEx2.Answer answer = evaluator.isAcceptableReferencedElement(element, referenceOrReferencedElement);
if (answer == TargetElementEvaluatorEx2.Answer.YES) return true;
if (answer == TargetElementEvaluatorEx2.Answer.NO) return false;
}
return false;
return true;
}
@Nullable
public PsiElement adjustElement(final Editor editor, final int flags, final PsiElement element, final PsiElement contextElement) {
public PsiElement adjustElement(final Editor editor, final int flags, @Nullable PsiElement element, @Nullable PsiElement contextElement) {
PsiElement langElement = element == null ? contextElement : element;
TargetElementEvaluatorEx2 evaluator = langElement != null ? getElementEvaluatorsEx2(langElement.getLanguage()) : null;
if (evaluator != null) {
element = evaluator.adjustElement(editor, flags, element, contextElement);
}
return element;
}
@Nullable
public PsiElement adjustReference(@NotNull PsiReference ref){
return null;
public PsiElement adjustReference(@NotNull PsiReference ref) {
PsiElement element = ref.getElement();
TargetElementEvaluatorEx2 evaluator = element != null ? getElementEvaluatorsEx2(element.getLanguage()) : null;
return evaluator != null ? evaluator.adjustReference(ref) : null;
}
@Nullable
@@ -291,20 +317,22 @@ public class TargetElementUtilBase {
@Nullable
protected PsiElement getNamedElement(@Nullable final PsiElement element) {
private PsiElement getNamedElement(@Nullable final PsiElement element) {
if (element == null) return null;
for (TargetElementEvaluatorEx2 each : getElementEvaluatorsEx2(element.getLanguage())) {
PsiElement result = each.getNamedElement(element);
TargetElementEvaluatorEx2 evaluator = getElementEvaluatorsEx2(element.getLanguage());
if (evaluator != null) {
PsiElement result = evaluator.getNamedElement(element);
if (result != null) return result;
}
PsiElement parent;
if ((parent = PsiTreeUtil.getParentOfType(element, PsiNamedElement.class, false)) != null) {
// A bit hacky depends on navigation offset correctly overridden
assert element != null : "notnull parent?";
if (parent.getTextOffset() == element.getTextRange().getStartOffset()) {
return parent;
if (evaluator == null || evaluator.isAcceptableNamedParent(parent)) {
return parent;
}
}
}
@@ -312,13 +340,25 @@ public class TargetElementUtilBase {
}
@Nullable
protected PsiElement getReferenceOrReferencedElement(PsiFile file, Editor editor, int flags, int offset) {
private PsiElement getReferenceOrReferencedElement(PsiFile file, Editor editor, int flags, int offset) {
PsiElement result = doGetReferenceOrReferencedElement(file, editor, flags, offset);
PsiElement languageElement = file.findElementAt(offset);
Language language = languageElement != null ? languageElement.getLanguage() : file.getLanguage();
TargetElementEvaluatorEx2 evaluator = getElementEvaluatorsEx2(language);
if (evaluator != null) {
result = evaluator.adjustReferenceOrReferencedElement(file, editor, offset, flags, result);
}
return result;
}
@Nullable
private PsiElement doGetReferenceOrReferencedElement(PsiFile file, Editor editor, int flags, int offset) {
PsiReference ref = findReference(editor, offset);
if (ref == null) return null;
final Language language = ref.getElement().getLanguage();
final List<TargetElementEvaluator> evaluators = targetElementEvaluator.allForLanguage(language);
for (TargetElementEvaluator evaluator : evaluators) {
TargetElementEvaluator evaluator = targetElementEvaluator.forLanguage(language);
if (evaluator != null) {
final PsiElement element = evaluator.getElementByReference(ref, flags);
if (element != null) return element;
}
@@ -337,7 +377,14 @@ public class TargetElementUtilBase {
}
@NotNull
public Collection<PsiElement> getTargetCandidates(PsiReference reference) {
public Collection<PsiElement> getTargetCandidates(@NotNull PsiReference reference) {
PsiElement refElement = reference.getElement();
TargetElementEvaluatorEx2 evaluator = refElement != null ? getElementEvaluatorsEx2(refElement.getLanguage()) : null;
if (evaluator != null) {
Collection<PsiElement> candidates = evaluator.getTargetCandidates(reference);
if (candidates != null) return candidates;
}
if (reference instanceof PsiPolyVariantReference) {
final ResolveResult[] results = ((PsiPolyVariantReference)reference).multiResolve(false);
List<PsiElement> navigatableResults = new ArrayList<PsiElement>(results.length);
@@ -359,40 +406,40 @@ public class TargetElementUtilBase {
}
public PsiElement getGotoDeclarationTarget(final PsiElement element, final PsiElement navElement) {
TargetElementEvaluatorEx2 evaluator = element != null ? getElementEvaluatorsEx2(element.getLanguage()) : null;
if (evaluator != null) {
PsiElement result = evaluator.getGotoDeclarationTarget(element, navElement);
if (result != null) return result;
}
return navElement;
}
public boolean includeSelfInGotoImplementation(@NotNull final PsiElement element) {
final TargetElementEvaluator elementEvaluator = targetElementEvaluator.forLanguage(element.getLanguage());
return elementEvaluator == null || elementEvaluator.includeSelfInGotoImplementation(element);
TargetElementEvaluator evaluator = targetElementEvaluator.forLanguage(element.getLanguage());
return evaluator == null || evaluator.includeSelfInGotoImplementation(element);
}
public boolean acceptImplementationForReference(@Nullable PsiReference reference, @Nullable PsiElement element) {
TargetElementEvaluatorEx2 evaluator = element != null ? getElementEvaluatorsEx2(element.getLanguage()) : null;
return evaluator == null || evaluator.acceptImplementationForReference(reference, element);
}
@NotNull
public SearchScope getSearchScope(Editor editor, @NotNull PsiElement element) {
TargetElementEvaluatorEx2 evaluator = getElementEvaluatorsEx2(element.getLanguage());
SearchScope result = evaluator != null ? evaluator.getSearchScope(editor, element) : null;
return result != null ? result : PsiSearchHelper.SERVICE.getInstance(element.getProject()).getUseScope(element);
}
protected final LanguageExtension<TargetElementEvaluator> targetElementEvaluator = new LanguageExtension<TargetElementEvaluator>("com.intellij.targetElementEvaluator");
private Iterable<TargetElementEvaluatorEx> getElementEvaluatorsEx(@NotNull Language language) {
//noinspection unchecked
return ContainerUtil.iterate(targetElementEvaluator.allForLanguage(language), new Condition() {
@Override
public boolean value(Object evaluator) {
return evaluator instanceof TargetElementEvaluatorEx;
}
});
@Nullable
private TargetElementEvaluatorEx getElementEvaluatorsEx(@NotNull Language language) {
TargetElementEvaluator result = targetElementEvaluator.forLanguage(language);
return result instanceof TargetElementEvaluatorEx ? (TargetElementEvaluatorEx)result : null;
}
private Iterable<TargetElementEvaluatorEx2> getElementEvaluatorsEx2(@NotNull Language language) {
//noinspection unchecked
return ContainerUtil.iterate(targetElementEvaluator.allForLanguage(language), new Condition() {
@Override
public boolean value(Object evaluator) {
return evaluator instanceof TargetElementEvaluatorEx2;
}
});
}
public boolean acceptImplementationForReference(PsiReference reference, PsiElement element) {
return true;
}
public SearchScope getSearchScope(Editor editor, PsiElement element) {
return PsiSearchHelper.SERVICE.getInstance(element.getProject()).getUseScope(element);
@Nullable
private TargetElementEvaluatorEx2 getElementEvaluatorsEx2(@NotNull Language language) {
TargetElementEvaluator result = targetElementEvaluator.forLanguage(language);
return result instanceof TargetElementEvaluatorEx2 ? (TargetElementEvaluatorEx2)result : null;
}
}
@@ -0,0 +1,28 @@
/*
* Copyright 2000-2015 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 com.intellij.codeInsight;
import com.intellij.openapi.extensions.ExtensionPointName;
public interface TargetElementUtilExtender {
ExtensionPointName<TargetElementUtilExtender> EP_NAME = ExtensionPointName.create("com.intellij.targetElementUtilExtender");
int getAdditionalAccepted();
int getAdditionalDefinitionSearchFlags();
int getAdditionalReferenceSearchFlags();
}
@@ -720,6 +720,7 @@
<extensionPoint name="templateCompletionProcessor"
interface="com.intellij.codeInsight.template.macro.TemplateCompletionProcessor"/>
<extensionPoint name="targetElementUtilExtender" interface="com.intellij.codeInsight.TargetElementUtilExtender"/>
<extensionPoint name="targetElementEvaluator" beanClass="com.intellij.lang.LanguageExtensionPoint">
<with attribute="implementationClass" implements="com.intellij.codeInsight.TargetElementEvaluator"/>
</extensionPoint>
+1
View File
@@ -15,6 +15,7 @@
<orderEntry type="module" module-name="junit" scope="TEST" />
<orderEntry type="module" module-name="java-indexing-api" />
<orderEntry type="module" module-name="java-psi-impl" />
<orderEntry type="module" module-name="java-impl" />
<orderEntry type="module" module-name="core-impl" />
<orderEntry type="module" module-name="extensions" />
<orderEntry type="module" module-name="annotations" />
@@ -16,7 +16,7 @@
package org.jetbrains.plugins.groovy.lang.psi.impl;
import com.intellij.codeInsight.TargetElementEvaluator;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiMethod;
@@ -35,14 +35,10 @@ import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrRenameableLightEle
/**
* @author Maxim.Medvedev
*/
public class GroovyTargetElementEvaluator implements TargetElementEvaluator {
public class GroovyTargetElementEvaluator extends TargetElementUtil {
public static final Key<Object> NAVIGATION_ELEMENT_IS_NOT_TARGET = Key.create("GroovyTargetElementEvaluator.DONT_FOLLOW_NAVIGATION_ELEMENT");
@Override
public boolean includeSelfInGotoImplementation(@NotNull PsiElement element) {
return true;
}
@Override
public PsiElement getElementByReference(@NotNull PsiReference ref, int flags) {
@@ -15,7 +15,6 @@
*/
package org.jetbrains.idea.maven.dom.references;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
@@ -34,7 +33,7 @@ public class MavenTargetUtil {
public static PsiElement getFindTarget(Editor editor, PsiFile file) {
if (editor == null || file == null) return null;
PsiElement target = TargetElementUtil.findTargetElement(editor, TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
PsiElement target = TargetElementUtilBase.findTargetElement(editor, TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
if (target instanceof MavenPsiElementWrapper) {
return ((MavenPsiElementWrapper)target).getWrappee();
}
@@ -16,7 +16,6 @@
package org.jetbrains.idea.maven.dom;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.TargetElementUtil;
import com.intellij.codeInsight.TargetElementUtilBase;
import com.intellij.codeInsight.documentation.DocumentationManager;
import com.intellij.codeInsight.highlighting.HighlightUsagesHandler;
@@ -353,7 +352,7 @@ public abstract class MavenDomTestCase extends MavenImportingTestCase {
MapDataContext context = new MapDataContext();
context.put(CommonDataKeys.EDITOR, getEditor(f));
context.put(CommonDataKeys.PSI_FILE, getTestPsiFile(f));
context.put(CommonDataKeys.PSI_ELEMENT, TargetElementUtil.findTargetElement(getEditor(f),
context.put(CommonDataKeys.PSI_ELEMENT, TargetElementUtilBase.findTargetElement(getEditor(f),
TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED
| TargetElementUtilBase.ELEMENT_NAME_ACCEPTED));
return context;
+5 -1
View File
@@ -1363,8 +1363,12 @@
<indexPatternBuilder implementation="com.intellij.psi.impl.search.JavaIndexPatternBuilder"/>
<indexPatternBuilder implementation="com.intellij.psi.impl.search.JspIndexPatternBuilder"/>
<applicationService serviceInterface="com.intellij.codeInsight.TargetElementUtilBase"
serviceImplementation="com.intellij.codeInsight.TargetElementUtil"/>
serviceImplementation="com.intellij.codeInsight.TargetElementUtilBase"/>
<targetElementUtilExtender implementation="com.intellij.codeInsight.TargetElementUtil"/>
<targetElementEvaluator language="JAVA" implementationClass="com.intellij.codeInsight.TargetElementUtil"/>
<gotoClassContributor implementation="com.intellij.ide.util.gotoByName.DefaultClassNavigationContributor"/>
<gotoSymbolContributor implementation="com.intellij.ide.util.gotoByName.DefaultSymbolNavigationContributor"/>
<scopeTreeExpander implementation="com.intellij.ide.scopeView.ClassesScopeTreeStructureExpander"/>