diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 221ac8b7412..8af2db70ae7 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -515,6 +515,7 @@
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt
index eed12d6c5af..761907d03fa 100644
--- a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinAnnotatedElementsSearcher.kt
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.idea.stubindex.JetAnnotationsIndex
import org.jetbrains.kotlin.idea.util.application.runReadAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
-import org.jetbrains.kotlin.psi.psiUtil.getChildrenOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -43,47 +42,54 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
public class KotlinAnnotatedElementsSearcher : QueryExecutor {
override fun execute(p: AnnotatedElementsSearch.Parameters, consumer: Processor): Boolean {
- val annClass = p.getAnnotationClass()
- assert(annClass.isAnnotationType(), "Annotation type should be passed to annotated members search")
-
- val annotationFQN = annClass.getQualifiedName()
- assert(annotationFQN != null)
-
- val useScope = p.getScope()
-
- for (elt in getJetAnnotationCandidates(annClass, useScope)) {
- if (notJetAnnotationEntry(elt)) continue
-
- val result = runReadAction(fun(): Boolean {
- val parentOfType = elt.getStrictParentOfType() ?: return true
-
- val annotationEntry = elt as JetAnnotationEntry
-
- val context = annotationEntry.analyze(BodyResolveMode.PARTIAL)
- val annotationDescriptor = context.get(BindingContext.ANNOTATION, annotationEntry) ?: return true
-
- val descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor() ?: return true
- if (!(DescriptorUtils.getFqName(descriptor).asString() == annotationFQN)) return true
-
- if (parentOfType is JetClass) {
- val lightClass = LightClassUtil.getPsiClass(parentOfType as JetClass?)
- if (!consumer.process(lightClass)) return false
+ return processAnnotatedMembers(p.annotationClass, p.scope) { declaration ->
+ when (declaration) {
+ is JetClass -> {
+ val lightClass = LightClassUtil.getPsiClass(declaration)
+ consumer.process(lightClass)
}
- else if (parentOfType is JetNamedFunction || parentOfType is JetSecondaryConstructor) {
- val wrappedMethod = LightClassUtil.getLightClassMethod(parentOfType as JetFunction)
- if (!consumer.process(wrappedMethod)) return false
+ is JetNamedFunction, is JetSecondaryConstructor -> {
+ val wrappedMethod = LightClassUtil.getLightClassMethod(declaration as JetFunction)
+ consumer.process(wrappedMethod)
}
- return true
- })
- if (!result) return false
+ else -> true
+ }
}
-
- return true
}
companion object {
private val LOG = Logger.getInstance("#com.intellij.psi.impl.search.AnnotatedMembersSearcher")
+ public fun processAnnotatedMembers(annClass: PsiClass, useScope: SearchScope, consumer: (JetDeclaration) -> Boolean): Boolean {
+ assert(annClass.isAnnotationType(), "Annotation type should be passed to annotated members search")
+
+ val annotationFQN = annClass.getQualifiedName()
+ assert(annotationFQN != null)
+
+ for (elt in getJetAnnotationCandidates(annClass, useScope)) {
+ if (notJetAnnotationEntry(elt)) continue
+
+ val result = runReadAction(fun(): Boolean {
+ val declaration = elt.getStrictParentOfType() ?: return true
+
+ val annotationEntry = elt as JetAnnotationEntry
+
+ val context = annotationEntry.analyze(BodyResolveMode.PARTIAL)
+ val annotationDescriptor = context.get(BindingContext.ANNOTATION, annotationEntry) ?: return true
+
+ val descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor() ?: return true
+ if (!(DescriptorUtils.getFqName(descriptor).asString() == annotationFQN)) return true
+
+ if (!consumer(declaration)) return false
+
+ return true
+ })
+ if (!result) return false
+ }
+
+ return true
+ }
+
/* Return all elements annotated with given annotation name. Aliases don't work now. */
private fun getJetAnnotationCandidates(annClass: PsiClass, useScope: SearchScope): Collection {
return runReadAction(fun(): Collection {
diff --git a/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinClassesWithAnnotatedMembersSearcher.kt b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinClassesWithAnnotatedMembersSearcher.kt
new file mode 100644
index 00000000000..d4c59cdf245
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/search/ideaExtensions/KotlinClassesWithAnnotatedMembersSearcher.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2010-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 org.jetbrains.kotlin.idea.search.ideaExtensions
+
+import com.intellij.psi.PsiClass
+import com.intellij.psi.search.GlobalSearchScope
+import com.intellij.psi.search.searches.ClassesWithAnnotatedMembersSearch
+import com.intellij.psi.search.searches.ScopedQueryExecutor
+import com.intellij.util.Processor
+import org.jetbrains.kotlin.asJava.LightClassUtil
+import org.jetbrains.kotlin.idea.JetFileType
+import org.jetbrains.kotlin.idea.search.allScope
+import org.jetbrains.kotlin.psi.JetClassOrObject
+import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
+
+class KotlinClassesWithAnnotatedMembersSearcher : ScopedQueryExecutor {
+ override fun getScope(param: ClassesWithAnnotatedMembersSearch.Parameters): GlobalSearchScope {
+ return GlobalSearchScope.getScopeRestrictedByFileTypes(param.annotationClass.project.allScope(), JetFileType.INSTANCE)
+ }
+
+ override fun execute(queryParameters: ClassesWithAnnotatedMembersSearch.Parameters, consumer: Processor): Boolean {
+ val processed = hashSetOf()
+ return KotlinAnnotatedElementsSearcher.processAnnotatedMembers(queryParameters.annotationClass, queryParameters.scope) { declaration ->
+ val jetClass = declaration.getNonStrictParentOfType()
+ if (jetClass != null && processed.add(jetClass)) {
+ val lightClass = LightClassUtil.getPsiClass(jetClass)
+ if (lightClass != null) consumer.process(lightClass) else true
+ }
+ else
+ true
+ }
+ }
+}