[groovy] IDEA-207415: Support super constructor call in `pre` attribute
[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.blocks.GrClosableBlock;
11 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
12 import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
13
14 import java.util.Collections;
15 import java.util.List;
16
17 import static org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtilKt.findDeclaredDetachedValue;
18 import static org.jetbrains.plugins.groovy.lang.psi.impl.GrAnnotationUtilKt.getArrayValue;
19
20 /**
21  * @author Max Medvedev
22  */
23 public final class GrAnnotationUtil {
24   @Nullable
25   public static String inferStringAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
26     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
27     return getString(targetValue);
28   }
29
30   @Nullable
31   public static GrClosableBlock inferClosureAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
32     PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
33     if (targetValue instanceof GrClosableBlock) {
34       return (GrClosableBlock)targetValue;
35     }
36     return null;
37   }
38
39   @Nullable
40   public static String getString(@Nullable PsiAnnotationMemberValue targetValue) {
41     if (targetValue instanceof PsiLiteral) {
42       final Object value = ((PsiLiteral)targetValue).getValue();
43       if (value instanceof String) return (String)value;
44     }
45     return null;
46   }
47
48   @Nullable
49   public static Integer inferIntegerAttribute(@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 Integer) return (Integer)value;
54     }
55     return null;
56   }
57
58   @Nullable
59   public static Boolean inferBooleanAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
60     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
61     if (targetValue instanceof PsiLiteral) {
62       final Object value = ((PsiLiteral)targetValue).getValue();
63       if (value instanceof Boolean) return (Boolean)value;
64     }
65     return null;
66   }
67
68   public static boolean inferBooleanAttributeNotNull(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
69     Boolean result = inferBooleanAttribute(annotation, attributeName);
70     return result != null && result;
71   }
72
73   @Nullable
74   public static PsiClass inferClassAttribute(@NotNull PsiAnnotation annotation, @NotNull String attributeName) {
75     final PsiAnnotationMemberValue targetValue = annotation.findAttributeValue(attributeName);
76     return getPsiClass(targetValue);
77   }
78
79   @Nullable
80   public static PsiClass getPsiClass(@Nullable PsiAnnotationMemberValue targetValue) {
81     if (targetValue instanceof PsiClassObjectAccessExpression) {
82       PsiType type = ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
83       if (type instanceof PsiClassType) {
84         return ((PsiClassType)type).resolve();
85       }
86     }
87     else if (targetValue instanceof GrReferenceExpression) {
88       if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
89         GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
90         if (qualifier instanceof GrReferenceExpression) {
91           PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
92           if (resolved instanceof PsiClass) {
93             return (PsiClass)resolved;
94           }
95         }
96       }
97       PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
98       if (resolved instanceof PsiClass) return (PsiClass)resolved;
99     }
100     return null;
101   }
102
103   @Nullable
104   public static PsiType extractClassTypeFromClassAttributeValue(PsiAnnotationMemberValue targetValue) {
105     if (targetValue instanceof PsiClassObjectAccessExpression) {
106       return ((PsiClassObjectAccessExpression)targetValue).getOperand().getType();
107     }
108     else if (targetValue instanceof GrReferenceExpression) {
109       if ("class".equals(((GrReferenceExpression)targetValue).getReferenceName())) {
110         GrExpression qualifier = ((GrReferenceExpression)targetValue).getQualifier();
111         if (qualifier instanceof GrReferenceExpression) {
112           PsiElement resolved = ((GrReferenceExpression)qualifier).resolve();
113           if (resolved instanceof PsiClass) {
114             return qualifier.getType();
115           }
116         }
117       }
118       PsiElement resolved = ((GrReferenceExpression)targetValue).resolve();
119       if (resolved instanceof PsiClass) {
120         return ((GrReferenceExpression)targetValue).getType();
121       }
122     }
123     return null;
124   }
125
126   public static PsiElement getActualOwner(GrAnnotation annotation) {
127     PsiAnnotationOwner owner = annotation.getOwner();
128     if (owner instanceof PsiModifierList) return ((PsiModifierList)owner).getParent();
129
130     return (PsiElement)owner;
131   }
132
133   public static List<PsiClass> getClassArrayValue(@NotNull PsiAnnotation annotation, @NotNull String attributeName, boolean declared) {
134     PsiAnnotationMemberValue value =
135       declared ? annotation.findDeclaredAttributeValue(attributeName) : annotation.findAttributeValue(attributeName);
136     return ContainerUtil.mapNotNull(AnnotationUtil.arrayAttributeValues(value), GrAnnotationUtil::getPsiClass);
137   }
138
139   public static List<String> getStringArrayValue(@NotNull PsiAnnotation annotation, @NotNull String attributeName, boolean declared) {
140     PsiAnnotationMemberValue value = findDetachedAttributeValue(annotation, attributeName, declared);
141     if (value == null) return Collections.emptyList();
142     return getArrayValue(value, AnnotationUtil::getStringAttributeValue);
143   }
144
145   @Nullable
146   private static PsiAnnotationMemberValue findDetachedAttributeValue(@NotNull PsiAnnotation annotation,
147                                                                      @Nullable String attributeName,
148                                                                      boolean declared) {
149     PsiAnnotationMemberValue declaredValue = findDeclaredDetachedValue(annotation, attributeName);
150     if (declaredValue != null) return declaredValue;
151     if (declared) return null;
152     return annotation.findAttributeValue(attributeName);
153   }
154 }