ws
authorMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Wed, 25 Nov 2009 16:51:34 +0000 (19:51 +0300)
committerMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Wed, 25 Nov 2009 16:51:34 +0000 (19:51 +0300)
plugins/IntelliLang/src/org/intellij/plugins/intelliLang/util/AnnotationUtilEx.java

index a1e46807fd75e9cffb433a016667006ae785b0e6..cbb98ac79f8622a3b3419c87ffcbf15e31aa5db8 100644 (file)
-/*\r
- * Copyright 2006 Sascha Weinreuter\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- *     http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-package org.intellij.plugins.intelliLang.util;\r
-\r
-import com.intellij.codeInsight.AnnotationUtil;\r
-import com.intellij.openapi.util.Pair;\r
-import com.intellij.psi.*;\r
-import com.intellij.psi.impl.PsiConstantEvaluationHelperImpl;\r
-import com.intellij.psi.search.searches.SuperMethodsSearch;\r
-import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;\r
-import com.intellij.psi.util.PsiTreeUtil;\r
-import com.intellij.util.Processor;\r
-import org.jetbrains.annotations.NonNls;\r
-import org.jetbrains.annotations.NotNull;\r
-import org.jetbrains.annotations.Nullable;\r
-\r
-import java.util.Arrays;\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-\r
-/**\r
- * Contains some extended utility functions for dealing with annotations.\r
- */\r
-public class AnnotationUtilEx {\r
-  private static final PsiConstantEvaluationHelperImpl CONSTANT_EVALUATION_HELPER = new PsiConstantEvaluationHelperImpl();\r
-\r
-  private AnnotationUtilEx() {\r
-  }\r
-\r
-  /**\r
-   * @see AnnotationUtilEx#getAnnotatedElementFor(com.intellij.psi.PsiElement, LookupType)\r
-   */\r
-  public enum LookupType {\r
-    PREFER_CONTEXT, PREFER_DECLARATION, CONTEXT_ONLY, DECLRARATION_ONLY\r
-  }\r
-\r
-  /**\r
-   * Determines the PsiModifierListOwner for the passed element depending of the specified LookupType. The LookupType\r
-   * decides whether to prefer the element a reference expressions resolves to, or the element that is implied by the\r
-   * usage context ("expected type").\r
-   */\r
-  @Nullable\r
-  public static PsiModifierListOwner getAnnotatedElementFor(@Nullable PsiElement element, LookupType type) {\r
-    while (element != null) {\r
-      if (type == LookupType.PREFER_DECLARATION || type == LookupType.DECLRARATION_ONLY) {\r
-        if (element instanceof PsiReferenceExpression) {\r
-          final PsiElement e = ((PsiReferenceExpression)element).resolve();\r
-          if (e instanceof PsiModifierListOwner) {\r
-            return (PsiModifierListOwner)e;\r
-          }\r
-          if (type == LookupType.DECLRARATION_ONLY) {\r
-            return null;\r
-          }\r
-        }\r
-      }\r
-      element = ContextComputationProcessor.getTopLevelInjectionTarget(element);\r
-      final PsiElement parent = element.getParent();\r
-\r
-      if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)element).getOperationSign().getTokenType() == JavaTokenType.PLUSEQ) {\r
-        element = ((PsiAssignmentExpression)element).getLExpression();\r
-        continue;\r
-      }\r
-      else if (parent instanceof PsiAssignmentExpression) {\r
-        final PsiAssignmentExpression p = (PsiAssignmentExpression)parent;\r
-        if (p.getRExpression() == element) {\r
-          element = p.getLExpression();\r
-          continue;\r
-        }\r
-      }\r
-      else if (parent instanceof PsiReturnStatement) {\r
-        final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);\r
-        if (m != null) {\r
-          return m;\r
-        }\r
-      }\r
-      else if (parent instanceof PsiModifierListOwner) {\r
-        return (PsiModifierListOwner)parent;\r
-      }\r
-      else if (parent instanceof PsiArrayInitializerMemberValue) {\r
-        final PsiArrayInitializerMemberValue value = (PsiArrayInitializerMemberValue)parent;\r
-        final PsiElement pair = value.getParent();\r
-        if (pair instanceof PsiNameValuePair) {\r
-          return getAnnotationMethod((PsiNameValuePair)pair, element);\r
-        }\r
-      }\r
-      else if (parent instanceof PsiNameValuePair) {\r
-        return getAnnotationMethod((PsiNameValuePair)parent, element);\r
-      }\r
-      else {\r
-        return PsiUtilEx.getParameterForArgument(element);\r
-      }\r
-\r
-      // If no annotation has been found through the usage context, check if the element\r
-      // (i.e. the element the reference refers to) is annotated itself\r
-      if (type != LookupType.DECLRARATION_ONLY) {\r
-        if (element instanceof PsiReferenceExpression) {\r
-          final PsiElement e = ((PsiReferenceExpression)element).resolve();\r
-          if (e instanceof PsiModifierListOwner) {\r
-            return (PsiModifierListOwner)e;\r
-          }\r
-        }\r
-      }\r
-      return null;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  @Nullable\r
-  private static PsiModifierListOwner getAnnotationMethod(PsiNameValuePair pair, PsiElement element) {\r
-    final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(pair.getParent(), PsiAnnotation.class);\r
-    assert annotation != null;\r
-\r
-    final String fqn = annotation.getQualifiedName();\r
-    if (fqn == null) return null;\r
-\r
-    final PsiClass psiClass = JavaPsiFacade.getInstance(element.getProject()).findClass(fqn, element.getResolveScope());\r
-    if (psiClass != null && psiClass.isAnnotationType()) {\r
-      final String name = pair.getName();\r
-      final PsiMethod[] methods = psiClass.findMethodsByName(name != null ? name : "value", false);\r
-      return methods.length > 0 ? methods[0] : null;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * Utility method to obtain annotations of a specific type from the supplied PsiModifierListOwner.\r
-   * For optimization reasons, this method only looks at elements of type java.lang.String.\r
-   * <p/>\r
-   * The parameter <code>allowIndirect</code> determines if the method should look for indirect annotations, i.e.\r
-   * annotations which have themselves been annotated by the supplied annotation name. Currently, this only allows\r
-   * one level of indirection and returns an array of [base-annotation, indirect annotation]\r
-   * <p/>\r
-   * The <code>annotationName</code> parameter is a pair of the target annotation class' fully qualified name as a\r
-   * String and as a Set. This is done for performance reasons because the Set is required by the\r
-   * {@link com.intellij.codeInsight.AnnotationUtil} utility class and allows to avoid unecessary object constructions.\r
-   */\r
-  @NotNull\r
-  public static PsiAnnotation[] getAnnotationFrom(PsiModifierListOwner owner,\r
-                                                  Pair<String, ? extends Set<String>> annotationName,\r
-                                                  boolean allowIndirect,\r
-                                                  boolean inHierarchy) {\r
-    if (!PsiUtilEx.isLanguageAnnotationTarget(owner)) return PsiAnnotation.EMPTY_ARRAY;\r
-\r
-    final PsiAnnotation directAnnotation = inHierarchy?\r
-      AnnotationUtil.findAnnotationInHierarchy(owner, annotationName.second) :\r
-      AnnotationUtil.findAnnotation(owner, annotationName.second);\r
-    if (directAnnotation != null) {\r
-      return new PsiAnnotation[]{directAnnotation};\r
-    }\r
-    if (allowIndirect) {\r
-      final PsiAnnotation[] annotations = getAnnotations(owner, inHierarchy);\r
-      for (PsiAnnotation annotation : annotations) {\r
-        PsiJavaCodeReferenceElement nameReference = annotation.getNameReferenceElement();\r
-        if (nameReference == null) continue;\r
-        PsiElement resolved = nameReference.resolve();\r
-        if (resolved instanceof PsiClass) {\r
-          final PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotationInHierarchy((PsiModifierListOwner)resolved, annotationName.second);\r
-          if (psiAnnotation != null) {\r
-            return new PsiAnnotation[]{psiAnnotation, annotation};\r
-          }\r
-        }\r
-      }\r
-    }\r
-    return PsiAnnotation.EMPTY_ARRAY;\r
-  }\r
-\r
-  public static PsiAnnotation[] getAnnotationFrom(@NotNull PsiModifierListOwner owner,\r
-                                                  @NotNull Pair<String, ? extends Set<String>> annotationName,\r
-                                                  boolean allowIndirect) {\r
-    return getAnnotationFrom(owner, annotationName, allowIndirect, true);\r
-  }\r
-\r
-  /**\r
-   * Calculates the value of the annotation's attribute referenced by the <code>attr</code> parameter by trying to\r
-   * find the attribute in the supplied list of annotations and calculating the constant value for the first attribute\r
-   * it finds.\r
-   */\r
-  @Nullable\r
-  public static String calcAnnotationValue(PsiAnnotation[] annotation, @NonNls String attr) {\r
-    for (PsiAnnotation psiAnnotation : annotation) {\r
-      final String value = calcAnnotationValue(psiAnnotation, attr);\r
-      if (value != null) return value;\r
-    }\r
-    return null;\r
-  }\r
-\r
-  @Nullable\r
-  public static String calcAnnotationValue(@NotNull PsiAnnotation annotation, @NonNls String attr) {\r
-    PsiElement value = annotation.findAttributeValue(attr);\r
-    if (value instanceof PsiExpression) {\r
-      Object o = CONSTANT_EVALUATION_HELPER.computeConstantExpression(value);\r
-      if (o instanceof String) {\r
-        return (String)o;\r
-      }\r
-    }\r
-    return null;\r
-  }\r
-\r
-  /**\r
-   * Returns all annotations for <code>listOwner</code>, possibly walking up the method hierarchy.\r
-   *\r
-   * @see com.intellij.codeInsight.AnnotationUtil#isAnnotated(com.intellij.psi.PsiModifierListOwner, java.lang.String, boolean)\r
-   */\r
-  private static PsiAnnotation[] getAnnotations(@NotNull PsiModifierListOwner listOwner, boolean inHierarchy) {\r
-    final PsiModifierList modifierList = listOwner.getModifierList();\r
-    if (modifierList == null) {\r
-      return PsiAnnotation.EMPTY_ARRAY;\r
-    }\r
-    if (!inHierarchy) {\r
-      return modifierList.getAnnotations();\r
-    }\r
-    final Set<PsiAnnotation> all = new HashSet<PsiAnnotation>() {\r
-      public boolean add(PsiAnnotation o) {\r
-        // don't overwrite "higher level" annotations\r
-        return !contains(o) && super.add(o);\r
-      }\r
-    };\r
-    if (listOwner instanceof PsiMethod) {\r
-      all.addAll(Arrays.asList(modifierList.getAnnotations()));\r
-      SuperMethodsSearch.search((PsiMethod)listOwner, null, true, true).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {\r
-            public boolean process(final MethodSignatureBackedByPsiMethod superMethod) {\r
-              all.addAll(Arrays.asList(superMethod.getMethod().getModifierList().getAnnotations()));\r
-              return true;\r
-            }\r
-          });\r
-      return all.toArray(new PsiAnnotation[all.size()]);\r
-    }\r
-    if (listOwner instanceof PsiParameter) {\r
-      PsiParameter parameter = (PsiParameter)listOwner;\r
-      PsiElement declarationScope = parameter.getDeclarationScope();\r
-      PsiParameterList parameterList;\r
-      if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod)declarationScope).getParameterList())) {\r
-        PsiMethod method = (PsiMethod)declarationScope;\r
-        final int parameterIndex = parameterList.getParameterIndex(parameter);\r
-        all.addAll(Arrays.asList(modifierList.getAnnotations()));\r
-        SuperMethodsSearch.search(method, null, true, true).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {\r
-          public boolean process(final MethodSignatureBackedByPsiMethod superMethod) {\r
-            PsiParameter superParameter = superMethod.getMethod().getParameterList().getParameters()[parameterIndex];\r
-            PsiModifierList modifierList = superParameter.getModifierList();\r
-            if (modifierList != null) {\r
-              all.addAll(Arrays.asList(modifierList.getAnnotations()));\r
-            }\r
-            return true;\r
-          }\r
-        });\r
-        return all.toArray(new PsiAnnotation[all.size()]);\r
-      }\r
-    }\r
-    return modifierList.getAnnotations();\r
-  }\r
-\r
-}\r
+/*
+ * Copyright 2006 Sascha Weinreuter
+ *
+ * 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.intellij.plugins.intelliLang.util;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiConstantEvaluationHelperImpl;
+import com.intellij.psi.search.searches.SuperMethodsSearch;
+import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Contains some extended utility functions for dealing with annotations.
+ */
+public class AnnotationUtilEx {
+  private static final PsiConstantEvaluationHelperImpl CONSTANT_EVALUATION_HELPER = new PsiConstantEvaluationHelperImpl();
+
+  private AnnotationUtilEx() {
+  }
+
+  /**
+   * @see AnnotationUtilEx#getAnnotatedElementFor(com.intellij.psi.PsiElement, LookupType)
+   */
+  public enum LookupType {
+    PREFER_CONTEXT, PREFER_DECLARATION, CONTEXT_ONLY, DECLRARATION_ONLY
+  }
+
+  /**
+   * Determines the PsiModifierListOwner for the passed element depending of the specified LookupType. The LookupType
+   * decides whether to prefer the element a reference expressions resolves to, or the element that is implied by the
+   * usage context ("expected type").
+   */
+  @Nullable
+  public static PsiModifierListOwner getAnnotatedElementFor(@Nullable PsiElement element, LookupType type) {
+    while (element != null) {
+      if (type == LookupType.PREFER_DECLARATION || type == LookupType.DECLRARATION_ONLY) {
+        if (element instanceof PsiReferenceExpression) {
+          final PsiElement e = ((PsiReferenceExpression)element).resolve();
+          if (e instanceof PsiModifierListOwner) {
+            return (PsiModifierListOwner)e;
+          }
+          if (type == LookupType.DECLRARATION_ONLY) {
+            return null;
+          }
+        }
+      }
+      element = ContextComputationProcessor.getTopLevelInjectionTarget(element);
+      final PsiElement parent = element.getParent();
+
+      if (element instanceof PsiAssignmentExpression && ((PsiAssignmentExpression)element).getOperationSign().getTokenType() == JavaTokenType.PLUSEQ) {
+        element = ((PsiAssignmentExpression)element).getLExpression();
+        continue;
+      }
+      else if (parent instanceof PsiAssignmentExpression) {
+        final PsiAssignmentExpression p = (PsiAssignmentExpression)parent;
+        if (p.getRExpression() == element) {
+          element = p.getLExpression();
+          continue;
+        }
+      }
+      else if (parent instanceof PsiReturnStatement) {
+        final PsiMethod m = PsiTreeUtil.getParentOfType(parent, PsiMethod.class);
+        if (m != null) {
+          return m;
+        }
+      }
+      else if (parent instanceof PsiModifierListOwner) {
+        return (PsiModifierListOwner)parent;
+      }
+      else if (parent instanceof PsiArrayInitializerMemberValue) {
+        final PsiArrayInitializerMemberValue value = (PsiArrayInitializerMemberValue)parent;
+        final PsiElement pair = value.getParent();
+        if (pair instanceof PsiNameValuePair) {
+          return getAnnotationMethod((PsiNameValuePair)pair, element);
+        }
+      }
+      else if (parent instanceof PsiNameValuePair) {
+        return getAnnotationMethod((PsiNameValuePair)parent, element);
+      }
+      else {
+        return PsiUtilEx.getParameterForArgument(element);
+      }
+
+      // If no annotation has been found through the usage context, check if the element
+      // (i.e. the element the reference refers to) is annotated itself
+      if (type != LookupType.DECLRARATION_ONLY) {
+        if (element instanceof PsiReferenceExpression) {
+          final PsiElement e = ((PsiReferenceExpression)element).resolve();
+          if (e instanceof PsiModifierListOwner) {
+            return (PsiModifierListOwner)e;
+          }
+        }
+      }
+      return null;
+    }
+    return null;
+  }
+
+  @Nullable
+  private static PsiModifierListOwner getAnnotationMethod(PsiNameValuePair pair, PsiElement element) {
+    final PsiAnnotation annotation = PsiTreeUtil.getParentOfType(pair.getParent(), PsiAnnotation.class);
+    assert annotation != null;
+
+    final String fqn = annotation.getQualifiedName();
+    if (fqn == null) return null;
+
+    final PsiClass psiClass = JavaPsiFacade.getInstance(element.getProject()).findClass(fqn, element.getResolveScope());
+    if (psiClass != null && psiClass.isAnnotationType()) {
+      final String name = pair.getName();
+      final PsiMethod[] methods = psiClass.findMethodsByName(name != null ? name : "value", false);
+      return methods.length > 0 ? methods[0] : null;
+    }
+    return null;
+  }
+
+  /**
+   * Utility method to obtain annotations of a specific type from the supplied PsiModifierListOwner.
+   * For optimization reasons, this method only looks at elements of type java.lang.String.
+   * <p/>
+   * The parameter <code>allowIndirect</code> determines if the method should look for indirect annotations, i.e.
+   * annotations which have themselves been annotated by the supplied annotation name. Currently, this only allows
+   * one level of indirection and returns an array of [base-annotation, indirect annotation]
+   * <p/>
+   * The <code>annotationName</code> parameter is a pair of the target annotation class' fully qualified name as a
+   * String and as a Set. This is done for performance reasons because the Set is required by the
+   * {@link com.intellij.codeInsight.AnnotationUtil} utility class and allows to avoid unecessary object constructions.
+   */
+  @NotNull
+  public static PsiAnnotation[] getAnnotationFrom(PsiModifierListOwner owner,
+                                                  Pair<String, ? extends Set<String>> annotationName,
+                                                  boolean allowIndirect,
+                                                  boolean inHierarchy) {
+    if (!PsiUtilEx.isLanguageAnnotationTarget(owner)) return PsiAnnotation.EMPTY_ARRAY;
+
+    final PsiAnnotation directAnnotation = inHierarchy?
+      AnnotationUtil.findAnnotationInHierarchy(owner, annotationName.second) :
+      AnnotationUtil.findAnnotation(owner, annotationName.second);
+    if (directAnnotation != null) {
+      return new PsiAnnotation[]{directAnnotation};
+    }
+    if (allowIndirect) {
+      final PsiAnnotation[] annotations = getAnnotations(owner, inHierarchy);
+      for (PsiAnnotation annotation : annotations) {
+        PsiJavaCodeReferenceElement nameReference = annotation.getNameReferenceElement();
+        if (nameReference == null) continue;
+        PsiElement resolved = nameReference.resolve();
+        if (resolved instanceof PsiClass) {
+          final PsiAnnotation psiAnnotation = AnnotationUtil.findAnnotationInHierarchy((PsiModifierListOwner)resolved, annotationName.second);
+          if (psiAnnotation != null) {
+            return new PsiAnnotation[]{psiAnnotation, annotation};
+          }
+        }
+      }
+    }
+    return PsiAnnotation.EMPTY_ARRAY;
+  }
+
+  public static PsiAnnotation[] getAnnotationFrom(@NotNull PsiModifierListOwner owner,
+                                                  @NotNull Pair<String, ? extends Set<String>> annotationName,
+                                                  boolean allowIndirect) {
+    return getAnnotationFrom(owner, annotationName, allowIndirect, true);
+  }
+
+  /**
+   * Calculates the value of the annotation's attribute referenced by the <code>attr</code> parameter by trying to
+   * find the attribute in the supplied list of annotations and calculating the constant value for the first attribute
+   * it finds.
+   */
+  @Nullable
+  public static String calcAnnotationValue(PsiAnnotation[] annotation, @NonNls String attr) {
+    for (PsiAnnotation psiAnnotation : annotation) {
+      final String value = calcAnnotationValue(psiAnnotation, attr);
+      if (value != null) return value;
+    }
+    return null;
+  }
+
+  @Nullable
+  public static String calcAnnotationValue(@NotNull PsiAnnotation annotation, @NonNls String attr) {
+    PsiElement value = annotation.findAttributeValue(attr);
+    if (value instanceof PsiExpression) {
+      Object o = CONSTANT_EVALUATION_HELPER.computeConstantExpression(value);
+      if (o instanceof String) {
+        return (String)o;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Returns all annotations for <code>listOwner</code>, possibly walking up the method hierarchy.
+   *
+   * @see com.intellij.codeInsight.AnnotationUtil#isAnnotated(com.intellij.psi.PsiModifierListOwner, java.lang.String, boolean)
+   */
+  private static PsiAnnotation[] getAnnotations(@NotNull PsiModifierListOwner listOwner, boolean inHierarchy) {
+    final PsiModifierList modifierList = listOwner.getModifierList();
+    if (modifierList == null) {
+      return PsiAnnotation.EMPTY_ARRAY;
+    }
+    if (!inHierarchy) {
+      return modifierList.getAnnotations();
+    }
+    final Set<PsiAnnotation> all = new HashSet<PsiAnnotation>() {
+      public boolean add(PsiAnnotation o) {
+        // don't overwrite "higher level" annotations
+        return !contains(o) && super.add(o);
+      }
+    };
+    if (listOwner instanceof PsiMethod) {
+      all.addAll(Arrays.asList(modifierList.getAnnotations()));
+      SuperMethodsSearch.search((PsiMethod)listOwner, null, true, true).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {
+            public boolean process(final MethodSignatureBackedByPsiMethod superMethod) {
+              all.addAll(Arrays.asList(superMethod.getMethod().getModifierList().getAnnotations()));
+              return true;
+            }
+          });
+      return all.toArray(new PsiAnnotation[all.size()]);
+    }
+    if (listOwner instanceof PsiParameter) {
+      PsiParameter parameter = (PsiParameter)listOwner;
+      PsiElement declarationScope = parameter.getDeclarationScope();
+      PsiParameterList parameterList;
+      if (declarationScope instanceof PsiMethod && parameter.getParent() == (parameterList = ((PsiMethod)declarationScope).getParameterList())) {
+        PsiMethod method = (PsiMethod)declarationScope;
+        final int parameterIndex = parameterList.getParameterIndex(parameter);
+        all.addAll(Arrays.asList(modifierList.getAnnotations()));
+        SuperMethodsSearch.search(method, null, true, true).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {
+          public boolean process(final MethodSignatureBackedByPsiMethod superMethod) {
+            PsiParameter superParameter = superMethod.getMethod().getParameterList().getParameters()[parameterIndex];
+            PsiModifierList modifierList = superParameter.getModifierList();
+            if (modifierList != null) {
+              all.addAll(Arrays.asList(modifierList.getAnnotations()));
+            }
+            return true;
+          }
+        });
+        return all.toArray(new PsiAnnotation[all.size()]);
+      }
+    }
+    return modifierList.getAnnotations();
+  }
+
+}