f731f0a64740e133f25e7bb9b9c0041372f8688c
[idea/community.git] / plugins / groovy / groovy-psi / src / org / jetbrains / plugins / groovy / lang / psi / impl / GrAnnotationUtil.java
1 // Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
2 package org.jetbrains.plugins.groovy.lang.psi.impl;
3
4 import com.intellij.codeInsight.AnnotationUtil;
5 import com.intellij.psi.*;
6 import com.intellij.util.containers.ContainerUtil;
7 import org.jetbrains.annotations.NotNull;
8 import org.jetbrains.annotations.Nullable;
9 import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotation;
10 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
11 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
12
13 import java.util.Collections;
14 import java.util.List;
15
16 import static org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtilKt.findDeclaredDetachedValue;
17 import static org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtilKt.getArrayValue;
18
19 /**
20  * @author Max Medvedev
21  */
22 public final class GrAnnotationUtil {
23   @Nullable
24   public static String inferStringAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
25     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
26     return getString(targetValue);
27   }
28
29   @Nullable
30   public static String getString(@Nullable PsiAnnotationMemberValue targetValue) {
31     if (targetValue instanceof PsiLiteral) {
32       final Object value = ((PsiLiteral)targetValue).getValue();
33       if (value instanceof String) return (String)value;
34     }
35     return null;
36   }
37
38   @Nullable
39   public static Integer inferIntegerAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
40     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
41     if (targetValue instanceof PsiLiteral) {
42       final Object value = ((PsiLiteral)targetValue).getValue();
43       if (value instanceof Integer) return (Integer)value;
44     }
45     return null;
46   }
47
48   @Nullable
49   public static Boolean inferBooleanAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
50     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
51     if (targetValue instanceof PsiLiteral) {
52       final Object value = ((PsiLiteral)targetValue).getValue();
53       if (value instanceof Boolean) return (Boolean)value;
54     }
55     return null;
56   }
57
58   public static boolean inferBooleanAttributeNotNull(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
59     Boolean result = inferBooleanAttribute(annotation, attributeName);
60     return result != null && result;
61   }
62
63   @Nullable
64   public static PsiClass inferClassAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
65     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
66     return getPsiClass(targetValue);
67   }
68
69   @Nullable
70   public static PsiClass getPsiClass(@Nullable PsiAnnotationMemberValue targetValue) {
71     if (targetValue instanceof PsiClassObjectAccessExpression) {
72       PsiType type = ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
73       if (type instanceof PsiClassType) {
74         return ((PsiClassType)type).resolve();
75       }
76     }
77     else if (targetValue instanceof GrReferenceExpression) {
78       if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
79         GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
80         if (qualifier instanceof GrReferenceExpression) {
81           PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
82           if (resolved instanceof PsiClass) {
83             return (PsiClass)resolved;
84           }
85         }
86       }
87       PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
88       if (resolved instanceof PsiClass) return (PsiClass)resolved;
89     }
90     return null;
91   }
92
93   @Nullable
94   public static PsiType extractClassTypeFromClassAttributeValue(PsiAnnotationMemberValue targetValue) {
95     if (targetValue instanceof PsiClassObjectAccessExpression) {
96       return ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
97     }
98     else if (targetValue instanceof GrReferenceExpression) {
99       if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
100         GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
101         if (qualifier instanceof GrReferenceExpression) {
102           PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
103           if (resolved instanceof PsiClass) {
104             return qualifier.getType();
105           }
106         }
107       }
108       PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
109       if (resolved instanceof PsiClass) {
110         return ((GrReferenceExpression)targetValue).getType();
111       }
112     }
113     return null;
114   }
115
116   public static PsiElement getActualOwner(GrAnnotation annotation) {
117     PsiAnnotationOwner owner = annotation.getOwner();
118     if (owner instanceof PsiModifierList) return ((PsiModifierList)owner).getParent();
119
120     return (PsiElement)owner;
121   }
122
123   public static List<PsiClass> getClassArrayValue(@NotNull PsiAnnotation annotation, @NotNull String attributeName, boolean declared) {
124     PsiAnnotationMemberValue value =
125       declared ? annotation.findDeclaredAttributeValue(attributeName) : annotation.findAttributeValue(attributeName);
126     return ContainerUtil.mapNotNull(AnnotationUtil.arrayAttributeValues(value), GrAnnotationUtil::getPsiClass);
127   }
128
129   public static List<String> getStringArrayValue(@NotNull PsiAnnotation annotation, @NotNull String attributeName, boolean declared) {
130     PsiAnnotationMemberValue value = findDetachedAttributeValue(annotation, attributeName, declared);
131     if (value == null) return Collections.emptyList();
132     return getArrayValue(value, AnnotationUtil::getStringAttributeValue);
133   }
134
135   @Nullable
136   private static PsiAnnotationMemberValue findDetachedAttributeValue(@NotNull PsiAnnotation annotation,
137                                                                      @Nullable String attributeName,
138                                                                      boolean declared) {
139     PsiAnnotationMemberValue declaredValue = findDeclaredDetachedValue(annotation, attributeName);
140     if (declaredValue != null) return declaredValue;
141     if (declared) return null;
142     return annotation.findAttributeValue(attributeName);
143   }
144 }