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

pmd / pmd / 130

06 Sep 2025 12:33PM UTC coverage: 78.533% (+0.04%) from 78.498%
130

push

github

oowekyala
Fix #4770: [java] UnusedFormalParameter should ignore public constructor as same as method (#5994)

Merge branch 'issue-4770-UnusedFormalParameter-should-ignore-public-constructor-as-same-as-method'

17953 of 23697 branches covered (75.76%)

Branch coverage included in aggregate %.

3 of 3 new or added lines in 2 files covered. (100.0%)

27 existing lines in 6 files now uncovered.

39280 of 49181 relevant lines covered (79.87%)

0.81 hits per line

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

88.32
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/ast/internal/PrettyPrintingUtil.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.ast.internal;
6

7
import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.Necessity;
8
import static net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule.needsParentheses;
9
import static net.sourceforge.pmd.util.AssertionUtil.shouldNotReachHere;
10

11
import org.checkerframework.checker.nullness.qual.NonNull;
12
import org.checkerframework.checker.nullness.qual.Nullable;
13

14
import net.sourceforge.pmd.lang.java.ast.ASTAmbiguousName;
15
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
16
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
17
import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess;
18
import net.sourceforge.pmd.lang.java.ast.ASTArrayAllocation;
19
import net.sourceforge.pmd.lang.java.ast.ASTArrayType;
20
import net.sourceforge.pmd.lang.java.ast.ASTAssignmentExpression;
21
import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
22
import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration;
23
import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral;
24
import net.sourceforge.pmd.lang.java.ast.ASTClassType;
25
import net.sourceforge.pmd.lang.java.ast.ASTConditionalExpression;
26
import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
27
import net.sourceforge.pmd.lang.java.ast.ASTConstructorDeclaration;
28
import net.sourceforge.pmd.lang.java.ast.ASTEnumDeclaration;
29
import net.sourceforge.pmd.lang.java.ast.ASTExecutableDeclaration;
30
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
31
import net.sourceforge.pmd.lang.java.ast.ASTFieldAccess;
32
import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
33
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
34
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
35
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
36
import net.sourceforge.pmd.lang.java.ast.ASTInfixExpression;
37
import net.sourceforge.pmd.lang.java.ast.ASTIntersectionType;
38
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
39
import net.sourceforge.pmd.lang.java.ast.ASTLambdaParameterList;
40
import net.sourceforge.pmd.lang.java.ast.ASTList;
41
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
42
import net.sourceforge.pmd.lang.java.ast.ASTLocalVariableDeclaration;
43
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
44
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
45
import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
46
import net.sourceforge.pmd.lang.java.ast.ASTPrimitiveType;
47
import net.sourceforge.pmd.lang.java.ast.ASTRecordDeclaration;
48
import net.sourceforge.pmd.lang.java.ast.ASTReferenceType;
49
import net.sourceforge.pmd.lang.java.ast.ASTResource;
50
import net.sourceforge.pmd.lang.java.ast.ASTSuperExpression;
51
import net.sourceforge.pmd.lang.java.ast.ASTSwitchExpression;
52
import net.sourceforge.pmd.lang.java.ast.ASTThisExpression;
53
import net.sourceforge.pmd.lang.java.ast.ASTType;
54
import net.sourceforge.pmd.lang.java.ast.ASTTypeArguments;
55
import net.sourceforge.pmd.lang.java.ast.ASTTypeDeclaration;
56
import net.sourceforge.pmd.lang.java.ast.ASTTypeExpression;
57
import net.sourceforge.pmd.lang.java.ast.ASTUnaryExpression;
58
import net.sourceforge.pmd.lang.java.ast.ASTUnionType;
59
import net.sourceforge.pmd.lang.java.ast.ASTVariableAccess;
60
import net.sourceforge.pmd.lang.java.ast.ASTVariableId;
61
import net.sourceforge.pmd.lang.java.ast.ASTVoidType;
62
import net.sourceforge.pmd.lang.java.ast.ASTWildcardType;
63
import net.sourceforge.pmd.lang.java.ast.JavaNode;
64
import net.sourceforge.pmd.lang.java.ast.JavaVisitorBase;
65
import net.sourceforge.pmd.lang.java.ast.QualifiableExpression;
66
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
67
import net.sourceforge.pmd.lang.java.types.JMethodSig;
68
import net.sourceforge.pmd.lang.java.types.TypePrettyPrint;
69
import net.sourceforge.pmd.lang.java.types.TypePrettyPrint.TypePrettyPrinter;
70
import net.sourceforge.pmd.util.CollectionUtil;
71

72
/**
73
 * @author Clément Fournier
74
 */
75
public final class PrettyPrintingUtil {
76

77
    private PrettyPrintingUtil() {
78
        // util class
79
    }
80

81
    /**
82
     * Returns a normalized method name. This just looks at the image of the types of the parameters.
83
     */
84
    public static String displaySignature(String methodName, ASTFormalParameters params) {
85

86
        StringBuilder sb = new StringBuilder();
1✔
87
        sb.append(methodName);
1✔
88
        sb.append('(');
1✔
89

90
        boolean first = true;
1✔
91
        for (ASTFormalParameter param : params) {
1✔
92
            if (!first) {
1✔
93
                sb.append(", ");
1✔
94
            }
95
            first = false;
1✔
96

97
            prettyPrintTypeNode(sb, param.getTypeNode());
1✔
98
            int extraDimensions = ASTList.sizeOrZero(param.getVarId().getExtraDimensions());
1✔
99
            while (extraDimensions-- > 0) {
1✔
100
                sb.append("[]");
1✔
101
            }
102
        }
1✔
103

104
        sb.append(')');
1✔
105

106
        return sb.toString();
1✔
107
    }
108

109
    private static void prettyPrintTypeNode(StringBuilder sb, ASTType t) {
110
        if (t instanceof ASTPrimitiveType) {
1✔
111
            sb.append(((ASTPrimitiveType) t).getKind().getSimpleName());
1✔
112
        } else if (t instanceof ASTClassType) {
1✔
113
            ASTClassType classT = (ASTClassType) t;
1✔
114
            sb.append(classT.getSimpleName());
1✔
115

116
            ASTTypeArguments targs = classT.getTypeArguments();
1✔
117
            if (targs != null) {
1✔
118
                sb.append("<");
1✔
119
                CollectionUtil.joinOn(sb, targs.toStream(), PrettyPrintingUtil::prettyPrintTypeNode, ", ");
1✔
120
                sb.append(">");
1✔
121
            }
122
        } else if (t instanceof ASTArrayType) {
1✔
123
            prettyPrintTypeNode(sb, ((ASTArrayType) t).getElementType());
1✔
124
            int depth = ((ASTArrayType) t).getArrayDepth();
1✔
125
            for (int i = 0; i < depth; i++) {
1✔
126
                sb.append("[]");
1✔
127
            }
128
        } else if (t instanceof ASTVoidType) {
1!
UNCOV
129
            sb.append("void");
×
130
        } else if (t instanceof ASTWildcardType) {
1!
131
            sb.append("?");
1✔
132
            ASTReferenceType bound = ((ASTWildcardType) t).getTypeBoundNode();
1✔
133
            if (bound != null) {
1✔
134
                sb.append(((ASTWildcardType) t).isLowerBound() ? " super " : " extends ");
1✔
135
                prettyPrintTypeNode(sb, bound);
1✔
136
            }
137
        } else if (t instanceof ASTUnionType) {
1!
138
            CollectionUtil.joinOn(sb, ((ASTUnionType) t).getComponents(),
×
139
                PrettyPrintingUtil::prettyPrintTypeNode, " | ");
140
        } else if (t instanceof ASTIntersectionType) {
×
141
            CollectionUtil.joinOn(sb, ((ASTIntersectionType) t).getComponents(),
×
142
                PrettyPrintingUtil::prettyPrintTypeNode, " & ");
143
        } else if (t instanceof ASTAmbiguousName) {
×
UNCOV
144
            sb.append(((ASTAmbiguousName) t).getName());
×
145
        } else {
UNCOV
146
            throw shouldNotReachHere("Unhandled type? " + t);
×
147
        }
148
    }
1✔
149

150
    public static String prettyPrintType(ASTType t) {
151
        StringBuilder sb = new StringBuilder();
1✔
152
        prettyPrintTypeNode(sb, t);
1✔
153
        return sb.toString();
1✔
154
    }
155

156
    /**
157
     * Returns a normalized method name. This just looks at the image of the types of the parameters.
158
     */
159
    public static String displaySignature(ASTExecutableDeclaration node) {
160
        return displaySignature(node.getName(), node.getFormalParameters());
1✔
161
    }
162

163
    /**
164
     * Returns the generic kind of declaration this is, eg "enum" or "class".
165
     */
166
    public static String getPrintableNodeKind(ASTTypeDeclaration decl) {
167
        if (decl instanceof ASTClassDeclaration && decl.isInterface()) {
1✔
168
            return "interface";
1✔
169
        } else if (decl instanceof ASTAnnotationTypeDeclaration) {
1✔
170
            return "annotation";
1✔
171
        } else if (decl instanceof ASTEnumDeclaration) {
1✔
172
            return "enum";
1✔
173
        } else if (decl instanceof ASTRecordDeclaration) {
1✔
174
            return "record";
1✔
175
        }
176
        return "class";
1✔
177
    }
178

179
    /**
180
     * Returns the "name" of a node. For methods and constructors, this
181
     * may return a signature with parameters.
182
     */
183
    public static String getNodeName(JavaNode node) {
184
        // constructors are differentiated by their parameters, while we only use method name for methods
185
        if (node instanceof ASTMethodDeclaration) {
1✔
186
            return ((ASTMethodDeclaration) node).getName();
1✔
187
        } else if (node instanceof ASTExecutableDeclaration) {
1✔
188
            // constructors are differentiated by their parameters, while we only use method name for methods
189
            return displaySignature((ASTConstructorDeclaration) node);
1✔
190
        } else if (node instanceof ASTFieldDeclaration) {
1✔
191
            return ((ASTFieldDeclaration) node).getVarIds().firstOrThrow().getName();
1✔
192
        } else if (node instanceof ASTResource) {
1✔
193
            ASTLocalVariableDeclaration var = ((ASTResource) node).asLocalVariableDeclaration();
1✔
194
            if (var != null) {
1!
195
                return var.getVarIds().firstOrThrow().getName();
1✔
196
            } else {
UNCOV
197
                return PrettyPrintingUtil.prettyPrint(((ASTResource) node).getInitializer()).toString();
×
198
            }
199
        } else if (node instanceof ASTTypeDeclaration) {
1!
200
            return ((ASTTypeDeclaration) node).getSimpleName();
1✔
201
        } else if (node instanceof ASTVariableId) {
×
UNCOV
202
            return ((ASTVariableId) node).getName();
×
203
        } else {
UNCOV
204
            throw new IllegalArgumentException("Node has no defined name: " + node);
×
205
        }
206
    }
207

208

209
    /**
210
     * Returns the 'kind' of node this is. For instance for a {@link ASTFieldDeclaration},
211
     * returns "field".
212
     *
213
     * @throws UnsupportedOperationException If unimplemented for a node kind
214
     * @see #getPrintableNodeKind(ASTTypeDeclaration)
215
     */
216
    public static String getPrintableNodeKind(JavaNode node) {
217
        if (node instanceof ASTTypeDeclaration) {
1✔
218
            return getPrintableNodeKind((ASTTypeDeclaration) node);
1✔
219
        } else if (node instanceof ASTMethodDeclaration) {
1✔
220
            return "method";
1✔
221
        } else if (node instanceof ASTConstructorDeclaration) {
1✔
222
            return "constructor";
1✔
223
        } else if (node instanceof ASTFieldDeclaration) {
1✔
224
            return "field";
1✔
225
        } else if (node instanceof ASTResource) {
1!
226
            return "resource specification";
1✔
227
        }
UNCOV
228
        throw new UnsupportedOperationException("Node " + node + " is unaccounted for");
×
229
    }
230

231
    public static String prettyImport(ASTImportDeclaration importDecl) {
232
        String name = importDecl.getImportedName();
1✔
233
        if (importDecl.isImportOnDemand()) {
1✔
234
            return name + ".*";
1✔
235
        }
236
        return name;
1✔
237
    }
238

239
    /**
240
     * Pretty print the selected overload.
241
     */
242
    public static @NonNull String prettyPrintOverload(ASTMethodCall it) {
UNCOV
243
        return prettyPrintOverload(it.getOverloadSelectionInfo().getMethodType());
×
244
    }
245

246
    public static @NonNull String prettyPrintOverload(JMethodSymbol it) {
247
        return prettyPrintOverload(it.getTypeSystem().sigOf(it));
1✔
248
    }
249

250
    public static @NonNull String prettyPrintOverload(JMethodSig it) {
251
        return TypePrettyPrint.prettyPrint(it, overloadPrinter());
1✔
252
    }
253

254
    private static TypePrettyPrinter overloadPrinter() {
255
        return new TypePrettyPrinter().qualifyNames(false).printMethodResult(false);
1✔
256
    }
257

258

259
    /** Pretty print an expression or any other kind of node. */
260
    public static CharSequence prettyPrint(JavaNode node) {
261
        StringBuilder sb = new StringBuilder();
1✔
262
        node.acceptVisitor(new ExprPrinter(), sb);
1✔
263
        return sb;
1✔
264
    }
265

266
    static class ExprPrinter extends JavaVisitorBase<StringBuilder, Void> {
1✔
267

268
        private static final int MAX_ARG_LENGTH = 20;
269
        public static final String BLOCK_PLACEHOLDER = "{ ... }";
270

271
        @Override
272
        public Void visitJavaNode(JavaNode node, StringBuilder data) {
273
            data.append("<<NOT_IMPLEMENTED: ").append(node).append(">>");
1✔
274
            return null; // don't recurse
1✔
275
        }
276

277
        @Override
278
        public Void visit(ASTTypeExpression node, StringBuilder data) {
279
            node.getTypeNode().acceptVisitor(this, data);
1✔
280
            return null;
1✔
281
        }
282

283
        @Override
284
        public Void visit(ASTCastExpression node, StringBuilder data) {
285
            ppInParens(data, node.getCastType()).append(' ');
1✔
286
            node.getOperand().acceptVisitor(this, data);
1✔
287
            return null;
1✔
288
        }
289

290
        @Override
291
        public Void visit(ASTClassLiteral node, StringBuilder data) {
292
            node.getTypeNode().acceptVisitor(this, data);
1✔
293
            data.append(".class");
1✔
294
            return null;
1✔
295
        }
296

297
        @Override
298
        public Void visitLiteral(ASTLiteral node, StringBuilder data) {
299
            data.append(node.getLiteralText());
1✔
300
            return null;
1✔
301
        }
302

303
        @Override
304
        public Void visit(ASTFieldAccess node, StringBuilder data) {
305
            addQualifier(node, data);
1✔
306
            data.append(node.getName());
1✔
307
            return null;
1✔
308
        }
309

310
        @Override
311
        public Void visit(ASTVariableAccess node, StringBuilder data) {
312
            data.append(node.getName());
1✔
313
            return null;
1✔
314
        }
315

316
        @Override
317
        public Void visit(ASTThisExpression node, StringBuilder data) {
318
            if (node.getQualifier() != null) {
1✔
319
                node.getQualifier().acceptVisitor(this, data);
1✔
320
                data.append('.');
1✔
321
            }
322
            data.append("this");
1✔
323
            return null;
1✔
324
        }
325

326
        @Override
327
        public Void visit(ASTSuperExpression node, StringBuilder data) {
328
            if (node.getQualifier() != null) {
×
329
                node.getQualifier().acceptVisitor(this, data);
×
UNCOV
330
                data.append('.');
×
331
            }
UNCOV
332
            data.append("super");
×
UNCOV
333
            return null;
×
334
        }
335

336
        @Override
337
        public Void visit(ASTArrayAccess node, StringBuilder data) {
338
            node.getQualifier().acceptVisitor(this, data);
×
UNCOV
339
            data.append('[');
×
UNCOV
340
            node.getIndexExpression().acceptVisitor(this, data);
×
UNCOV
341
            data.append(']');
×
UNCOV
342
            return null;
×
343
        }
344

345
        @Override
346
        public Void visitType(ASTType node, StringBuilder data) {
347
            prettyPrintTypeNode(data, node);
1✔
348
            return null;
1✔
349
        }
350

351
        @Override
352
        public Void visit(ASTAmbiguousName node, StringBuilder data) {
353
            data.append(node.getName());
1✔
354
            return null;
1✔
355
        }
356

357
        @Override
358
        public Void visit(ASTInfixExpression node, StringBuilder sb) {
359
            printWithParensIfNecessary(node.getLeftOperand(), sb, node);
1✔
360
            sb.append(' ');
1✔
361
            sb.append(node.getOperator());
1✔
362
            sb.append(' ');
1✔
363
            printWithParensIfNecessary(node.getRightOperand(), sb, node);
1✔
364
            return null;
1✔
365
        }
366

367

368
        @Override
369
        public Void visit(ASTUnaryExpression node, StringBuilder sb) {
370
            boolean prefix = node.getOperator().isPrefix();
1✔
371
            if (prefix) {
1✔
372
                sb.append(node.getOperator());
1✔
373
            }
374
            printWithParensIfNecessary(node.getOperand(), sb, node);
1✔
375
            if (!prefix) {
1✔
376
                sb.append(node.getOperator());
1✔
377
            }
378
            return null;
1✔
379
        }
380

381
        private void printWithParensIfNecessary(ASTExpression operand, StringBuilder sb, ASTExpression parent) {
382
            if (operand.isParenthesized() && needsParentheses(operand, parent) != Necessity.NEVER) {
1✔
383
                ppInParens(sb, operand);
1✔
384
            } else {
385
                operand.acceptVisitor(this, sb);
1✔
386
            }
387
        }
1✔
388

389
        @Override
390
        public Void visit(ASTConditionalExpression node, StringBuilder sb) {
391
            printWithParensIfNecessary(node.getCondition(), sb, node);
1✔
392
            sb.append(" ? ");
1✔
393
            printWithParensIfNecessary(node.getThenBranch(), sb, node);
1✔
394
            sb.append(" : ");
1✔
395
            printWithParensIfNecessary(node.getElseBranch(), sb, node);
1✔
396
            return null;
1✔
397
        }
398

399
        @Override
400
        public Void visit(ASTLambdaExpression node, StringBuilder sb) {
401
            node.getParameters().acceptVisitor(this, sb);
1✔
402
            sb.append(" -> ");
1✔
403
            ASTExpression exprBody = node.getExpressionBody();
1✔
404
            if (exprBody != null) {
1✔
405
                exprBody.acceptVisitor(this, sb);
1✔
406
            } else {
407
                sb.append(BLOCK_PLACEHOLDER);
1✔
408
            }
409
            return null;
1✔
410
        }
411

412
        @Override
413
        public Void visit(ASTLambdaParameterList node, StringBuilder sb) {
414
            if (node.size() == 1) {
1✔
415
                sb.append(node.get(0).getVarId().getName());
1✔
416
                return null;
1✔
417
            } else if (node.isEmpty()) {
1✔
418
                sb.append("()");
1✔
419
                return null;
1✔
420
            }
421

422
            sb.append('(');
1✔
423
            sb.append(node.get(0).getVarId().getName());
1✔
424
            node.toStream().drop(1).forEach(it -> {
1✔
425
                sb.append(", ");
1✔
426
                sb.append(it.getVarId().getName());
1✔
427
            });
1✔
428
            sb.append(')');
1✔
429

430
            return null;
1✔
431
        }
432

433
        @Override
434
        public Void visit(ASTMethodCall node, StringBuilder sb) {
435
            addQualifier(node, sb);
1✔
436
            ppTypeArgs(sb, node.getExplicitTypeArguments());
1✔
437
            sb.append(node.getMethodName());
1✔
438
            ppArguments(sb, node.getArguments());
1✔
439
            return null;
1✔
440
        }
441

442
        @Override
443
        public Void visit(ASTConstructorCall node, StringBuilder sb) {
444
            addQualifier(node, sb);
1✔
445
            sb.append("new ");
1✔
446
            ppTypeArgs(sb, node.getExplicitTypeArguments());
1✔
447
            prettyPrintTypeNode(sb, node.getTypeNode());
1✔
448
            ppArguments(sb, node.getArguments());
1✔
449
            return null;
1✔
450
        }
451

452
        private void ppArguments(StringBuilder sb, ASTArgumentList arguments) {
453
            if (arguments.isEmpty()) {
1✔
454
                sb.append("()");
1✔
455
            } else {
456
                final int argStart = sb.length();
1✔
457
                sb.append('(');
1✔
458
                boolean first = true;
1✔
459
                for (ASTExpression arg : arguments) {
1✔
460
                    if (sb.length() - argStart >= MAX_ARG_LENGTH) {
1✔
461
                        sb.append("...");
1✔
462
                        break;
1✔
463
                    } else if (!first) {
1✔
464
                        sb.append(", ");
1✔
465
                    }
466
                    arg.acceptVisitor(this, sb);
1✔
467
                    first = false;
1✔
468
                }
1✔
469
                sb.append(')');
1✔
470
            }
471
        }
1✔
472

473
        @Override
474
        public Void visit(ASTMethodReference node, StringBuilder sb) {
475
            printWithParensIfNecessary(node.getQualifier(), sb, node);
1✔
476
            sb.append("::");
1✔
477
            ppTypeArgs(sb, node.getExplicitTypeArguments());
1✔
478
            sb.append(node.getMethodName());
1✔
479
            return null;
1✔
480
        }
481

482
        @Override
483
        public Void visit(ASTAssignmentExpression node, StringBuilder sb) {
484
            node.getLeftOperand().acceptVisitor(this, sb);
1✔
485
            sb.append(" = ");
1✔
486
            node.getRightOperand().acceptVisitor(this, sb);
1✔
487
            return null;
1✔
488
        }
489

490
        @Override
491
        public Void visit(ASTSwitchExpression node, StringBuilder sb) {
492
            sb.append("switch (");
1✔
493
            node.getFirstChild().acceptVisitor(this, sb);
1✔
494
            sb.append(") ").append(BLOCK_PLACEHOLDER);
1✔
495
            return null;
1✔
496
        }
497

498
        @Override
499
        public Void visit(ASTArrayAllocation node, StringBuilder sb) {
500
            sb.append("new ");
1✔
501
            node.getTypeNode().getElementType().acceptVisitor(this, sb);
1✔
502
            node.getTypeNode().getDimensions().children().forEach(child -> {
1✔
503
                sb.append('[');
1✔
504
                JavaNode firstChild = child.getFirstChild();
1✔
505
                if (firstChild != null) {
1✔
506
                    firstChild.acceptVisitor(this, sb);
1✔
507
                }
508
                sb.append(']');
1✔
509
            });
1✔
510
            if (node.getArrayInitializer() != null) {
1✔
511
                sb.append(node.getArrayInitializer().length() == 0 ? "{}" : BLOCK_PLACEHOLDER);
1✔
512
            }
513
            return null;
1✔
514
        }
515

516
        private void addQualifier(QualifiableExpression node, StringBuilder data) {
517
            ASTExpression qualifier = node.getQualifier();
1✔
518
            if (qualifier != null) {
1✔
519
                printWithParensIfNecessary(qualifier, data, node);
1✔
520
                data.append('.');
1✔
521
            }
522

523
        }
1✔
524

525
        private StringBuilder ppInParens(StringBuilder data, JavaNode qualifier) {
526
            data.append('(');
1✔
527
            qualifier.acceptVisitor(this, data);
1✔
528
            return data.append(')');
1✔
529
        }
530

531

532
        private void ppTypeArgs(StringBuilder data, @Nullable ASTTypeArguments targs) {
533
            if (targs == null) {
1✔
534
                return;
1✔
535
            }
536
            data.append('<');
1✔
537
            prettyPrintTypeNode(data, targs.get(0));
1✔
538
            for (int i = 1; i < targs.size(); i++) {
1!
UNCOV
539
                data.append(", ");
×
UNCOV
540
                prettyPrintTypeNode(data, targs.get(i));
×
541
            }
542
            data.append('>');
1✔
543
        }
1✔
544

545
    }
546

547

548
}
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