1 package com
.intellij
.psi
.impl
;
3 import com
.intellij
.lang
.ASTNode
;
4 import com
.intellij
.openapi
.diagnostic
.Logger
;
5 import com
.intellij
.openapi
.util
.text
.StringUtil
;
6 import com
.intellij
.psi
.*;
7 import com
.intellij
.psi
.filters
.ElementFilter
;
8 import com
.intellij
.psi
.impl
.light
.LightClassReference
;
9 import com
.intellij
.psi
.impl
.source
.PsiClassReferenceType
;
10 import com
.intellij
.psi
.impl
.source
.PsiImmediateClassType
;
11 import com
.intellij
.psi
.impl
.source
.tree
.CompositeElement
;
12 import com
.intellij
.psi
.impl
.source
.tree
.ElementType
;
13 import com
.intellij
.psi
.impl
.source
.tree
.JavaDocElementType
;
14 import com
.intellij
.psi
.impl
.source
.tree
.TreeElement
;
15 import com
.intellij
.psi
.javadoc
.PsiDocComment
;
16 import com
.intellij
.psi
.scope
.ElementClassHint
;
17 import com
.intellij
.psi
.scope
.PsiScopeProcessor
;
18 import com
.intellij
.psi
.scope
.processor
.FilterScopeProcessor
;
19 import com
.intellij
.psi
.scope
.util
.PsiScopesUtil
;
20 import com
.intellij
.psi
.search
.GlobalSearchScope
;
21 import com
.intellij
.psi
.search
.LocalSearchScope
;
22 import com
.intellij
.psi
.search
.PackageScope
;
23 import com
.intellij
.psi
.search
.SearchScope
;
24 import com
.intellij
.psi
.util
.PsiTreeUtil
;
25 import com
.intellij
.psi
.util
.PsiUtil
;
26 import com
.intellij
.util
.IncorrectOperationException
;
27 import com
.intellij
.util
.ObjectUtils
;
28 import com
.intellij
.util
.SmartList
;
29 import org
.jetbrains
.annotations
.NonNls
;
30 import org
.jetbrains
.annotations
.NotNull
;
31 import org
.jetbrains
.annotations
.Nullable
;
33 import java
.util
.List
;
35 public class PsiImplUtil
{
36 private static final Logger LOG
= Logger
.getInstance("#com.intellij.psi.impl.PsiImplUtil");
38 private PsiImplUtil() {
42 public static PsiMethod
[] getConstructors(PsiClass aClass
) {
43 final List
<PsiMethod
> constructorsList
= new SmartList
<PsiMethod
>();
44 final PsiMethod
[] methods
= aClass
.getMethods();
45 for (final PsiMethod method
: methods
) {
46 if (method
.isConstructor()) constructorsList
.add(method
);
48 return constructorsList
.toArray(new PsiMethod
[constructorsList
.size()]);
52 public static PsiAnnotationMemberValue
findDeclaredAttributeValue(PsiAnnotation annotation
, @NonNls String attributeName
) {
53 if ("value".equals(attributeName
)) attributeName
= null;
54 PsiNameValuePair
[] attributes
= annotation
.getParameterList().getAttributes();
55 for (PsiNameValuePair attribute
: attributes
) {
56 @NonNls final String name
= attribute
.getName();
57 if (ObjectUtils
.equals(name
, attributeName
) || attributeName
== null && name
.equals(PsiAnnotation
.DEFAULT_REFERENCED_METHOD_NAME
)) {
58 return attribute
.getValue();
65 public static PsiAnnotationMemberValue
findAttributeValue(PsiAnnotation annotation
, @NonNls String attributeName
) {
66 final PsiAnnotationMemberValue value
= findDeclaredAttributeValue(annotation
, attributeName
);
67 if (value
!= null) return value
;
69 if (attributeName
== null) attributeName
= "value";
70 final PsiJavaCodeReferenceElement referenceElement
= annotation
.getNameReferenceElement();
71 if (referenceElement
!= null) {
72 PsiElement resolved
= referenceElement
.resolve();
73 if (resolved
!= null) {
74 PsiMethod
[] methods
= ((PsiClass
)resolved
).getMethods();
75 for (PsiMethod method
: methods
) {
76 if (method
instanceof PsiAnnotationMethod
&& ObjectUtils
.equals(method
.getName(), attributeName
)) {
77 return ((PsiAnnotationMethod
)method
).getDefaultValue();
85 public static PsiTypeParameter
[] getTypeParameters(PsiTypeParameterListOwner owner
) {
86 final PsiTypeParameterList typeParameterList
= owner
.getTypeParameterList();
87 if (typeParameterList
!= null) {
88 return typeParameterList
.getTypeParameters();
90 return PsiTypeParameter
.EMPTY_ARRAY
;
94 public static PsiJavaCodeReferenceElement
[] namesToPackageReferences(PsiManager manager
, String
[] names
) {
95 PsiJavaCodeReferenceElement
[] refs
= new PsiJavaCodeReferenceElement
[names
.length
];
96 for (int i
= 0; i
< names
.length
; i
++) {
97 String name
= names
[i
];
99 refs
[i
] = JavaPsiFacade
.getInstance(manager
.getProject()).getElementFactory().createPackageReferenceElement(name
);
101 catch (IncorrectOperationException e
) {
108 public static int getParameterIndex(PsiParameter parameter
, PsiParameterList parameterList
) {
109 PsiParameter
[] parameters
= parameterList
.getParameters();
110 for (int i
= 0; i
< parameters
.length
; i
++) {
111 if (parameter
.equals(parameters
[i
])) return i
;
113 LOG
.assertTrue(false);
117 public static int getTypeParameterIndex(PsiTypeParameter typeParameter
, PsiTypeParameterList typeParameterList
) {
118 PsiTypeParameter
[] typeParameters
= typeParameterList
.getTypeParameters();
119 for (int i
= 0; i
< typeParameters
.length
; i
++) {
120 if (typeParameter
.equals(typeParameters
[i
])) return i
;
122 LOG
.assertTrue(false);
127 public static Object
[] getReferenceVariantsByFilter(PsiJavaCodeReferenceElement reference
, ElementFilter filter
) {
128 FilterScopeProcessor processor
= new FilterScopeProcessor(filter
);
129 PsiScopesUtil
.resolveAndWalk(processor
, reference
, null, true);
130 return processor
.getResults().toArray();
133 public static boolean processDeclarationsInMethod(PsiMethod method
,
134 PsiScopeProcessor processor
,
136 PsiElement lastParent
,
138 final ElementClassHint hint
= processor
.getHint(ElementClassHint
.KEY
);
139 processor
.handleEvent(PsiScopeProcessor
.Event
.SET_DECLARATION_HOLDER
, method
);
140 if (hint
== null || hint
.shouldProcess(ElementClassHint
.DeclaractionKind
.CLASS
)) {
141 final PsiTypeParameterList list
= method
.getTypeParameterList();
142 if (list
!= null && !list
.processDeclarations(processor
, state
, null, place
)) return false;
144 if (lastParent
instanceof PsiCodeBlock
) {
145 final PsiParameter
[] parameters
= method
.getParameterList().getParameters();
146 for (PsiParameter parameter
: parameters
) {
147 if (!processor
.execute(parameter
, state
)) return false;
154 public static boolean hasTypeParameters(PsiTypeParameterListOwner owner
) {
155 final PsiTypeParameterList typeParameterList
= owner
.getTypeParameterList();
156 return typeParameterList
!= null && typeParameterList
.getTypeParameters().length
!= 0;
160 public static PsiType
[] typesByReferenceParameterList(final PsiReferenceParameterList parameterList
) {
161 PsiTypeElement
[] typeElements
= parameterList
.getTypeParameterElements();
163 return typesByTypeElements(typeElements
);
167 public static PsiType
[] typesByTypeElements(PsiTypeElement
[] typeElements
) {
168 PsiType
[] types
= new PsiType
[typeElements
.length
];
169 for (int i
= 0; i
< types
.length
; i
++) {
170 types
[i
] = typeElements
[i
].getType();
175 public static PsiType
getType(PsiClassObjectAccessExpression classAccessExpression
) {
176 GlobalSearchScope resolveScope
= classAccessExpression
.getResolveScope();
177 PsiManager manager
= classAccessExpression
.getManager();
178 final PsiClass classClass
= JavaPsiFacade
.getInstance(manager
.getProject()).findClass("java.lang.Class", resolveScope
);
179 if (classClass
== null) {
180 return new PsiClassReferenceType(new LightClassReference(manager
, "Class", "java.lang.Class", resolveScope
), null);
182 if (!PsiUtil
.isLanguageLevel5OrHigher(classAccessExpression
)) {
183 //Raw java.lang.Class
184 return JavaPsiFacade
.getInstance(manager
.getProject()).getElementFactory().createType(classClass
);
187 PsiSubstitutor substitutor
= PsiSubstitutor
.EMPTY
;
188 PsiType operandType
= classAccessExpression
.getOperand().getType();
189 if (operandType
instanceof PsiPrimitiveType
&& !PsiType
.NULL
.equals(operandType
)) {
190 if (PsiType
.VOID
.equals(operandType
)) {
191 operandType
= JavaPsiFacade
.getInstance(manager
.getProject()).getElementFactory()
192 .createTypeByFQClassName("java.lang.Void", classAccessExpression
.getResolveScope());
195 operandType
= ((PsiPrimitiveType
)operandType
).getBoxedType(classAccessExpression
);
198 final PsiTypeParameter
[] typeParameters
= classClass
.getTypeParameters();
199 if (typeParameters
.length
== 1) {
200 substitutor
= substitutor
.put(typeParameters
[0], operandType
);
203 return new PsiImmediateClassType(classClass
, substitutor
);
206 public static PsiAnnotation
findAnnotation(PsiAnnotationOwner modifierList
, @NotNull String qualifiedName
) {
207 final String shortName
= StringUtil
.getShortName(qualifiedName
);
208 PsiAnnotation
[] annotations
= modifierList
.getAnnotations();
209 for (PsiAnnotation annotation
: annotations
) {
210 final PsiJavaCodeReferenceElement referenceElement
= annotation
.getNameReferenceElement();
211 if (referenceElement
!= null && shortName
.equals(referenceElement
.getReferenceName())) {
212 if (qualifiedName
.equals(annotation
.getQualifiedName())) return annotation
;
220 public static ASTNode
findDocComment(final CompositeElement element
) {
221 TreeElement node
= element
.getFirstChildNode();
222 while (node
!= null &&
223 (ElementType
.WHITE_SPACE_BIT_SET
.contains(node
.getElementType()) ||
224 node
.getElementType() == JavaTokenType
.C_STYLE_COMMENT
||
225 node
.getElementType() == JavaTokenType
.END_OF_LINE_COMMENT
)) {
226 node
= node
.getTreeNext();
229 if (node
!= null && node
.getElementType() == JavaDocElementType
.DOC_COMMENT
) {
237 public static PsiType
normalizeWildcardTypeByPosition(final PsiType type
, final PsiExpression expression
) {
238 PsiExpression toplevel
= expression
;
239 while (toplevel
.getParent() instanceof PsiArrayAccessExpression
&&
240 ((PsiArrayAccessExpression
)toplevel
.getParent()).getArrayExpression() == toplevel
) {
241 toplevel
= (PsiExpression
)toplevel
.getParent();
244 final PsiType normalized
= doNormalizeWildcardByPosition(type
, expression
, toplevel
);
245 if (normalized
instanceof PsiClassType
&& !PsiUtil
.isAccessedForWriting(toplevel
)) {
246 return PsiUtil
.captureToplevelWildcards(normalized
, expression
);
252 private static PsiType
doNormalizeWildcardByPosition(final PsiType type
, final PsiExpression expression
, final PsiExpression toplevel
) {
253 if (type
instanceof PsiCapturedWildcardType
) {
254 return doNormalizeWildcardByPosition(((PsiCapturedWildcardType
)type
).getWildcard(), expression
, toplevel
);
258 if (type
instanceof PsiWildcardType
) {
259 final PsiWildcardType wildcardType
= (PsiWildcardType
)type
;
261 if (PsiUtil
.isAccessedForWriting(toplevel
)) {
262 return wildcardType
.isSuper() ? wildcardType
.getBound() : PsiCapturedWildcardType
.create(wildcardType
, expression
);
265 if (wildcardType
.isExtends()) {
266 return wildcardType
.getBound();
269 return PsiType
.getJavaLangObject(expression
.getManager(), expression
.getResolveScope());
273 else if (type
instanceof PsiArrayType
) {
274 final PsiType componentType
= ((PsiArrayType
)type
).getComponentType();
275 final PsiType normalizedComponentType
= doNormalizeWildcardByPosition(componentType
, expression
, toplevel
);
276 if (normalizedComponentType
!= componentType
) {
277 return normalizedComponentType
.createArrayType();
285 public static SearchScope
getMemberUseScope(final PsiMember member
) {
286 final PsiManagerEx psiManager
= (PsiManagerEx
)member
.getManager();
287 final GlobalSearchScope maximalUseScope
= psiManager
.getFileManager().getUseScope(member
);
288 PsiFile file
= member
.getContainingFile();
289 if (PsiUtil
.isInJspFile(file
)) return maximalUseScope
;
291 PsiClass aClass
= member
.getContainingClass();
292 if (aClass
instanceof PsiAnonymousClass
) {
293 //member from anonymous class can be called from outside the class
294 PsiElement methodCallExpr
= PsiTreeUtil
.getParentOfType(aClass
, PsiMethodCallExpression
.class);
295 return new LocalSearchScope(methodCallExpr
!= null ? methodCallExpr
: aClass
);
298 if (member
.hasModifierProperty(PsiModifier
.PUBLIC
)) {
299 return maximalUseScope
; // class use scope doesn't matter, since another very visible class can inherit from aClass
301 else if (member
.hasModifierProperty(PsiModifier
.PROTECTED
)) {
302 return maximalUseScope
; // class use scope doesn't matter, since another very visible class can inherit from aClass
304 else if (member
.hasModifierProperty(PsiModifier
.PRIVATE
)) {
305 PsiClass topClass
= PsiUtil
.getTopLevelClass(member
);
306 return topClass
!= null ?
new LocalSearchScope(topClass
) : new LocalSearchScope(file
);
309 if (file
instanceof PsiJavaFile
) {
310 PsiPackage aPackage
= JavaPsiFacade
.getInstance(psiManager
.getProject()).findPackage(((PsiJavaFile
)file
).getPackageName());
311 if (aPackage
!= null) {
312 SearchScope scope
= PackageScope
.packageScope(aPackage
, false);
313 scope
= scope
.intersectWith(maximalUseScope
);
318 return maximalUseScope
;
322 public static PsiElement
setName(PsiElement element
, String name
) throws IncorrectOperationException
{
323 PsiManager manager
= element
.getManager();
324 PsiElementFactory factory
= JavaPsiFacade
.getInstance(manager
.getProject()).getElementFactory();
325 PsiIdentifier newNameIdentifier
= factory
.createIdentifier(name
);
326 return element
.replace(newNameIdentifier
);
329 public static boolean isDeprecatedByAnnotation(PsiModifierListOwner owner
) {
330 PsiModifierList modifierList
= owner
.getModifierList();
331 return modifierList
!= null && modifierList
.findAnnotation("java.lang.Deprecated") != null;
334 public static boolean isDeprecatedByDocTag(PsiDocCommentOwner owner
) {
335 PsiDocComment docComment
= owner
.getDocComment();
336 return docComment
!= null && docComment
.findTagByName("deprecated") != null;