[maven] remove unfinished quick fix
[idea/community.git] / java / java-psi-api / src / com / intellij / patterns / PsiJavaElementPattern.java
1 /*
2  * Copyright 2000-2015 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 com.intellij.patterns;
17
18 import com.intellij.psi.*;
19 import com.intellij.util.ProcessingContext;
20 import com.intellij.util.containers.ContainerUtil;
21 import org.jetbrains.annotations.NonNls;
22 import org.jetbrains.annotations.NotNull;
23 import org.jetbrains.annotations.Nullable;
24
25 /**
26  * @author peter
27  */
28 public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElementPattern<T,Self>> extends PsiElementPattern<T,Self> {
29   @NonNls private static final String VALUE = "value";
30
31   public PsiJavaElementPattern(final Class<T> aClass) {
32     super(aClass);
33   }
34
35   public PsiJavaElementPattern(@NotNull final InitialPatternCondition<T> condition) {
36     super(condition);
37   }
38
39   public Self annotationParam(@NonNls final String annotationQualifiedName, @NonNls final String parameterName) {
40     return withParent(
41       PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
42         PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
43           PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
44   }
45
46   public Self annotationParam(@NonNls final String annotationQualifiedName) {
47     return annotationParam(annotationQualifiedName, VALUE);
48   }
49
50   public Self annotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
51     return withParent(
52       PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
53         PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
54           PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
55   }
56   public Self annotationParam(@NotNull ElementPattern<? extends PsiAnnotation> annotation) {
57     return withParent(
58       PsiJavaPatterns.psiNameValuePair().withParent(
59         PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
60           annotation)));
61   }
62
63   public Self annotationParam(String parameterName, @NotNull ElementPattern<? extends PsiAnnotation> annotation) {
64     return withParent(
65       PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
66         PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(annotation)));
67   }
68
69   public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
70     return withAncestor(3,   // can be array initializer
71                         PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
72         PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
73           PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
74   }
75
76   public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName) {
77     return insideAnnotationParam(annotationQualifiedName, VALUE);
78   }
79
80   public Self insideAnnotationParam(@NotNull String annotationQualifiedName) {
81     return insideAnnotationParam(StandardPatterns.string().equalTo(annotationQualifiedName));
82   }
83
84   public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
85     return nameIdentifierOf(StandardPatterns.instanceOf(aClass));
86   }
87
88   public Self nameIdentifierOf(final ElementPattern<? extends PsiMember> pattern) {
89     return with(new PatternCondition<T>("nameIdentifierOf") {
90       @Override
91       public boolean accepts(@NotNull final T t, final ProcessingContext context) {
92         if (!(t instanceof PsiIdentifier)) return false;
93
94         final PsiElement parent = t.getParent();
95         if (parent instanceof PsiClass && t != ((PsiClass) parent).getNameIdentifier()) return false;
96         if (parent instanceof PsiMethod && t != ((PsiMethod) parent).getNameIdentifier()) return false;
97         if (parent instanceof PsiVariable && t != ((PsiVariable) parent).getNameIdentifier()) return false;
98
99         return pattern.accepts(parent, context);
100       }
101     });
102   }
103
104   public Self methodCallParameter(final int index, final ElementPattern<? extends PsiMethod> methodPattern) {
105     final PsiNamePatternCondition nameCondition = ContainerUtil.findInstance(methodPattern.getCondition().getConditions(), PsiNamePatternCondition.class);
106
107     return with(new PatternCondition<T>("methodCallParameter") {
108       @Override
109       public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
110         final PsiElement parent = literal.getParent();
111         if (parent instanceof PsiExpressionList) {
112           return hasIndex(literal, index) && checkCall(context, (PsiExpressionList)parent, methodPattern, nameCondition);
113         }
114         return false;
115       }
116
117       private boolean hasIndex(@NotNull T literal, int index) {
118         int currentIndex = 0;
119         PsiElement each = literal;
120         while (each != null) {
121           each = each.getPrevSibling();
122           if (each instanceof PsiExpression) {
123             currentIndex++;
124             if (currentIndex > index) return false;
125           }
126         }
127
128         if (currentIndex != index) return false;
129         return true;
130       }
131     });
132   }
133
134   public Self methodCallParameter(@NotNull final ElementPattern<? extends PsiMethod> methodPattern) {
135     final PsiNamePatternCondition nameCondition = ContainerUtil.findInstance(methodPattern.getCondition().getConditions(), PsiNamePatternCondition.class);
136
137     return with(new PatternCondition<T>("methodCallParameter") {
138       @Override
139       public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
140         final PsiElement parent = literal.getParent();
141         return parent instanceof PsiExpressionList && checkCall(context, (PsiExpressionList)parent, methodPattern, nameCondition);
142       }
143     });
144   }
145
146   private static boolean checkCall(ProcessingContext context,
147                                    PsiExpressionList psiExpressionList,
148                                    ElementPattern<? extends PsiMethod> methodPattern,
149                                    @Nullable PsiNamePatternCondition nameCondition) {
150     final PsiElement element = psiExpressionList.getParent();
151     if (element instanceof PsiMethodCallExpression) {
152       PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)element).getMethodExpression();
153       if (nameCondition != null && !nameCondition.getNamePattern().accepts(methodExpression.getReferenceName())) {
154         return false;
155       }
156
157       for (JavaResolveResult result : methodExpression.multiResolve(false)) {
158         if (methodPattern.accepts(result.getElement(), context)) {
159           return true;
160         }
161       }
162     }
163     return false;
164   }
165
166   public Self constructorParameter(final int index, final String... fqns) {
167     return with(new PatternCondition<T>("constructorParameter") {
168       @Override
169       public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
170         final PsiElement parent = literal.getParent();
171         if (parent instanceof PsiExpressionList) {
172           final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
173           final PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
174           if (!(psiExpressions.length > index && psiExpressions[index] == literal)) return false;
175
176           final PsiElement element = psiExpressionList.getParent();
177           if (element instanceof PsiNewExpression) {
178             PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassOrAnonymousClassReference();
179             if (reference != null) {
180               String qualifiedName = reference.getQualifiedName();
181               for (String fqn : fqns) {
182                 if( fqn.equals(qualifiedName)) return true;
183               }
184             }
185           }
186         }
187         return false;
188       }
189     });
190   }
191
192   public static class Capture<T extends PsiElement> extends PsiJavaElementPattern<T, Capture<T>> {
193     public Capture(final Class<T> aClass) {
194       super(aClass);
195     }
196
197     public Capture(@NotNull final InitialPatternCondition<T> condition) {
198       super(condition);
199     }
200   }
201
202
203
204 }