2 * Copyright 2003-2006 Dave Griffith, Bas Leijdekkers
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 package com
.siyeh
.ig
.psiutils
;
18 import com
.intellij
.psi
.*;
19 import org
.jetbrains
.annotations
.NonNls
;
20 import org
.jetbrains
.annotations
.NotNull
;
21 import org
.jetbrains
.annotations
.Nullable
;
23 import java
.util
.HashMap
;
24 import java
.util
.HashSet
;
28 public class CollectionUtils
{
31 * @noinspection StaticCollection
33 @NonNls private static final Set
<String
> s_collectionClassesRequiringCapacity
=
34 new HashSet
<String
>(10);
36 * @noinspection StaticCollection
38 @NonNls private static final Set
<String
> s_allCollectionClasses
=
39 new HashSet
<String
>(10);
41 * @noinspection StaticCollection
43 @NonNls private static final Set
<String
> s_allCollectionClassesAndInterfaces
=
44 new HashSet
<String
>(10);
46 * @noinspection StaticCollection
48 @NonNls private static final Map
<String
, String
> s_interfaceForCollection
=
49 new HashMap
<String
, String
>(10);
52 s_collectionClassesRequiringCapacity
.add("java.util.BitSet");
53 s_collectionClassesRequiringCapacity
.add("java.util.Vector");
54 s_collectionClassesRequiringCapacity
.add("java.util.ArrayList");
55 s_collectionClassesRequiringCapacity
.add("java.util.HashMap");
56 s_collectionClassesRequiringCapacity
.add("java.util.LinkedHashMap");
57 s_collectionClassesRequiringCapacity
.add("java.util.WeakHashMap");
58 s_collectionClassesRequiringCapacity
.add("java.util.Hashtable");
59 s_collectionClassesRequiringCapacity
.add("java.util.HashSet");
60 s_collectionClassesRequiringCapacity
.add("java.util.LinkedHashSet");
61 s_collectionClassesRequiringCapacity
62 .add("com.sun.java.util.collections.BitSet");
63 s_collectionClassesRequiringCapacity
64 .add("com.sun.java.util.collections.Vector");
65 s_collectionClassesRequiringCapacity
66 .add("com.sun.java.util.collections.ArrayList");
67 s_collectionClassesRequiringCapacity
68 .add("com.sun.java.util.collections.HashMap");
69 s_collectionClassesRequiringCapacity
70 .add("com.sun.java.util.collections.Hashtable");
71 s_collectionClassesRequiringCapacity
72 .add("com.sun.java.util.collections.HashSet");
74 s_allCollectionClasses
.add("java.util.ArrayList");
75 s_allCollectionClasses
.add("java.util.EnumMap");
76 s_allCollectionClasses
.add("java.util.EnumSet");
77 s_allCollectionClasses
.add("java.util.HashMap");
78 s_allCollectionClasses
.add("java.util.HashSet");
79 s_allCollectionClasses
.add("java.util.Hashtable");
80 s_allCollectionClasses
.add("java.util.IdentityHashMap");
81 s_allCollectionClasses
.add("java.util.LinkedHashMap");
82 s_allCollectionClasses
.add("java.util.LinkedHashSet");
83 s_allCollectionClasses
.add("java.util.LinkedList");
84 s_allCollectionClasses
.add("java.util.PriorityQueue");
85 s_allCollectionClasses
.add("java.util.TreeMap");
86 s_allCollectionClasses
.add("java.util.TreeSet");
87 s_allCollectionClasses
.add("java.util.Vector");
88 s_allCollectionClasses
.add("java.util.WeakHashMap");
89 s_allCollectionClasses
.add("com.sun.java.util.collections.ArrayList");
90 s_allCollectionClasses
.add("com.sun.java.util.collections.HashMap");
91 s_allCollectionClasses
.add("com.sun.java.util.collections.HashSet");
92 s_allCollectionClasses
.add("com.sun.java.util.collections.Hashtable");
93 s_allCollectionClasses
.add("com.sun.java.util.collections.TreeMap");
94 s_allCollectionClasses
.add("com.sun.java.util.collections.TreeSet");
95 s_allCollectionClasses
.add("com.sun.java.util.collections.LinkedList");
96 s_allCollectionClasses
.add("com.sun.java.util.collections.Vector");
98 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractCollection");
99 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractList");
100 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractMap");
101 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractQueue");
102 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractSequentialList");
103 s_allCollectionClassesAndInterfaces
.add("java.util.AbstractSet");
104 s_allCollectionClassesAndInterfaces
.add("java.util.ArrayList");
105 s_allCollectionClassesAndInterfaces
.add("java.util.Collection");
106 s_allCollectionClassesAndInterfaces
.add("java.util.Dictionary");
107 s_allCollectionClassesAndInterfaces
.add("java.util.HashMap");
108 s_allCollectionClassesAndInterfaces
.add("java.util.HashSet");
109 s_allCollectionClassesAndInterfaces
.add("java.util.Hashtable");
110 s_allCollectionClassesAndInterfaces
.add("java.util.IdentityHashMap");
111 s_allCollectionClassesAndInterfaces
.add("java.util.LinkedHashMap");
112 s_allCollectionClassesAndInterfaces
.add("java.util.LinkedHashSet");
113 s_allCollectionClassesAndInterfaces
.add("java.util.LinkedList");
114 s_allCollectionClassesAndInterfaces
.add("java.util.List");
115 s_allCollectionClassesAndInterfaces
.add("java.util.Map");
116 s_allCollectionClassesAndInterfaces
.add("java.util.Queue");
117 s_allCollectionClassesAndInterfaces
.add("java.util.Set");
118 s_allCollectionClassesAndInterfaces
.add("java.util.SortedMap");
119 s_allCollectionClassesAndInterfaces
.add("java.util.SortedSet");
120 s_allCollectionClassesAndInterfaces
.add("java.util.Stack");
121 s_allCollectionClassesAndInterfaces
.add("java.util.TreeMap");
122 s_allCollectionClassesAndInterfaces
.add("java.util.TreeSet");
123 s_allCollectionClassesAndInterfaces
.add("java.util.Vector");
124 s_allCollectionClassesAndInterfaces
.add("java.util.WeakHashMap");
125 s_allCollectionClassesAndInterfaces
126 .add("com.sun.java.util.collections.ArrayList");
127 s_allCollectionClassesAndInterfaces
128 .add("com.sun.java.util.collections.Collection");
129 s_allCollectionClassesAndInterfaces
130 .add("com.sun.java.util.collections.HashMap");
131 s_allCollectionClassesAndInterfaces
132 .add("com.sun.java.util.collections.HashSet");
133 s_allCollectionClassesAndInterfaces
134 .add("com.sun.java.util.collections.Hashtable");
135 s_allCollectionClassesAndInterfaces
136 .add("com.sun.java.util.collections.LinkedList");
137 s_allCollectionClassesAndInterfaces
138 .add("com.sun.java.util.collections.List");
139 s_allCollectionClassesAndInterfaces
140 .add("com.sun.java.util.collections.Map");
141 s_allCollectionClassesAndInterfaces
142 .add("com.sun.java.util.collections.Set");
143 s_allCollectionClassesAndInterfaces
144 .add("com.sun.java.util.collections.SortedMap");
145 s_allCollectionClassesAndInterfaces
146 .add("com.sun.java.util.collections.SortedSet");
147 s_allCollectionClassesAndInterfaces
148 .add("com.sun.java.util.collections.TreeMap");
149 s_allCollectionClassesAndInterfaces
150 .add("com.sun.java.util.collections.TreeSet");
151 s_allCollectionClassesAndInterfaces
152 .add("com.sun.java.util.collections.Vector");
154 s_interfaceForCollection
.put("ArrayList", "List");
155 s_interfaceForCollection
.put("EnumMap", "Map");
156 s_interfaceForCollection
.put("EnumSet", "Set");
157 s_interfaceForCollection
.put("HashMap", "Map");
158 s_interfaceForCollection
.put("HashSet", "Set");
159 s_interfaceForCollection
.put("Hashtable", "Map");
160 s_interfaceForCollection
.put("IdentityHashMap", "Map");
161 s_interfaceForCollection
.put("LinkedHashMap", "Map");
162 s_interfaceForCollection
.put("LinkedHashSet", "Set");
163 s_interfaceForCollection
.put("LinkedList", "List");
164 s_interfaceForCollection
.put("PriorityQueue", "Queue");
165 s_interfaceForCollection
.put("TreeMap", "Map");
166 s_interfaceForCollection
.put("TreeSet", "SortedSet");
167 s_interfaceForCollection
.put("Vector", "List");
168 s_interfaceForCollection
.put("WeakHashMap", "Map");
169 s_interfaceForCollection
.put("java.util.ArrayList", "java.util.List");
170 s_interfaceForCollection
.put("java.util.EnumMap", "java.util.Map");
171 s_interfaceForCollection
.put("java.util.EnumSet", "java.util.Set");
172 s_interfaceForCollection
.put("java.util.HashMap", "java.util.Map");
173 s_interfaceForCollection
.put("java.util.HashSet", "java.util.Set");
174 s_interfaceForCollection
.put("java.util.Hashtable", "java.util.Map");
175 s_interfaceForCollection
176 .put("java.util.IdentityHashMap", "java.util.Map");
177 s_interfaceForCollection
178 .put("java.util.LinkedHashMap", "java.util.Map");
179 s_interfaceForCollection
180 .put("java.util.LinkedHashSet", "java.util.Set");
181 s_interfaceForCollection
.put("java.util.LinkedList", "java.util.List");
182 s_interfaceForCollection
.put("java.util.PriorityQueue",
184 s_interfaceForCollection
.put("java.util.TreeMap", "java.util.Map");
185 s_interfaceForCollection
.put("java.util.TreeSet", "java.util.Set");
186 s_interfaceForCollection
.put("java.util.Vector", "java.util.List");
187 s_interfaceForCollection
.put("java.util.WeakHashMap", "java.util.Map");
188 s_interfaceForCollection
.put("com.sun.java.util.collections.HashSet",
189 "com.sun.java.util.collections.Set");
190 s_interfaceForCollection
.put("com.sun.java.util.collections.TreeSet",
191 "com.sun.java.util.collections.Set");
192 s_interfaceForCollection
.put("com.sun.java.util.collections.Vector",
193 "com.sun.java.util.collections.List");
194 s_interfaceForCollection
.put("com.sun.java.util.collections.ArrayList",
195 "com.sun.java.util.collections.List");
196 s_interfaceForCollection
.put("com.sun.java.util.collections.LinkedList",
197 "com.sun.java.util.collections.List");
198 s_interfaceForCollection
.put("com.sun.java.util.collections.TreeMap",
199 "com.sun.java.util.collections.Map");
200 s_interfaceForCollection
.put("com.sun.java.util.collections.HashMap",
201 "com.sun.java.util.collections.Map");
202 s_interfaceForCollection
.put("com.sun.java.util.collections.Hashtable",
203 "com.sun.java.util.collections.Map");
206 private CollectionUtils(){
210 public static boolean isCollectionWithInitialCapacity(
211 @Nullable PsiType type
){
212 if(!(type
instanceof PsiClassType
)){
215 final PsiClassType classType
= (PsiClassType
) type
;
216 final PsiClass resolved
= classType
.resolve();
217 if(resolved
== null){
220 final String className
= resolved
.getQualifiedName();
221 return s_collectionClassesRequiringCapacity
.contains(className
);
224 public static boolean isCollectionClass(@Nullable PsiType type
){
225 if(!(type
instanceof PsiClassType
)){
228 final PsiClassType classType
= (PsiClassType
) type
;
229 final PsiClass resolved
= classType
.resolve();
230 if(resolved
== null){
233 return isCollectionClass(resolved
);
236 public static boolean isCollectionClass(PsiClass aClass
){
237 final String className
= aClass
.getQualifiedName();
238 return s_allCollectionClasses
.contains(className
);
241 public static boolean isCollectionClassOrInterface(@Nullable PsiType type
){
242 if(!(type
instanceof PsiClassType
)){
245 final PsiClassType classType
= (PsiClassType
) type
;
246 final PsiClass resolved
= classType
.resolve();
247 if(resolved
== null){
250 return isCollectionClassOrInterface(resolved
);
253 public static boolean isCollectionClassOrInterface(PsiClass aClass
) {
254 return isCollectionClassOrInterface(aClass
, new HashSet
<PsiClass
>());
258 * alreadyChecked set to avoid infinite loop in constructs like:
259 * class C extends C {}
261 private static boolean isCollectionClassOrInterface(
262 PsiClass aClass
, Set
<PsiClass
> visitedClasses
){
263 if (!visitedClasses
.add(aClass
)){
266 final String className
= aClass
.getQualifiedName();
267 if (s_allCollectionClassesAndInterfaces
.contains(className
)){
270 final PsiClass
[] supers
= aClass
.getSupers();
271 for (PsiClass aSuper
: supers
){
272 if (isCollectionClassOrInterface(aSuper
, visitedClasses
)){
279 public static boolean isWeakCollectionClass(@Nullable PsiType type
){
280 if(!(type
instanceof PsiClassType
)){
283 final String typeText
= type
.getCanonicalText();
284 if(typeText
== null){
287 return "java.util.WeakHashMap".equals(typeText
);
290 public static boolean isConstantEmptyArray(@NotNull PsiField field
){
291 if(!field
.hasModifierProperty(PsiModifier
.STATIC
) ||
292 !field
.hasModifierProperty(PsiModifier
.FINAL
)){
295 return isEmptyArray(field
);
298 public static boolean isEmptyArray(PsiField field
) {
299 final PsiExpression initializer
= field
.getInitializer();
300 if (initializer
instanceof PsiArrayInitializerExpression
) {
301 final PsiArrayInitializerExpression arrayInitializerExpression
=
302 (PsiArrayInitializerExpression
)initializer
;
303 final PsiExpression
[] initializers
=
304 arrayInitializerExpression
.getInitializers();
305 return initializers
.length
== 0;
307 return ExpressionUtils
.isZeroLengthArrayConstruction(initializer
);
310 public static boolean isArrayOrCollectionField(@NotNull PsiField field
) {
311 final PsiType type
= field
.getType();
312 if (isCollectionClassOrInterface(type
)) {
315 if (!(type
instanceof PsiArrayType
)) {
318 // constant empty arrays are ignored.
319 return !isConstantEmptyArray(field
);
323 public static String
getInterfaceForClass(String name
){
324 final int paramStart
= name
.indexOf((int) '<');
328 baseName
= name
.substring(0, paramStart
);
329 baseName
= baseName
.trim();
330 arg
= name
.substring(paramStart
);
335 return s_interfaceForCollection
.get(baseName
) + arg
;