• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pmd / pmd / #3722

pending completion
#3722

push

github actions

adangel
Suppress MissingOverride for Chars::isEmpty (#4291)

67270 of 127658 relevant lines covered (52.7%)

0.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.67
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/JTypeMirror.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.lang.java.types;
6

7
import java.util.Collections;
8
import java.util.List;
9
import java.util.Set;
10
import java.util.function.Function;
11
import java.util.function.Predicate;
12
import java.util.stream.Stream;
13

14
import org.checkerframework.checker.nullness.qual.NonNull;
15
import org.checkerframework.checker.nullness.qual.Nullable;
16
import org.pcollections.PSet;
17

18
import net.sourceforge.pmd.annotation.Experimental;
19
import net.sourceforge.pmd.internal.util.AssertionUtil;
20
import net.sourceforge.pmd.lang.java.ast.TypeNode;
21
import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
22
import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol;
23
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
24
import net.sourceforge.pmd.lang.java.symbols.JTypeDeclSymbol;
25
import net.sourceforge.pmd.lang.java.symbols.JTypeParameterSymbol;
26
import net.sourceforge.pmd.lang.java.symbols.SymbolicValue.SymAnnot;
27
import net.sourceforge.pmd.lang.java.types.JPrimitiveType.PrimitiveTypeKind;
28
import net.sourceforge.pmd.lang.java.types.TypeOps.Convertibility;
29
import net.sourceforge.pmd.lang.java.types.internal.infer.InferenceVar;
30

31
/**
32
 * Type mirrors represent Java types. They are created by a {@link TypeSystem}
33
 * from {@linkplain JTypeDeclSymbol symbols}, a layer of abstraction above reflection
34
 * classes.
35
 *
36
 * <p>Type mirrors can be obtained {@linkplain TypesFromReflection from reflected types},
37
 * directly {@linkplain TypeNode#getTypeMirror() from nodes}, or from
38
 * arbitrary symbols (see {@link TypeSystem}).
39
 *
40
 * <p>Type mirrors are primarily divided between {@linkplain JPrimitiveType primitive types}
41
 * and reference types. Reference types can be of one of those kinds:
42
 * <ul>
43
 * <li>{@linkplain JClassType class or interface types}
44
 * <li>{@linkplain JArrayType array types}
45
 * <li>{@linkplain JIntersectionType intersection types}
46
 * <li>{@linkplain JTypeVar type variables}
47
 * </ul>
48
 *
49
 * <p>{@linkplain JWildcardType Wildcard types} implement this interface,
50
 * but are not really types, they can only occur as type arguments of a
51
 * class type.
52
 *
53
 * <p>A few other special types do not implement one of these public interfaces:
54
 * <ul>
55
 * <li>{@linkplain TypeSystem#NULL_TYPE The null type}
56
 * <li>{@linkplain TypeSystem#ERROR The error type}
57
 * <li>{@linkplain TypeSystem#UNKNOWN The unresolved type}
58
 * </ul>
59
 *
60
 * <p>Lastly, types may be {@linkplain InferenceVar inference variables},
61
 * which <i>should not ever occur</i> outside of a type inference
62
 * run and should be ignored when querying the AST. If you find an ivar,
63
 * report a bug.
64
 *
65
 * <p>Note that implementing this type hierarchy outside of this package
66
 * is not a supported usage of this API. The API is built to work with any
67
 * symbol implementation, and that is its extension point.
68
 */
69
public interface JTypeMirror extends JTypeVisitable {
70
    // TODO: unstable stuff (@Experimental)
71
    //  - Member access:
72
    //    - #getDeclaredField
73
    //    - #getDeclaredClass
74
    //  - In JWildcardType, the specification of some methods is unstable:
75
    //    - #isSubtypeOf/#isConvertibleTo
76
    //    - #getErasure
77

78
    // TODO figure out what parts of TypeOps/TypeConversion are internal
79
    //  - problem is that parts of those access package-private API, eg
80
    //  to implement capture.
81

82
    /**
83
     * Returns the type system that built this type.
84
     */
85
    TypeSystem getTypeSystem();
86

87

88
    /**
89
     * Return a list of annotations on this type. Annotations can be written
90
     * on nearly any type (eg {@code @A Out.@B In<@C T>}, {@code @A ? extends @B Up}).
91
     *
92
     * <p>For {@link JTypeVar}, this includes both the annotations defined
93
     * on the type var and those defined at use site. For instance
94
     * <pre>{@code
95
     *    <@A T> void accept(@B T t);
96
     * }</pre>
97
     * The T type var will have annotation {@code @A} in the symbol
98
     * ({@link JTypeParameterSymbol#getDeclaredAnnotations()})
99
     * and in the type var that is in the {@link JMethodSig#getTypeParameters()}.
100
     * In the formal parameter, the type var will have annotations {@code @B @A}.
101
     */
102
    // todo annotations do not participate in equality of types.
103
    PSet<SymAnnot> getTypeAnnotations();
104

105

106
    /**
107
     * Returns true if this type is the same type or a subtype of the
108
     * given type. Note that for convenience, this returns true if both
109
     * types are primitive, and this type is convertible to the other
110
     * through primitive widening. See {@link Convertibility#bySubtyping()}.
111
     *
112
     * @throws NullPointerException If the argument is null
113
     */
114
    default boolean isSubtypeOf(@NonNull JTypeMirror other) {
115
        return isConvertibleTo(other).bySubtyping();
1✔
116
    }
117

118
    /**
119
     * Tests this type's convertibility to the other type. See
120
     * {@link Convertibility} for a description of the results.
121
     *
122
     * <p>Note that this does not check for boxing/unboxing conversions.
123
     *
124
     * @throws NullPointerException If the argument is null
125
     */
126
    default Convertibility isConvertibleTo(@NonNull JTypeMirror other) {
127
        return TypeOps.isConvertible(this, other);
1✔
128
    }
129

130

131
    /**
132
     * Returns the set of (nominal) supertypes of this type.
133
     * If this is a primitive type, returns the set of other
134
     * primitives to which this type is convertible by widening
135
     * conversion (eg for {@code long} returns {@code {long, float, double}}).
136
     *
137
     * <p>The returned set always contains this type, so is
138
     * never empty. Ordering is stable, though unspecified.
139
     *
140
     * <p>Note that this set contains {@link TypeSystem#OBJECT}
141
     * for interfaces too.
142
     *
143
     * @throws UnsupportedOperationException If this is the null type
144
     */
145
    default Set<JTypeMirror> getSuperTypeSet() {
146
        return TypeOps.getSuperTypeSet(this);
1✔
147
    }
148

149

150
    /**
151
     * Returns the erasure of this type. Erasure is defined by JLS§4.6,
152
     * an adapted definition follows:
153
     *
154
     * <blockquote>
155
     * <ol>
156
     * <li>The erasure of a parameterized type (§4.5) {@literal G<T1,...,Tn>} is |G|.
157
     * <li>The erasure of a nested type T.C is |T|.C.
158
     * <li>The erasure of an array type T[] is |T|[].
159
     * <li>The erasure of a type variable (§4.4) is the erasure of its upper bound.
160
     * <li>The erasure of an intersection type is the erasure of its leftmost component.
161
     * <li>The erasure of every other type is the type itself.
162
     * </ol>
163
     * </blockquote>
164
     *
165
     * <p>The JVM representation of a type is in general the symbol
166
     * of its erasure. So to get a {@link Class} instance for the runtime
167
     * representation of a type, you should do {@code t.getErasure().getSymbol()}.
168
     * The erasure procedure gets rid of types that have no symbol (except
169
     * if {@code t} is a wildcard type, or the {@link TypeSystem#NULL_TYPE})
170
     */
171
    default JTypeMirror getErasure() {
172
        return this;
1✔
173
    }
174

175

176
    /**
177
     * Returns the symbol declaring this type. {@linkplain #isReifiable() Reifiable}
178
     * types present a symbol, and some other types too. This method's
179
     * return value depends on this type:
180
     * <ul>
181
     * <li>{@link JClassType}: a {@link JClassSymbol}, always (even if not reifiable)
182
     * <li>{@link JPrimitiveType}: a {@link JClassSymbol}, always
183
     * <li>{@link JArrayType}: a {@link JClassSymbol}, if the element type does present a symbol.
184
     * <li>{@link JTypeVar}: a {@link JTypeParameterSymbol}, or null if this is a capture variable.
185
     * Note that the erasure yields a different symbol (eg Object for unbounded tvars).
186
     * <li>{@link JIntersectionType}: null, though their erasure always
187
     * presents a symbol.
188
     * <li>{@link JWildcardType}, {@link TypeSystem#NULL_TYPE the null type}: null, always
189
     * </ul>
190
     *
191
     * <p>Note that type annotations are not reflected on the
192
     * symbol, but only on the type.
193
     */
194
    default @Nullable JTypeDeclSymbol getSymbol() {
195
        return null;
1✔
196
    }
197

198

199
    /**
200
     * Returns the primitive wrapper type of this type, if this is a
201
     * primitive type. Otherwise returns this type unchanged.
202
     */
203
    default JTypeMirror box() {
204
        return this;
1✔
205
    }
206

207

208
    /**
209
     * Returns the unboxed version of this type. Returns this type unchanged
210
     * if this is not a primitive wrapper type.
211
     */
212
    default JTypeMirror unbox() {
213
        return this;
1✔
214
    }
215

216

217
    /**
218
     * Returns the most specific declared supertype of this type whose erasure
219
     * is the same as that of the parameter. E.g. for {@code Enum<E>, Comparable},
220
     * returns {@code Comparable<E>}.
221
     *
222
     * <p>Returns null if that can't be found, meaning that the given type
223
     * is not a supertype of this type.
224
     */
225
    default @Nullable JTypeMirror getAsSuper(@NonNull JClassSymbol symbol) {
226
        return TypeOps.asSuper(this, symbol);
1✔
227
    }
228

229

230

231
    /**
232
     * Returns true if this type is reifiable. If so, its {@link #getSymbol() symbol}
233
     * will not be null (the reverse is not necessarily true).
234
     *
235
     * <p>Reifiable types are those types that are completely available
236
     * at run time. See also <a href="https://docs.oracle.com/javase/specs/jls/se13/html/jls-4.html#jls-4.7">JLS§4.7</a>
237
     */
238
    default boolean isReifiable() {
239
        if (this instanceof JPrimitiveType) {
1✔
240
            return true;
1✔
241
        } else if (this instanceof JArrayType) {
1✔
242
            return ((JArrayType) this).getElementType().isReifiable();
1✔
243
        }
244

245
        return this instanceof JClassType && TypeOps.allArgsAreUnboundedWildcards(((JClassType) this).getTypeArgs());
1✔
246
    }
247

248

249
    /** Returns true if this type is a {@linkplain JPrimitiveType primitive type}. */
250
    default boolean isPrimitive() {
251
        return false; // overridden in JPrimitiveType
1✔
252
    }
253

254
    /** Returns true if this type is the primitive type of the given kind in its type system. */
255
    default boolean isPrimitive(PrimitiveTypeKind kind) {
256
        return false; // overridden in JPrimitiveType
1✔
257
    }
258

259
    /**
260
     * Returns true if this type is a {@linkplain JPrimitiveType primitive type}
261
     * of a floating point type.
262
     */
263
    default boolean isFloatingPoint() {
264
        return false; // overridden in JPrimitiveType
1✔
265
    }
266

267
    /**
268
     * Returns true if this type is a {@linkplain JPrimitiveType primitive type}
269
     * of an integral type.
270
     */
271
    default boolean isIntegral() {
272
        return false; // overridden in JPrimitiveType
×
273
    }
274

275

276
    /** Returns true if this type is a {@linkplain JTypeVar type variable}. */
277
    default boolean isTypeVariable() {
278
        return this instanceof JTypeVar;
1✔
279
    }
280

281
    /**
282
     * Returns true if this type is a boxed primitive type. This is a {@link JClassType},
283
     * whose {@link #unbox()} method returns a {@link JPrimitiveType}.
284
     */
285
    default boolean isBoxedPrimitive() {
286
        return unbox() != this; // NOPMD CompareObjectsWithEquals
1✔
287
    }
288

289

290
    /**
291
     * Returns true if this is a primitive numeric type. The only
292
     * non-numeric primitive type is {@link TypeSystem#BOOLEAN}.
293
     */
294
    default boolean isNumeric() {
295
        return false;
1✔
296
    }
297

298

299
    /** Returns true if this is a {@linkplain JClassType class or interface type}. */
300
    default boolean isClassOrInterface() {
301
        return this instanceof JClassType;
1✔
302
    }
303

304
    /**
305
     * Returns true if this is {@link TypeSystem#OBJECT}.
306
     */
307
    default boolean isTop() {
308
        return false; // overridden
1✔
309
    }
310

311

312
    /**
313
     * Returns true if this is {@link TypeSystem#NULL_TYPE}.
314
     */
315
    default boolean isBottom() {
316
        return false; // overridden
1✔
317
    }
318

319
    /**
320
     * Returns true if this is {@link TypeSystem#NO_TYPE}, ie {@code void}.
321
     */
322
    default boolean isVoid() {
323
        return this == getTypeSystem().NO_TYPE; // NOPMD CompareObjectsWithEquals
1✔
324
    }
325

326
    /** Returns true if this is an {@linkplain JArrayType array type}. */
327
    default boolean isArray() {
328
        return this instanceof JArrayType;
1✔
329
    }
330

331
    /**
332
     * Returns true if this represents the *declaration* of a generic
333
     * class or interface and not some parameterization. This is the
334
     * "canonical" form of a parameterized type.
335
     *
336
     * <p>In that case, the {@link JClassType#getTypeArgs()} is the same
337
     * as {@link JClassType#getFormalTypeParams()}.
338
     *
339
     * <p>The generic type declaration of a generic type may be obtained
340
     * with {@link JClassType#getGenericTypeDeclaration()}.
341
     */
342
    default boolean isGenericTypeDeclaration() {
343
        return false;
1✔
344
    }
345

346

347

348
    /**
349
     * Returns true if this type is a generic class type.
350
     * This means, the symbol declares some type parameters,
351
     * which is also true for erased types, including raw types.
352
     *
353
     * <p>For example, {@code List}, {@code List<T>}, and {@code List<String>}
354
     * are generic, but {@code String} is not.
355
     *
356
     * @see JClassType#isGeneric().
357
     */
358
    default boolean isGeneric() {
359
        return false;
×
360
    }
361

362

363

364
    /**
365
     * Returns true if this type is generic, and it it neither {@linkplain #isRaw() raw},
366
     * nor a {@linkplain JClassType#isGenericTypeDeclaration() generic type declaration}.
367
     *
368
     * <p>E.g. returns true for {@code List<String>} or {@code Enum<KeyCode>},
369
     * but not for {@code List} (raw type), {@code List<T>} (generic type declaration),
370
     * or {@code KeyCode} (not a generic type).
371
     */
372
    default boolean isParameterizedType() {
373
        return false;
1✔
374
    }
375

376

377
    /**
378
     * Returns true if this is a raw type. This may be
379
     * <ul>
380
     * <li>A generic class or interface type for which no type arguments
381
     * were provided
382
     * <li>An array type whose element type is raw
383
     * <li>A non-static member type of a raw type
384
     * </ul>
385
     *
386
     * <p>https://docs.oracle.com/javase/specs/jls/se11/html/jls-4.html#jls-4.8
387
     *
388
     * @see JClassType#isRaw()
389
     */
390
    default boolean isRaw() {
391
        return false;
1✔
392
    }
393

394
    /**
395
     * Returns true if this is an interface type. Annotations are also
396
     * interface types.
397
     */
398
    default boolean isInterface() {
399
        JTypeDeclSymbol sym = getSymbol();
1✔
400
        return sym != null && sym.isInterface();
1✔
401
    }
402

403

404
    /**
405
     * Returns a stream of method signatures declared in and inherited
406
     * by this type. Method signatures are created on-demand by this
407
     * method, they're not reused between calls. This stream does not
408
     * include constructors.
409
     *
410
     * @param prefilter Filter selecting symbols for which a signature
411
     *                  should be created and yielded by the stream
412
     *
413
     * @experimental streams are a bit impractical when it comes to
414
     *     configuring the filter. Possibly a specialized API should be introduced.
415
     *     We need to support the use cases of the symbol table, ie filter by name + accessibility + staticity,
416
     *     and also possibly use cases for rules, like getting a method from
417
     *     a known signature. See also {@link JClassType#getDeclaredMethod(JExecutableSymbol)},
418
     *     which looks like this. Unifying this API would be nice.
419
     */
420
    @Experimental
421
    default Stream<JMethodSig> streamMethods(Predicate<? super JMethodSymbol> prefilter) {
422
        return Stream.empty();
1✔
423
    }
424

425
    /**
426
     * Like {@link #streamMethods(Predicate) streamMethods}, but does
427
     * not recurse into supertypes. Note that only class and array types
428
     * declare methods themselves.
429
     *
430
     * @experimental See {@link #streamMethods(Predicate)}
431
     *
432
     * @see #streamMethods(Predicate)
433
     */
434
    @Experimental
435
    default Stream<JMethodSig> streamDeclaredMethods(Predicate<? super JMethodSymbol> prefilter) {
436
        return Stream.empty();
×
437
    }
438

439

440
    /**
441
     * Returns a list of all the declared constructors for this type.
442
     * Abstract types like type variables and interfaces have no constructors.
443
     */
444
    @Experimental
445
    default List<JMethodSig> getConstructors() {
446
        return Collections.emptyList();
1✔
447
    }
448

449

450
    @Override
451
    JTypeMirror subst(Function<? super SubstVar, ? extends @NonNull JTypeMirror> subst);
452

453

454
    /**
455
     * Returns a type mirror that is equal to this instance but has different
456
     * type annotations. Note that some types ignore this method and return
457
     * themselves without changing. Eg the null type cannot be annotated.
458
     *
459
     * @param newTypeAnnots New type annotations (not null)
460
     *
461
     * @return A new type, maybe this one
462
     */
463
    JTypeMirror withAnnotations(PSet<SymAnnot> newTypeAnnots);
464

465
    /**
466
     * Returns a type mirror that is equal to this instance but has one
467
     * more type annotation.
468
     *
469
     * @see #withAnnotations(PSet)
470
     */
471
    default JTypeMirror addAnnotation(@NonNull SymAnnot newAnnot) {
472
        AssertionUtil.requireParamNotNull("annot", newAnnot);
1✔
473
        return withAnnotations(getTypeAnnotations().plus(newAnnot));
1✔
474
    }
475

476

477
    /**
478
     * Returns true if the object is a type equivalent to this one. A
479
     * few kinds of types use reference identity, like captured type
480
     * variables, or the null type. A few special types are represented
481
     * by constants (see {@link TypeSystem}). Apart from those, types
482
     * should always be compared using this method. or {@link TypeOps#isSameType(JTypeMirror, JTypeMirror)}
483
     * (which is null-safe).
484
     *
485
     * <p>Note that types belonging to different type systems do <i>not</i>
486
     * test equal. The type system object is global to the analysis though,
487
     * so this should not ever happen in rules.
488
     *
489
     * @param o {@inheritDoc}
490
     *
491
     * @return {@inheritDoc}
492
     *
493
     * @implSpec This method should be implemented with
494
     *     {@link TypeOps#isSameType(JTypeMirror, JTypeMirror)},
495
     *     and perform no side-effects on inference variables.
496
     */
497
    @Override
498
    boolean equals(Object o);
499

500

501
    /**
502
     * The toString of type mirrors prints useful debug information,
503
     * but shouldn't be relied on anywhere, as it may change anytime.
504
     * Use {@link TypePrettyPrint} to display types.
505
     */
506
    @Override
507
    String toString();
508

509
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc