1 | /* |
---|---|
2 | * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. |
3 | * Copyright (C) 2011, 2013-2020 The JavaParser Team. |
4 | * |
5 | * This file is part of JavaParser. |
6 | * |
7 | * JavaParser can be used either under the terms of |
8 | * a) the GNU Lesser General Public License as published by |
9 | * the Free Software Foundation, either version 3 of the License, or |
10 | * (at your option) any later version. |
11 | * b) the terms of the Apache License |
12 | * |
13 | * You should have received a copy of both licenses in LICENCE.LGPL and |
14 | * LICENCE.APACHE. Please refer to those files for details. |
15 | * |
16 | * JavaParser is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU Lesser General Public License for more details. |
20 | */ |
21 | |
22 | package com.github.javaparser.resolution.declarations; |
23 | |
24 | |
25 | import com.github.javaparser.resolution.types.ResolvedType; |
26 | |
27 | import java.util.List; |
28 | import java.util.Optional; |
29 | |
30 | /** |
31 | * Declaration of a type parameter. |
32 | * For example: |
33 | * <p> |
34 | * class A<E extends String>{} |
35 | * </p> |
36 | * <p> |
37 | * In this case <b>E</b> would be a type parameter. |
38 | * |
39 | * @author Federico Tomassetti |
40 | */ |
41 | public interface ResolvedTypeParameterDeclaration extends ResolvedTypeDeclaration { |
42 | |
43 | /** |
44 | * Instantiate a TypeParameter defined on a Type with the given data. |
45 | */ |
46 | static ResolvedTypeParameterDeclaration onType(final String name, String classQName, List<Bound> bounds) { |
47 | return new ResolvedTypeParameterDeclaration() { |
48 | @Override |
49 | public String getName() { |
50 | return name; |
51 | } |
52 | |
53 | @Override |
54 | public boolean declaredOnType() { |
55 | return true; |
56 | } |
57 | |
58 | @Override |
59 | public boolean declaredOnMethod() { |
60 | return false; |
61 | } |
62 | |
63 | @Override |
64 | public boolean declaredOnConstructor() { |
65 | return false; |
66 | } |
67 | |
68 | @Override |
69 | public String getContainerQualifiedName() { |
70 | return classQName; |
71 | } |
72 | |
73 | @Override |
74 | public String getContainerId() { |
75 | return classQName; |
76 | } |
77 | |
78 | @Override |
79 | public ResolvedTypeParametrizable getContainer() { |
80 | return null; |
81 | } |
82 | |
83 | @Override |
84 | public List<Bound> getBounds() { |
85 | return bounds; |
86 | } |
87 | |
88 | @Override |
89 | public String toString() { |
90 | return "TypeParameter onType " + name; |
91 | } |
92 | |
93 | @Override |
94 | public Optional<ResolvedReferenceTypeDeclaration> containerType() { |
95 | throw new UnsupportedOperationException(); |
96 | } |
97 | }; |
98 | } |
99 | |
100 | /** |
101 | * Name of the type parameter. |
102 | */ |
103 | String getName(); |
104 | |
105 | /** |
106 | * Is the type parameter been defined on a type? |
107 | */ |
108 | default boolean declaredOnType() { |
109 | return (getContainer() instanceof ResolvedReferenceTypeDeclaration); |
110 | } |
111 | |
112 | /** |
113 | * Is the type parameter been defined on a method? |
114 | */ |
115 | default boolean declaredOnMethod() { |
116 | return (getContainer() instanceof ResolvedMethodDeclaration); |
117 | } |
118 | |
119 | /** |
120 | * Is the type parameter been defined on a constructor? |
121 | */ |
122 | default boolean declaredOnConstructor() { |
123 | return (getContainer() instanceof ResolvedConstructorDeclaration); |
124 | } |
125 | |
126 | /** |
127 | * The package name of the type bound(s). |
128 | * This is unsupported because there is no package for a Type Parameter, only for its container. |
129 | */ |
130 | default String getPackageName() { |
131 | throw new UnsupportedOperationException(); |
132 | } |
133 | |
134 | /** |
135 | * The class(es) wrapping the type bound(s). |
136 | * This is unsupported because there is no class for a Type Parameter, only for its container. |
137 | */ |
138 | default String getClassName() { |
139 | throw new UnsupportedOperationException(); |
140 | } |
141 | |
142 | /** |
143 | * The qualified name of the Type Parameter. |
144 | * It is composed by the qualified name of the container followed by a dot and the name of the Type Parameter. |
145 | * The qualified name of a method is its qualified signature. |
146 | */ |
147 | default String getQualifiedName() { |
148 | return String.format("%s.%s", getContainerId(), getName()); |
149 | } |
150 | |
151 | /** |
152 | * The qualified name of the container. |
153 | */ |
154 | String getContainerQualifiedName(); |
155 | |
156 | /** |
157 | * The ID of the container. See TypeContainer.getId |
158 | */ |
159 | String getContainerId(); |
160 | |
161 | /** |
162 | * The TypeParametrizable of the container. Can be either a ReferenceTypeDeclaration or a MethodLikeDeclaration |
163 | */ |
164 | ResolvedTypeParametrizable getContainer(); |
165 | |
166 | /** |
167 | * The bounds specified for the type parameter. |
168 | * For example: |
169 | * "extends A" or "super B" |
170 | */ |
171 | List<Bound> getBounds(); |
172 | |
173 | /** |
174 | * Has the type parameter a lower bound? |
175 | */ |
176 | default boolean hasLowerBound() { |
177 | for (Bound b : getBounds()) { |
178 | if (b.isExtends()) { |
179 | return true; |
180 | } |
181 | } |
182 | return false; |
183 | } |
184 | |
185 | /** |
186 | * Has the type parameter an upper bound? |
187 | */ |
188 | default boolean hasUpperBound() { |
189 | for (Bound b : getBounds()) { |
190 | if (b.isSuper()) { |
191 | return true; |
192 | } |
193 | } |
194 | return false; |
195 | } |
196 | |
197 | /** |
198 | * Get the type used as lower bound. |
199 | * |
200 | * @throws IllegalStateException if there is no lower bound |
201 | */ |
202 | default ResolvedType getLowerBound() { |
203 | for (Bound b : getBounds()) { |
204 | if (b.isExtends()) { |
205 | return b.getType(); |
206 | } |
207 | } |
208 | throw new IllegalStateException(); |
209 | } |
210 | |
211 | /** |
212 | * Get the type used as upper bound. |
213 | * |
214 | * @throws IllegalStateException if there is no upper bound |
215 | */ |
216 | default ResolvedType getUpperBound() { |
217 | for (Bound b : getBounds()) { |
218 | if (b.isSuper()) { |
219 | return b.getType(); |
220 | } |
221 | } |
222 | throw new IllegalStateException(); |
223 | } |
224 | |
225 | /** |
226 | * A Bound on a Type Parameter. |
227 | */ |
228 | class Bound { |
229 | private boolean extendsBound; |
230 | private ResolvedType type; |
231 | |
232 | private Bound(boolean extendsBound, ResolvedType type) { |
233 | this.extendsBound = extendsBound; |
234 | this.type = type; |
235 | } |
236 | |
237 | /** |
238 | * Create an extends bound with the given type: |
239 | * <p> |
240 | * extends "given type" |
241 | * </p> |
242 | */ |
243 | public static Bound extendsBound(ResolvedType type) { |
244 | return new Bound(true, type); |
245 | } |
246 | |
247 | /** |
248 | * Create a super bound with the given type: |
249 | * <p> |
250 | * super "given type" |
251 | * </p> |
252 | */ |
253 | public static Bound superBound(ResolvedType type) { |
254 | return new Bound(false, type); |
255 | } |
256 | |
257 | /** |
258 | * Get the type used in the Bound. |
259 | */ |
260 | public ResolvedType getType() { |
261 | return type; |
262 | } |
263 | |
264 | /** |
265 | * Is this an extends bound? |
266 | */ |
267 | public boolean isExtends() { |
268 | return extendsBound; |
269 | } |
270 | |
271 | /** |
272 | * Is this a super bound? |
273 | */ |
274 | public boolean isSuper() { |
275 | return !isExtends(); |
276 | } |
277 | |
278 | @Override |
279 | public String toString() { |
280 | return "Bound{" + |
281 | "extendsBound=" + extendsBound + |
282 | ", type=" + type + |
283 | '}'; |
284 | } |
285 | |
286 | @Override |
287 | public boolean equals(Object o) { |
288 | if (this == o) return true; |
289 | if (o == null || getClass() != o.getClass()) return false; |
290 | |
291 | Bound bound = (Bound) o; |
292 | |
293 | if (extendsBound != bound.extendsBound) return false; |
294 | return type != null ? type.equals(bound.type) : bound.type == null; |
295 | } |
296 | |
297 | @Override |
298 | public int hashCode() { |
299 | int result = (extendsBound ? 1 : 0); |
300 | result = 31 * result + (type != null ? type.hashCode() : 0); |
301 | return result; |
302 | } |
303 | } |
304 | |
305 | } |
306 |
Members