KotlinAnnotatedElementsSearcher: J2K
This commit is contained in:
+79
-86
@@ -14,118 +14,111 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.search.ideaExtensions;
|
package org.jetbrains.kotlin.idea.search.ideaExtensions
|
||||||
|
|
||||||
import com.intellij.openapi.application.ApplicationManager;
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.diagnostic.Logger;
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
import com.intellij.openapi.util.Computable;
|
import com.intellij.openapi.util.Computable
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.psi.PsiClass;
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiModifierListOwner
|
||||||
import com.intellij.psi.PsiMethod;
|
import com.intellij.psi.impl.search.AnnotatedElementsSearcher
|
||||||
import com.intellij.psi.PsiModifierListOwner;
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.impl.search.AnnotatedElementsSearcher;
|
import com.intellij.psi.search.SearchScope
|
||||||
import com.intellij.psi.search.GlobalSearchScope;
|
import com.intellij.psi.search.searches.AnnotatedElementsSearch
|
||||||
import com.intellij.psi.search.SearchScope;
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import com.intellij.psi.search.searches.AnnotatedElementsSearch;
|
import com.intellij.psi.util.PsiUtilCore
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.util.Processor
|
||||||
import com.intellij.psi.util.PsiUtilCore;
|
import com.intellij.util.indexing.FileBasedIndex
|
||||||
import com.intellij.util.Processor;
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
import com.intellij.util.indexing.FileBasedIndex;
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil;
|
import org.jetbrains.kotlin.idea.stubindex.JetAnnotationsIndex
|
||||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor;
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage;
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.idea.stubindex.JetAnnotationsIndex;
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.psi.*;
|
import java.util.ArrayList
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils;
|
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
public class KotlinAnnotatedElementsSearcher : AnnotatedElementsSearcher() {
|
||||||
import java.util.Collection;
|
|
||||||
|
|
||||||
public class KotlinAnnotatedElementsSearcher extends AnnotatedElementsSearcher {
|
override fun execute(p: AnnotatedElementsSearch.Parameters, consumer: Processor<PsiModifierListOwner>): Boolean {
|
||||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.AnnotatedMembersSearcher");
|
val annClass = p.getAnnotationClass()
|
||||||
|
assert(annClass.isAnnotationType(), "Annotation type should be passed to annotated members search")
|
||||||
|
|
||||||
@Override
|
val annotationFQN = annClass.getQualifiedName()
|
||||||
public boolean execute(@NotNull AnnotatedElementsSearch.Parameters p, @NotNull final Processor<PsiModifierListOwner> consumer) {
|
assert(annotationFQN != null)
|
||||||
PsiClass annClass = p.getAnnotationClass();
|
|
||||||
assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search";
|
|
||||||
|
|
||||||
final String annotationFQN = annClass.getQualifiedName();
|
val useScope = p.getScope()
|
||||||
assert annotationFQN != null;
|
|
||||||
|
|
||||||
SearchScope useScope = p.getScope();
|
for (elt in getJetAnnotationCandidates(annClass, useScope)) {
|
||||||
|
if (notJetAnnotationEntry(elt)) continue
|
||||||
|
|
||||||
for (final PsiElement elt : getJetAnnotationCandidates(annClass, useScope)) {
|
ApplicationManager.getApplication().runReadAction(object : Runnable {
|
||||||
if (notJetAnnotationEntry(elt)) continue;
|
override fun run() {
|
||||||
|
val parentOfType = PsiTreeUtil.getParentOfType<JetDeclaration>(elt, javaClass<JetDeclaration>()) ?: return
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
val annotationEntry = elt as JetAnnotationEntry
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
JetDeclaration parentOfType = PsiTreeUtil.getParentOfType(elt, JetDeclaration.class);
|
|
||||||
if (parentOfType == null) return;
|
|
||||||
|
|
||||||
JetAnnotationEntry annotationEntry = (JetAnnotationEntry) elt;
|
val context = annotationEntry.analyze(BodyResolveMode.PARTIAL)
|
||||||
|
val annotationDescriptor = context.get<JetAnnotationEntry, AnnotationDescriptor>(BindingContext.ANNOTATION, annotationEntry)
|
||||||
|
if (annotationDescriptor == null) return
|
||||||
|
|
||||||
BindingContext context = ResolvePackage.analyze(annotationEntry, BodyResolveMode.PARTIAL);
|
val descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor()
|
||||||
AnnotationDescriptor annotationDescriptor = context.get(BindingContext.ANNOTATION, annotationEntry);
|
if (descriptor == null) return
|
||||||
if (annotationDescriptor == null) return;
|
if (!(DescriptorUtils.getFqName(descriptor).asString() == annotationFQN)) return
|
||||||
|
|
||||||
ClassifierDescriptor descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor();
|
if (parentOfType is JetClass) {
|
||||||
if (descriptor == null) return;
|
val lightClass = LightClassUtil.getPsiClass(parentOfType as JetClass?)
|
||||||
if (!(DescriptorUtils.getFqName(descriptor).asString().equals(annotationFQN))) return;
|
consumer.process(lightClass)
|
||||||
|
|
||||||
if (parentOfType instanceof JetClass) {
|
|
||||||
PsiClass lightClass = LightClassUtil.getPsiClass((JetClass) parentOfType);
|
|
||||||
consumer.process(lightClass);
|
|
||||||
}
|
}
|
||||||
else if (parentOfType instanceof JetNamedFunction || parentOfType instanceof JetSecondaryConstructor) {
|
else if (parentOfType is JetNamedFunction || parentOfType is JetSecondaryConstructor) {
|
||||||
PsiMethod wrappedMethod = LightClassUtil.getLightClassMethod((JetFunction) parentOfType);
|
val wrappedMethod = LightClassUtil.getLightClassMethod(parentOfType as JetFunction)
|
||||||
consumer.process(wrappedMethod);
|
consumer.process(wrappedMethod)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return all elements annotated with given annotation name. Aliases don't work now. */
|
companion object {
|
||||||
private static Collection<? extends PsiElement> getJetAnnotationCandidates(final PsiClass annClass, final SearchScope useScope) {
|
private val LOG = Logger.getInstance("#com.intellij.psi.impl.search.AnnotatedMembersSearcher")
|
||||||
return ApplicationManager.getApplication().runReadAction(new Computable<Collection<? extends PsiElement>>() {
|
|
||||||
@Override
|
|
||||||
public Collection<? extends PsiElement> compute() {
|
|
||||||
if (useScope instanceof GlobalSearchScope) {
|
|
||||||
Collection<JetAnnotationEntry> annotationEntries =
|
|
||||||
JetAnnotationsIndex.getInstance().get(annClass.getName(), annClass.getProject(), (GlobalSearchScope) useScope);
|
|
||||||
|
|
||||||
// Add annotations 'test' as often used alias when we search Test annotation
|
/* Return all elements annotated with given annotation name. Aliases don't work now. */
|
||||||
if (annClass.getName().equals("Test")) {
|
private fun getJetAnnotationCandidates(annClass: PsiClass, useScope: SearchScope): Collection<PsiElement> {
|
||||||
annotationEntries.addAll(JetAnnotationsIndex.getInstance().get(annClass.getName().toLowerCase(), annClass.getProject(), (GlobalSearchScope) useScope));
|
return ApplicationManager.getApplication().runReadAction(object : Computable<Collection<PsiElement>> {
|
||||||
|
override fun compute(): Collection<PsiElement> {
|
||||||
|
if (useScope is GlobalSearchScope) {
|
||||||
|
val name = annClass.getName() ?: return emptyList()
|
||||||
|
val annotationEntries = JetAnnotationsIndex.getInstance().get(name, annClass.getProject(), useScope)
|
||||||
|
|
||||||
|
// Add annotations 'test' as often used alias when we search Test annotation
|
||||||
|
if (name == "Test") {
|
||||||
|
annotationEntries.addAll(JetAnnotationsIndex.getInstance().get(name.toLowerCase(), annClass.getProject(), useScope))
|
||||||
|
}
|
||||||
|
|
||||||
|
return annotationEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
return annotationEntries;
|
// TODO getJetAnnotationCandidates works only with global search scope
|
||||||
|
return ArrayList()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// TODO getJetAnnotationCandidates works only with global search scope
|
private fun notJetAnnotationEntry(found: PsiElement): Boolean {
|
||||||
return new ArrayList<PsiElement>();
|
if (found is JetAnnotationEntry) return false
|
||||||
|
|
||||||
|
val faultyContainer = PsiUtilCore.getVirtualFile(found)
|
||||||
|
LOG.error("Non annotation in annotations list: $faultyContainer; element:$found")
|
||||||
|
if (faultyContainer != null && faultyContainer.isValid()) {
|
||||||
|
FileBasedIndex.getInstance().requestReindex(faultyContainer)
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean notJetAnnotationEntry(PsiElement found) {
|
return true
|
||||||
if (found instanceof JetAnnotationEntry) return false;
|
|
||||||
|
|
||||||
VirtualFile faultyContainer = PsiUtilCore.getVirtualFile(found);
|
|
||||||
LOG.error("Non annotation in annotations list: " + faultyContainer+"; element:"+found);
|
|
||||||
if (faultyContainer != null && faultyContainer.isValid()) {
|
|
||||||
FileBasedIndex.getInstance().requestReindex(faultyContainer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user