/plugins/groovy/src/org/jetbrains/plugins/groovy/findUsages/AnnotatedMembersSearcher.java

https://bitbucket.org/nbargnesi/idea · Java · 136 lines · 103 code · 15 blank · 18 comment · 18 complexity · 09428fb5afed3c6f5eb12cb101bdf9fe MD5 · raw file

  1. /*
  2. * Copyright 2000-2009 JetBrains s.r.o.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.jetbrains.plugins.groovy.findUsages;
  17. import com.intellij.openapi.application.AccessToken;
  18. import com.intellij.openapi.application.ApplicationManager;
  19. import com.intellij.openapi.application.ReadAction;
  20. import com.intellij.openapi.util.Computable;
  21. import com.intellij.psi.*;
  22. import com.intellij.psi.impl.search.AnnotatedElementsSearcher;
  23. import com.intellij.psi.search.GlobalSearchScope;
  24. import com.intellij.psi.search.LocalSearchScope;
  25. import com.intellij.psi.search.SearchScope;
  26. import com.intellij.psi.search.searches.AnnotatedElementsSearch;
  27. import com.intellij.psi.stubs.StubIndex;
  28. import com.intellij.util.Processor;
  29. import com.intellij.util.QueryExecutor;
  30. import org.jetbrains.annotations.NotNull;
  31. import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
  32. import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElement;
  33. import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
  34. import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
  35. import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
  36. import org.jetbrains.plugins.groovy.lang.psi.stubs.index.GrAnnotatedMemberIndex;
  37. import java.util.ArrayList;
  38. import java.util.Collection;
  39. import java.util.Collections;
  40. import java.util.List;
  41. /**
  42. * @author ven
  43. */
  44. public class AnnotatedMembersSearcher implements QueryExecutor<PsiModifierListOwner, AnnotatedElementsSearch.Parameters> {
  45. @NotNull
  46. private static List<PsiModifierListOwner> getAnnotatedMemberCandidates(final PsiClass clazz, final GlobalSearchScope scope) {
  47. final String name = clazz.getName();
  48. if (name == null) return Collections.emptyList();
  49. final Collection<PsiElement> members = ApplicationManager.getApplication().runReadAction(new Computable<Collection<PsiElement>>() {
  50. @Override
  51. public Collection<PsiElement> compute() {
  52. return StubIndex.getInstance().get(GrAnnotatedMemberIndex.KEY, name, clazz.getProject(), scope);
  53. }
  54. });
  55. if (members.isEmpty()) {
  56. return Collections.emptyList();
  57. }
  58. final ArrayList<PsiModifierListOwner> result = new ArrayList<PsiModifierListOwner>();
  59. for (PsiElement element : members) {
  60. if (element instanceof GroovyFile) {
  61. element = ((GroovyFile)element).getPackageDefinition();
  62. }
  63. if (element instanceof PsiModifierListOwner) {
  64. result.add((PsiModifierListOwner)element);
  65. }
  66. }
  67. return result;
  68. }
  69. public boolean execute(@NotNull final AnnotatedElementsSearch.Parameters p, @NotNull final Processor<PsiModifierListOwner> consumer) {
  70. final PsiClass annClass = p.getAnnotationClass();
  71. assert annClass.isAnnotationType() : "Annotation type should be passed to annotated members search";
  72. AccessToken token = ReadAction.start();
  73. final String annotationFQN;
  74. try {
  75. annotationFQN = annClass.getQualifiedName();
  76. }
  77. finally {
  78. token.finish();
  79. }
  80. assert annotationFQN != null;
  81. final SearchScope scope = p.getScope();
  82. final List<PsiModifierListOwner> candidates;
  83. if (scope instanceof GlobalSearchScope) {
  84. candidates = getAnnotatedMemberCandidates(annClass, ((GlobalSearchScope)scope));
  85. } else {
  86. candidates = new ArrayList<PsiModifierListOwner>();
  87. for (PsiElement element : ((LocalSearchScope)scope).getScope()) {
  88. if (element instanceof GroovyPsiElement) {
  89. ((GroovyPsiElement)element).accept(new GroovyRecursiveElementVisitor() {
  90. public void visitMethod(GrMethod method) {
  91. candidates.add(method);
  92. }
  93. public void visitField(GrField field) {
  94. candidates.add(field);
  95. }
  96. });
  97. }
  98. }
  99. }
  100. for (PsiModifierListOwner candidate : candidates) {
  101. token = ReadAction.start();
  102. try {
  103. if (!AnnotatedElementsSearcher.isInstanceof(candidate, p.getTypes())) {
  104. continue;
  105. }
  106. PsiModifierList list = candidate.getModifierList();
  107. if (list != null) {
  108. for (PsiAnnotation annotation : list.getAnnotations()) {
  109. if (annotationFQN.equals(annotation.getQualifiedName()) && !consumer.process(candidate)) {
  110. return false;
  111. }
  112. }
  113. }
  114. }
  115. finally {
  116. token.finish();
  117. }
  118. }
  119. return true;
  120. }
  121. }