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

pmd / pmd / 43

20 Jun 2025 06:39PM UTC coverage: 78.375% (-0.002%) from 78.377%
43

push

github

adangel
Fix #1639 #5832: Use filtered comment text for UnnecessaryImport (#5833)

Merged pull request #5833 from adangel:java/issue-5832-unnecessaryimport

17714 of 23438 branches covered (75.58%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 1 file covered. (100.0%)

109 existing lines in 17 files now uncovered.

38908 of 48807 relevant lines covered (79.72%)

0.81 hits per line

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

85.09
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/types/internal/infer/ExprOps.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.internal.infer;
6

7
import static net.sourceforge.pmd.lang.java.types.TypeConversion.capture;
8
import static net.sourceforge.pmd.lang.java.types.internal.InternalMethodTypeItf.cast;
9
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
10

11
import java.lang.reflect.Modifier;
12
import java.util.Collections;
13
import java.util.List;
14
import java.util.function.Predicate;
15
import java.util.function.Supplier;
16
import java.util.stream.Collectors;
17

18
import org.checkerframework.checker.nullness.qual.NonNull;
19
import org.checkerframework.checker.nullness.qual.Nullable;
20

21
import net.sourceforge.pmd.lang.java.ast.JavaNode;
22
import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
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.types.JClassType;
26
import net.sourceforge.pmd.lang.java.types.JMethodSig;
27
import net.sourceforge.pmd.lang.java.types.JTypeMirror;
28
import net.sourceforge.pmd.lang.java.types.JTypeVar;
29
import net.sourceforge.pmd.lang.java.types.Substitution;
30
import net.sourceforge.pmd.lang.java.types.TypeOps;
31
import net.sourceforge.pmd.lang.java.types.TypeSystem;
32
import net.sourceforge.pmd.lang.java.types.TypingContext;
33
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.BranchingMirror;
34
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.FunctionalExprMirror;
35
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror;
36
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.InvocationMirror.MethodCtDecl;
37
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.LambdaExprMirror;
38
import net.sourceforge.pmd.lang.java.types.internal.infer.ExprMirror.MethodRefMirror;
39
import net.sourceforge.pmd.util.CollectionUtil;
40

41
public final class ExprOps {
1✔
42

43
    private final Infer infer;
44
    private final TypeSystem ts;
45

46
    ExprOps(Infer infer) {
1✔
47
        this.infer = infer;
1✔
48
        this.ts = infer.getTypeSystem();
1✔
49
        assert ts != null;
1!
50
    }
1✔
51

52
    /**
53
     * Returns true if the argument expression is potentially
54
     * compatible with type t, as specified by JLSยง15.12.2.1:
55
     *
56
     * https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.12.1
57
     *
58
     * @param m Method for which the potential applicability is being tested
59
     * @param e Argument expression
60
     * @param t Formal parameter type
61
     */
62
    boolean isPotentiallyCompatible(JMethodSig m, ExprMirror e, JTypeMirror t) {
63
        if (e instanceof BranchingMirror) {
1✔
64
            // A conditional expression (ยง15.25) is potentially compatible with a type if each
65
            // of its second and third operand expressions are potentially compatible with that type.
66

67
            BranchingMirror cond = (BranchingMirror) e;
1✔
68
            return cond.branchesMatch(branch -> isPotentiallyCompatible(m, branch, t));
1✔
69

70
        }
71

72
        boolean isLambdaOrRef = e instanceof FunctionalExprMirror;
1✔
73

74
        if (isLambdaOrRef) {
1✔
75
            if (t instanceof JTypeVar) {
1✔
76
                //  A lambda expression or a method reference expression is potentially compatible with
77
                //  a type variable if the type variable is a type parameter of the candidate method.
78
                return m.getTypeParameters().contains(t);
1✔
79
            }
80
            if (TypeOps.isUnresolved(t)) {
1✔
81
                // Then we will not find a functional interface method.
82
                // Treat the argument as potentially compatible though.
83
                return true;
1✔
84
            }
85
            JMethodSig fun = TypeOps.findFunctionalInterfaceMethod(t);
1✔
86
            if (fun == null) {
1✔
87
                // t is not a functional interface
88
                return false;
1✔
89
            }
90

91
            if (e instanceof LambdaExprMirror) {
1✔
92
                LambdaExprMirror lambda = (LambdaExprMirror) e;
1✔
93
                if (fun.getArity() != lambda.getParamCount()) {
1✔
94
                    return false;
1✔
95
                }
96

97
                boolean expectsVoid = fun.getReturnType() == ts.NO_TYPE;
1✔
98

99
                return expectsVoid && lambda.isVoidCompatible() || lambda.isValueCompatible();
1!
100

101
            } else {
102
                // is method reference
103

104
                // TODO need to look for potentially applicable methods
105
                return true;
1✔
106
            }
107
        }
108

109
        // A class instance creation expression, a method invocation expression, or an expression of
110
        // a standalone form (ยง15.2) is potentially compatible with any type.
111
        // (ie anything else)
112
        return true;
1✔
113
    }
114

115
    /**
116
     * Returns true if the the argument expression is pertinent
117
     * to applicability for the potentially applicable method m,
118
     * called at site 'invoc', as specified by JLSยง15.12.2.2:
119
     *
120
     * https://docs.oracle.com/javase/specs/jls/se9/html/jls-15.html#jls-15.12.2.2
121
     *
122
     * @param arg        Argument expression
123
     * @param m          Method type
124
     * @param formalType Type of the formal parameter
125
     * @param invoc      Invocation expression
126
     */
127
    static boolean isPertinentToApplicability(ExprMirror arg, JMethodSig m, JTypeMirror formalType, InvocationMirror invoc) {
128
        // An argument expression is considered pertinent to applicability
129
        // for a potentially applicable method m unless it has one of the following forms:
130

131
        if (arg instanceof LambdaExprMirror) {
1✔
132
            LambdaExprMirror lambda = (LambdaExprMirror) arg;
1✔
133

134
            // An implicitly typed lambda expression(ยง 15.27 .1).
135
            if (!lambda.isExplicitlyTyped()) {
1✔
136
                return false;
1✔
137
            }
138

139
            // An explicitly typed lambda expression where at least
140
            // one result expression is not pertinent to applicability.
141
            for (ExprMirror it : lambda.getResultExpressions()) {
1✔
142
                if (!isPertinentToApplicability(it, m, formalType, invoc)) {
1!
UNCOV
143
                    return false;
×
144
                }
145
            }
1✔
146

147
            //  If m is a generic method and the method invocation does
148
            //  not provide explicit type arguments, an explicitly typed
149
            //  lambda expression for which the corresponding target type
150
            //  (as derived from the signature of m) is a type parameter of m.
151
            return !m.isGeneric()
1✔
152
                    || !invoc.getExplicitTypeArguments().isEmpty()
1!
153
                    || !formalType.isTypeVariable();
1✔
154
        }
155

156
        if (arg instanceof MethodRefMirror) {
1✔
157
            // An inexact method reference expression(ยง 15.13 .1).
158
            return getExactMethod((MethodRefMirror) arg) != null
1✔
159
                    //  If m is a generic method and the method invocation does
160
                    //  not provide explicit type arguments, an exact method
161
                    //  reference expression for which the corresponding target type
162
                    //  (as derived from the signature of m) is a type parameter of m.
163
                    && (!m.isGeneric()
1✔
164
                        || !invoc.getExplicitTypeArguments().isEmpty()
1✔
165
                        || !formalType.isTypeVariable());
1✔
166
        }
167

168
        if (arg instanceof BranchingMirror) {
1✔
169
            // A conditional expression (ยง15.25) is potentially compatible with a type if each
170
            // of its second and third operand expressions are potentially compatible with that type.
171

172
            BranchingMirror cond = (BranchingMirror) arg;
1✔
173
            return cond.branchesMatch(branch -> isPertinentToApplicability(branch, m, formalType, invoc));
1✔
174
        }
175

176
        return true;
1✔
177
    }
178

179

180
    /**
181
     * Returns null if the method reference is inexact.
182
     */
183
    public static @Nullable JMethodSig getExactMethod(MethodRefMirror mref) {
184
        JMethodSig cached = mref.getCachedExactMethod();
1✔
185

186
        if (cached == null) { // inexact
1✔
187
            return null;
1✔
188
        }
189

190
        if (cached.getTypeSystem().UNRESOLVED_METHOD == cached) {
1✔
191
            cached = computeExactMethod(mref);
1✔
192
            mref.setCachedExactMethod(cached); // set to null if inexact, sentinel is UNRESOLVED_METHOD
1✔
193
        }
194

195
        return cached;
1✔
196
    }
197

198
    private static @Nullable JMethodSig computeExactMethod(MethodRefMirror mref) {
199

200

201
        final @Nullable JTypeMirror lhs = mref.getLhsIfType();
1✔
202

203
        List<JMethodSig> accessible;
204

205
        if (mref.isConstructorRef()) {
1✔
206
            if (lhs == null) {
1!
207
                // ct error, already reported as a missing symbol in our system
UNCOV
208
                return null;
×
209
            } else if (lhs.isArray()) {
1✔
210
                // A method reference expression of the form ArrayType :: new is always exact.
211
                // But:  If a method reference expression has the form ArrayType :: new, then ArrayType
212
                // must denote a type that is reifiable (ยง4.7), or a compile-time error occurs.
213
                if (lhs.isReifiable()) {
1!
214
                    JTypeDeclSymbol symbol = lhs.getSymbol();
1✔
215

216
                    assert symbol instanceof JClassSymbol && ((JClassSymbol) symbol).isArray()
1!
217
                        : "Reifiable array should present a symbol! " + lhs;
218

219
                    return lhs.getConstructors().get(0);
1✔
220
                } else {
221
                    // todo compile time error
UNCOV
222
                    return null;
×
223
                }
224
            } else {
225
                if (lhs.isRaw() || !(lhs instanceof JClassType)) {
1!
226
                    return null;
1✔
227
                }
228

229
                accessible = TypeOps.filterAccessible(lhs.getConstructors(),
1✔
230
                                                      mref.getEnclosingType().getSymbol());
1✔
231
            }
232
        } else {
233
            JClassType enclosing = mref.getEnclosingType();
1✔
234
            accessible = mref.getTypeToSearch()
1✔
235
                             .streamMethods(TypeOps.accessibleMethodFilter(mref.getMethodName(), enclosing.getSymbol()))
1✔
236
                             .collect(OverloadSet.collectMostSpecific(enclosing));
1✔
237
        }
238

239
        if (accessible.size() == 1) {
1✔
240
            JMethodSig candidate = accessible.get(0);
1✔
241
            if (candidate.isVarargs()
1!
242
                || candidate.isGeneric() && mref.getExplicitTypeArguments().isEmpty()) {
1✔
243
                return null;
1✔
244
            }
245

246
            candidate = candidate.subst(Substitution.mapping(candidate.getTypeParameters(), mref.getExplicitTypeArguments()));
1✔
247

248
            if (lhs != null && lhs.isRaw()) {
1✔
249
                // can be raw if the method doesn't mention type vars
250
                // of the original owner, ie the erased method is the
251
                // same as the generic method.
252
                JClassType lhsClass = (JClassType) candidate.getDeclaringType();
1✔
253
                JMethodSig unerased = cast(cast(candidate).withOwner(lhsClass.getGenericTypeDeclaration())).originalMethod();
1✔
254
                if (TypeOps.mentionsAny(unerased, lhsClass.getFormalTypeParams())) {
1✔
255
                    return null;
1✔
256
                }
257
            }
258

259
            // For exact method references, the return type is Class<? extends T> (no erasure).
260
            // So it's mref::getTypeToSearch and not mref.getTypeToSearch()::getErasure
261
            return adaptGetClass(candidate, mref::getTypeToSearch);
1✔
262
        } else {
263
            return null;
1✔
264
        }
265
    }
266

267

268
    // for inexact method refs
269
    @Nullable MethodCtDecl findInexactMethodRefCompileTimeDecl(MethodRefMirror mref, JMethodSig targetType) {
270
        // https://docs.oracle.com/javase/specs/jls/se14/html/jls-15.html#jls-15.13.1
271

272
        JTypeMirror lhsIfType = mref.getLhsIfType();
1✔
273
        boolean acceptLowerArity = lhsIfType != null && lhsIfType.isClassOrInterface() && !mref.isConstructorRef();
1!
274

275
        MethodCallSite site1 = infer.newCallSite(methodRefAsInvocation(mref, targetType, false), null);
1✔
276
        site1.setLogging(!acceptLowerArity); // if we do only one search, then failure matters
1✔
277
        MethodCtDecl ctd1 = infer.determineInvocationTypeOrFail(site1);
1✔
278
        JMethodSig m1 = ctd1.getMethodType();
1✔
279

280
        if (acceptLowerArity) {
1✔
281
            // then we need to perform two searches, one with arity n, looking for static methods,
282
            // one with n-1, looking for instance methods
283

284
            MethodCallSite site2 = infer.newCallSite(methodRefAsInvocation(mref, targetType, true), null);
1✔
285
            site2.setLogging(false);
1✔
286
            MethodCtDecl ctd2 = infer.determineInvocationTypeOrFail(site2);
1✔
287
            JMethodSig m2 = ctd2.getMethodType();
1✔
288

289
            //  If the first search produces a most specific method that is static,
290
            //  and the set of applicable methods produced by the second search
291
            //  contains no non-static methods, then the compile-time declaration
292
            //  is the most specific method of the first search.
293
            if (m1 != ts.UNRESOLVED_METHOD && m1.isStatic() && (m2 == ts.UNRESOLVED_METHOD || m2.isStatic())) {
1!
294
                return ctd1;
1✔
295
            } else if (m2 != ts.UNRESOLVED_METHOD && !m2.isStatic() && (m1 == ts.UNRESOLVED_METHOD || !m1.isStatic())) {
1!
296
                // Otherwise, if the set of applicable methods produced by the
297
                // first search contains no static methods, and the second search
298
                // produces a most specific method that is non-static, then the
299
                // compile-time declaration is the most specific method of the second search.
300
                return ctd2;
1✔
301
            }
302

303
            //  Otherwise, there is no compile-time declaration.
304
            return null;
1✔
305
        } else if (m1 == ts.UNRESOLVED_METHOD || m1.isStatic()) {
1!
306
            // if the most specific applicable method is static, there is no compile-time declaration.
UNCOV
307
            return null;
×
308
        } else {
309
            // Otherwise, the compile-time declaration is the most specific applicable method.
310
            return ctd1;
1✔
311
        }
312
    }
313

314
    static InvocationMirror methodRefAsInvocation(final MethodRefMirror mref, JMethodSig targetType, boolean asInstanceMethod) {
315
        // the arguments are treated as if they were of the type
316
        // of the formal parameters of the candidate
317
        List<JTypeMirror> formals = targetType.getFormalParameters();
1✔
318
        if (asInstanceMethod && !formals.isEmpty()) {
1✔
319
            formals = formals.subList(1, formals.size()); // skip first param (receiver)
1✔
320
        }
321

322
        List<ExprMirror> arguments = CollectionUtil.map(
1✔
323
            formals,
324
            fi -> new ExprMirror() {
1✔
325

326
                @Override
327
                public void setInferredType(JTypeMirror mirror) {
328
                    // do nothing
329
                }
1✔
330

331
                @Override
332
                public @Nullable JTypeMirror getInferredType() {
UNCOV
333
                    throw new UnsupportedOperationException();
×
334
                }
335

336
                @Override
337
                public JavaNode getLocation() {
338
                    return mref.getLocation();
1✔
339
                }
340

341
                @Override
342
                public JTypeMirror getStandaloneType() {
343
                    return fi;
1✔
344
                }
345

346
                @Override
347
                public String toString() {
UNCOV
348
                    return "formal : " + fi;
×
349
                }
350

351
                @Override
352
                public TypingContext getTypingContext() {
UNCOV
353
                    return mref.getTypingContext();
×
354
                }
355

356
                @Override
357
                public boolean isEquivalentToUnderlyingAst() {
UNCOV
358
                    throw new UnsupportedOperationException("Cannot invoque isSemanticallyEquivalent on this mirror, it doesn't have a backing AST node: " + this);
×
359
                }
360
            }
361
        );
362

363

364
        return new InvocationMirror() {
1✔
365

366
            private MethodCtDecl mt;
367

368
            @Override
369
            public JavaNode getLocation() {
UNCOV
370
                return mref.getLocation();
×
371
            }
372

373
            @Override
374
            public Iterable<JMethodSig> getAccessibleCandidates() {
375
                return ExprOps.getAccessibleCandidates(mref, asInstanceMethod, targetType);
1✔
376
            }
377

378
            @Override
379
            public JTypeMirror getErasedReceiverType() {
UNCOV
380
                return mref.getTypeToSearch().getErasure();
×
381
            }
382

383
            @Override
384
            public @Nullable JTypeMirror getReceiverType() {
385
                return mref.getTypeToSearch();
1✔
386
            }
387

388
            @Override
389
            public List<JTypeMirror> getExplicitTypeArguments() {
390
                return mref.getExplicitTypeArguments();
1✔
391
            }
392

393
            @Override
394
            public JavaNode getExplicitTargLoc(int i) {
UNCOV
395
                throw new IndexOutOfBoundsException();
×
396
            }
397

398
            @Override
399
            public String getName() {
UNCOV
400
                return mref.getMethodName();
×
401
            }
402

403
            @Override
404
            public List<ExprMirror> getArgumentExpressions() {
405
                return arguments;
1✔
406
            }
407

408
            @Override
409
            public int getArgumentCount() {
410
                return arguments.size();
1✔
411
            }
412

413
            @Override
414
            public void setCompileTimeDecl(MethodCtDecl methodType) {
415
                this.mt = methodType;
1✔
416
            }
1✔
417

418
            @Override
419
            public @Nullable MethodCtDecl getCtDecl() {
420
                return mt;
1✔
421
            }
422

423
            JTypeMirror inferred;
424

425
            @Override
426
            public void setInferredType(JTypeMirror mirror) {
427
                // todo is this useful for method refs?
428
                inferred = mirror;
1✔
429
            }
1✔
430

431
            @Override
432
            public JTypeMirror getInferredType() {
UNCOV
433
                return inferred;
×
434
            }
435

436
            @Override
437
            public @NonNull JClassType getEnclosingType() {
UNCOV
438
                return mref.getEnclosingType();
×
439
            }
440

441
            @Override
442
            public String toString() {
UNCOV
443
                return "Method ref adapter (for " + mref + ")";
×
444
            }
445

446
            @Override
447
            public TypingContext getTypingContext() {
UNCOV
448
                return mref.getTypingContext();
×
449
            }
450

451
            @Override
452
            public boolean isEquivalentToUnderlyingAst() {
UNCOV
453
                throw new UnsupportedOperationException("Cannot invoque isSemanticallyEquivalent on this mirror, it doesn't have a backing AST node: " + this);
×
454
            }
455
        };
456
    }
457

458
    private static Iterable<JMethodSig> getAccessibleCandidates(MethodRefMirror mref, boolean asInstanceMethod, JMethodSig targetType) {
459
        JMethodSig exactMethod = getExactMethod(mref);
1✔
460
        if (exactMethod != null) {
1!
UNCOV
461
            return Collections.singletonList(exactMethod);
×
462
        } else {
463
            final JTypeMirror actualTypeToSearch;
464
            {
465
                JTypeMirror typeToSearch = mref.getTypeToSearch();
1✔
466
                if (typeToSearch.isArray() && mref.isConstructorRef()) {
1!
467
                    // ArrayType :: new
UNCOV
468
                    return typeToSearch.getConstructors();
×
469
                } else if (typeToSearch instanceof JClassType && mref.isConstructorRef()) {
1!
470
                    // ClassType :: [TypeArguments] new
471
                    // TODO treatment of raw constructors is whacky
472
                    return TypeOps.lazyFilterAccessible(typeToSearch.getConstructors(), mref.getEnclosingType().getSymbol());
1✔
473
                }
474

475
                if (asInstanceMethod && typeToSearch.isRaw() && typeToSearch instanceof JClassType
1!
476
                    && targetType.getArity() > 0) {
1!
477
                    //  In the second search, if P1, ..., Pn is not empty
478
                    //  and P1 is a subtype of ReferenceType, then the
479
                    //  method reference expression is treated as if it were
480
                    //  a method invocation expression with argument expressions
481
                    //  of types P2, ..., Pn. If ReferenceType is a raw type,
482
                    //  and there exists a parameterization of this type, G<...>,
483
                    //  that is a supertype of P1, the type to search is the result
484
                    //  of capture conversion (ยง5.1.10) applied to G<...>; otherwise,
485
                    //  the type to search is the same as the type of the first search.
486

487
                    JClassType type = (JClassType) typeToSearch;
1✔
488
                    JTypeMirror p1 = targetType.getFormalParameters().get(0);
1✔
489
                    JTypeMirror asSuper = p1.getAsSuper(type.getSymbol());
1✔
490
                    if (asSuper != null && asSuper.isParameterizedType()) {
1!
491
                        typeToSearch = capture(asSuper);
1✔
492
                    }
493
                }
494
                actualTypeToSearch = typeToSearch;
1✔
495
            }
496

497
            // Primary :: [TypeArguments] Identifier
498
            // ExpressionName :: [TypeArguments] Identifier
499
            // super :: [TypeArguments] Identifier
500
            // TypeName.super :: [TypeArguments] Identifier
501
            // ReferenceType :: [TypeArguments] Identifier
502

503
            boolean acceptsInstanceMethods = canUseInstanceMethods(actualTypeToSearch, targetType, mref);
1✔
504

505
            Predicate<JMethodSymbol> prefilter = TypeOps.accessibleMethodFilter(mref.getMethodName(), mref.getEnclosingType().getSymbol())
1✔
506
                                                        .and(m -> Modifier.isStatic(m.getModifiers())
1✔
507
                                                            || acceptsInstanceMethods);
508
            return actualTypeToSearch.streamMethods(prefilter).collect(Collectors.toList());
1✔
509
        }
510
    }
511

512
    private static boolean canUseInstanceMethods(JTypeMirror typeToSearch, JMethodSig sig, MethodRefMirror mref) {
513
        // For example, if you write
514
        // stringStream.map(Objects::toString),
515

516
        // The type to search is Objects. But Objects inherits Object.toString(),
517
        // which could not be called on a string (String.toString() != Objects.toString()).
518

519
        if (mref.getLhsIfType() != null && !sig.getFormalParameters().isEmpty()) {
1✔
520
            // ReferenceType :: [TypeArguments] Identifier
521
            JTypeMirror firstFormal = sig.getFormalParameters().get(0);
1✔
522
            return firstFormal.isSubtypeOf(typeToSearch);
1✔
523
        }
524
        return true;
1✔
525
    }
526

527

528
    /**
529
     * Calls to {@link Object#getClass()} on a type {@code T} have type
530
     * {@code Class<? extends |T|>}. If the selected method is that method, then
531
     * we need to replace its return type (the symbol has return type {@link Object}).
532
     *
533
     * <p>For exact method reference expressions, the type is {@code <? extends T>} (no erasure).
534
     *
535
     * @param sig                   Selected signature
536
     * @param replacementReturnType Lazily created, because in many cases it's not necessary
537
     *
538
     * @return Signature, adapted if it is {@link Object#getClass()}
539
     */
540
    static JMethodSig adaptGetClass(JMethodSig sig, Supplier<JTypeMirror> replacementReturnType) {
541
        TypeSystem ts = sig.getTypeSystem();
1✔
542
        if ("getClass".equals(sig.getName()) && sig.getDeclaringType().equals(ts.OBJECT)) {
1!
543
            return cast(cast(sig).withReturnType(getClassReturn(replacementReturnType.get(), ts))).markAsAdapted();
1✔
544
        }
545
        return sig;
1✔
546
    }
547

548
    private static JTypeMirror getClassReturn(JTypeMirror erasedReceiverType, TypeSystem ts) {
549
        return ts.parameterise(ts.getClassSymbol(Class.class), listOf(ts.wildcard(true, erasedReceiverType)));
1✔
550
    }
551

552
    static boolean isContextDependent(JMethodSig m) {
553
        m = cast(m).adaptedMethod();
1✔
554
        return m.isGeneric() && TypeOps.mentionsAny(m.getReturnType(), m.getTypeParameters());
1✔
555
    }
556
}
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