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

pmd / pmd / 95

22 Jul 2025 05:33PM UTC coverage: 78.418% (-0.02%) from 78.436%
95

push

github

web-flow
chore: [scala] Fix javadoc config (#5920)

17758 of 23477 branches covered (75.64%)

Branch coverage included in aggregate %.

38997 of 48898 relevant lines covered (79.75%)

0.81 hits per line

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

85.12
/pmd-java/src/main/java/net/sourceforge/pmd/lang/java/symbols/internal/ImplicitMemberSymbols.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.symbols.internal;
6

7
import static java.util.Collections.emptyList;
8
import static java.util.Collections.singletonList;
9

10
import java.lang.reflect.Modifier;
11
import java.util.List;
12
import java.util.function.BiFunction;
13
import java.util.function.Function;
14

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

18
import net.sourceforge.pmd.lang.java.ast.ASTVariableId;
19
import net.sourceforge.pmd.lang.java.internal.JavaAstProcessor;
20
import net.sourceforge.pmd.lang.java.symbols.JClassSymbol;
21
import net.sourceforge.pmd.lang.java.symbols.JConstructorSymbol;
22
import net.sourceforge.pmd.lang.java.symbols.JExecutableSymbol;
23
import net.sourceforge.pmd.lang.java.symbols.JFieldSymbol;
24
import net.sourceforge.pmd.lang.java.symbols.JFormalParamSymbol;
25
import net.sourceforge.pmd.lang.java.symbols.JMethodSymbol;
26
import net.sourceforge.pmd.lang.java.symbols.JRecordComponentSymbol;
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.TypeSystem;
31
import net.sourceforge.pmd.util.CollectionUtil;
32

33
/**
34
 * Members inserted by the compiler, eg default constructor, etc. They
35
 * would be absent from the source, but are reflected by the {@link Class}.
36
 */
37
public final class ImplicitMemberSymbols {
1✔
38

39
    private static final int VISIBILITY_MASK = Modifier.PRIVATE | Modifier.PUBLIC | Modifier.PROTECTED;
40
    /** This is the private access flag for varargs modifiers. */
41
    private static final int VARARGS_MOD = 0x00000080;
42

43
    private ImplicitMemberSymbols() {
44

45
    }
46

47
    public static JMethodSymbol enumValueOf(JClassSymbol enumSym) {
48
        assert enumSym.isEnum() : "Not an enum symbol " + enumSym;
1!
49

50
        return new FakeMethodSym(
1✔
51
            enumSym,
52
            "valueOf",
53
            Modifier.PUBLIC | Modifier.STATIC,
54
            TypeSystem::declaration,
55
            singletonList(t -> new FakeFormalParamSym(t, "name", (ts, s) -> ts.declaration(ts.getClassSymbol(String.class))))
1✔
56
        );
57
    }
58

59
    public static JMethodSymbol enumValues(JClassSymbol enumSym) {
60
        assert enumSym.isEnum() : "Not an enum symbol " + enumSym;
1!
61

62
        return new FakeMethodSym(
1✔
63
            enumSym,
64
            "values",
65
            Modifier.PUBLIC | Modifier.STATIC,
66
            (ts, c) -> ts.arrayType(ts.declaration(c)),
1✔
67
            emptyList()
1✔
68
        );
69
    }
70

71

72
    public static JConstructorSymbol defaultCtor(JClassSymbol sym) {
73
        assert sym != null;
1!
74

75
        // Enum constructors have 2 additional implicit parameters, for the name and ordinal
76
        // Inner classes have 1 additional implicit param, for the outer instance
77
        // They are not reflected by the symbol
78

79
        int modifiers = sym.isEnum() ? Modifier.PRIVATE
1✔
80
                                     : sym.getModifiers() & VISIBILITY_MASK;
1✔
81

82
        return new FakeCtorSym(sym, modifiers, emptyList());
1✔
83
    }
84

85

86
    public static JMethodSymbol arrayClone(JClassSymbol arraySym) {
87
        assert arraySym.isArray() : "Not an array symbol " + arraySym;
1!
88

89
        return new FakeMethodSym(
1✔
90
            arraySym,
91
            "clone",
92
            Modifier.PUBLIC | Modifier.FINAL,
93
            TypeSystem::declaration,
94
            emptyList()
1✔
95
        );
96
    }
97

98
    public static JConstructorSymbol arrayConstructor(JClassSymbol arraySym) {
99
        assert arraySym.isArray() : "Not an array symbol " + arraySym;
1!
100

101
        return new FakeCtorSym(
1✔
102
            arraySym,
103
            Modifier.PUBLIC | Modifier.FINAL,
104
            singletonList(c -> new FakeFormalParamSym(c, "arg0", (ts, sym) -> ts.INT))
1✔
105
        );
106
    }
107

108
    /** Symbol for the canonical record constructor. */
109
    public static JConstructorSymbol recordConstructor(JClassSymbol recordSym,
110
                                                       List<JRecordComponentSymbol> recordComponents,
111
                                                       boolean isVarargs) {
112
        assert recordSym.isRecord() : "Not a record symbol " + recordSym;
1!
113

114
        int modifiers = isVarargs ? Modifier.PUBLIC | VARARGS_MOD
1✔
115
                                  : Modifier.PUBLIC;
1✔
116

117
        return new FakeCtorSym(
1✔
118
            recordSym,
119
            modifiers,
120
            CollectionUtil.map(
1✔
121
                recordComponents,
122
                f -> c -> new FakeFormalParamSym(c, f.getSimpleName(), f.tryGetNode().getVarId(), (ts, sym) -> f.getTypeMirror(Substitution.EMPTY))
1✔
123
            )
124
        );
125
    }
126

127
    /**
128
     * Symbol for a record component accessor.
129
     * Only synthesized if it is not explicitly declared.
130
     */
131
    public static JMethodSymbol recordAccessor(JClassSymbol recordSym, JRecordComponentSymbol recordComponent) {
132
        // See https://cr.openjdk.java.net/~gbierman/jep359/jep359-20200115/specs/records-jls.html#jls-8.10.3
133

134
        assert recordSym.isRecord() : "Not a record symbol " + recordSym;
1!
135

136
        return new FakeMethodSym(
1✔
137
            recordSym,
138
            recordComponent.getSimpleName(),
1✔
139
            Modifier.PUBLIC,
140
            (ts, encl) -> recordComponent.getTypeMirror(Substitution.EMPTY),
1✔
141
            emptyList()
1✔
142
        );
143
    }
144

145
    public static JFieldSymbol arrayLengthField(JClassSymbol arraySym) {
146
        assert arraySym.isArray() : "Not an array symbol " + arraySym;
1!
147

148
        return new FakeFieldSym(
1✔
149
            arraySym,
150
            "length",
151
            Modifier.PUBLIC | Modifier.FINAL,
152
            (ts, s) -> ts.INT
1✔
153
        );
154
    }
155

156
    public static JFieldSymbol lombokSlf4jLoggerField(JClassSymbol classSym, JavaAstProcessor processor) {
157
        // https://javadoc.io/doc/org.projectlombok/lombok/1.16.18/lombok/extern/slf4j/Slf4j.html
158

159
        return new FakeFieldSym(
1✔
160
                classSym,
161
                "log",
162
                Modifier.PRIVATE | Modifier.STATIC | Modifier.FINAL,
163
                (ts, s) ->
164
                        ts.declaration(processor.findSymbolCannotFail("org.slf4j.Logger"))
1✔
165
        );
166
    }
167

168
    private abstract static class FakeExecutableSymBase<T extends JExecutableSymbol> implements JExecutableSymbol {
169

170
        private final JClassSymbol owner;
171
        private final String name;
172
        private final int modifiers;
173
        private final List<JFormalParamSymbol> formals;
174

175

176
        FakeExecutableSymBase(JClassSymbol owner,
177
                              String name,
178
                              int modifiers,
179
                              List<Function<T, JFormalParamSymbol>> formals) {
1✔
180
            this.owner = owner;
1✔
181
            this.name = name;
1✔
182
            this.modifiers = modifiers;
1✔
183
            this.formals = CollectionUtil.map(formals, f -> f.apply((T) this));
1✔
184
        }
1✔
185

186
        @Override
187
        public TypeSystem getTypeSystem() {
188
            return owner.getTypeSystem();
1✔
189
        }
190

191
        @Override
192
        public List<JTypeMirror> getFormalParameterTypes(Substitution subst) {
193
            return CollectionUtil.map(formals, p -> p.getTypeMirror(subst));
1✔
194
        }
195

196
        @Override
197
        public List<JTypeMirror> getThrownExceptionTypes(Substitution subst) {
198
            return emptyList();
1✔
199
        }
200

201
        @Override
202
        public List<JTypeVar> getTypeParameters() {
203
            return emptyList();
1✔
204
        }
205

206
        @Override
207
        public String getSimpleName() {
208
            return name;
1✔
209
        }
210

211
        @Override
212
        public List<JFormalParamSymbol> getFormalParameters() {
213
            return formals;
1✔
214
        }
215

216
        @Override
217
        public boolean isVarargs() {
218
            return (modifiers & VARARGS_MOD) != 0;
1✔
219
        }
220

221
        @Override
222
        public int getArity() {
223
            return formals.size();
1✔
224
        }
225

226
        @Override
227
        public @Nullable JTypeMirror getAnnotatedReceiverType(Substitution subst) {
228
            if (!this.hasReceiver()) {
×
229
                return null;
×
230
            }
231
            return getTypeSystem().declaration(owner).subst(subst);
×
232
        }
233

234
        @Override
235
        public int getModifiers() {
236
            return modifiers;
1✔
237
        }
238

239
        @Override
240
        public @NonNull JClassSymbol getEnclosingClass() {
241
            return owner;
1✔
242
        }
243

244
        @Override
245
        public String toString() {
246
            return SymbolToStrings.FAKE.toString(this);
×
247
        }
248
    }
249

250
    private static final class FakeMethodSym extends FakeExecutableSymBase<JMethodSymbol> implements JMethodSymbol {
251

252
        private final BiFunction<? super TypeSystem, ? super JClassSymbol, ? extends JTypeMirror> returnType;
253

254
        FakeMethodSym(JClassSymbol owner,
255
                      String name,
256
                      int modifiers,
257
                      BiFunction<? super TypeSystem, ? super JClassSymbol, ? extends JTypeMirror> returnType,
258
                      List<Function<JMethodSymbol, JFormalParamSymbol>> formals) {
259
            super(owner, name, modifiers, formals);
1✔
260
            this.returnType = returnType;
1✔
261
        }
1✔
262

263
        @Override
264
        public boolean isBridge() {
265
            return false;
×
266
        }
267

268
        @Override
269
        public JTypeMirror getReturnType(Substitution subst) {
270
            return returnType.apply(getTypeSystem(), getEnclosingClass());
1✔
271
        }
272

273
        @Override
274
        public boolean equals(Object o) {
275
            return SymbolEquality.METHOD.equals(this, o);
1✔
276
        }
277

278
        @Override
279
        public int hashCode() {
280
            return SymbolEquality.METHOD.hash(this);
1✔
281
        }
282
    }
283

284
    private static final class FakeCtorSym extends FakeExecutableSymBase<JConstructorSymbol> implements JConstructorSymbol {
285

286
        FakeCtorSym(JClassSymbol owner,
287
                    int modifiers,
288
                    List<Function<JConstructorSymbol, JFormalParamSymbol>> formals) {
289
            super(owner, JConstructorSymbol.CTOR_NAME, modifiers, formals);
1✔
290
        }
1✔
291

292

293
        @Override
294
        public boolean equals(Object o) {
295
            return SymbolEquality.CONSTRUCTOR.equals(this, o);
1✔
296
        }
297

298
        @Override
299
        public int hashCode() {
300
            return SymbolEquality.CONSTRUCTOR.hash(this);
1✔
301
        }
302
    }
303

304
    private static final class FakeFormalParamSym implements JFormalParamSymbol {
305

306
        private final JExecutableSymbol owner;
307
        private final String name;
308
        private final ASTVariableId node;
309
        private final BiFunction<? super TypeSystem, ? super JFormalParamSymbol, ? extends JTypeMirror> type;
310

311
        private FakeFormalParamSym(JExecutableSymbol owner, String name, BiFunction<? super TypeSystem, ? super JFormalParamSymbol, ? extends JTypeMirror> type) {
312
            this(owner, name, null, type);
1✔
313
        }
1✔
314

315
        private FakeFormalParamSym(JExecutableSymbol owner, String name, @Nullable ASTVariableId node, BiFunction<? super TypeSystem, ? super JFormalParamSymbol, ? extends JTypeMirror> type) {
1✔
316
            this.owner = owner;
1✔
317
            this.name = name;
1✔
318
            this.node = node;
1✔
319
            this.type = type;
1✔
320
        }
1✔
321

322
        @Override
323
        public @Nullable ASTVariableId tryGetNode() {
324
            return node;
1✔
325
        }
326

327
        @Override
328
        public TypeSystem getTypeSystem() {
329
            return owner.getTypeSystem();
1✔
330
        }
331

332
        @Override
333
        public JTypeMirror getTypeMirror(Substitution subst) {
334
            return type.apply(getTypeSystem(), this).subst(subst);
1✔
335
        }
336

337
        @Override
338
        public JExecutableSymbol getDeclaringSymbol() {
339
            return owner;
1✔
340
        }
341

342
        @Override
343
        public boolean isFinal() {
344
            return false;
1✔
345
        }
346

347
        @Override
348
        public String getSimpleName() {
349
            return name;
1✔
350
        }
351

352
        @Override
353
        public String toString() {
354
            return SymbolToStrings.FAKE.toString(this);
×
355
        }
356

357
        @Override
358
        public boolean equals(Object o) {
359
            return SymbolEquality.FORMAL_PARAM.equals(this, o);
×
360
        }
361

362
        @Override
363
        public int hashCode() {
364
            return SymbolEquality.FORMAL_PARAM.hash(this);
1✔
365
        }
366
    }
367

368

369
    private static final class FakeFieldSym implements JFieldSymbol {
370

371
        private final JClassSymbol owner;
372
        private final String name;
373
        private final int modifiers;
374
        private final BiFunction<? super TypeSystem, ? super JClassSymbol, ? extends JTypeMirror> type;
375

376
        FakeFieldSym(JClassSymbol owner, String name, int modifiers, BiFunction<? super TypeSystem, ? super JClassSymbol, ? extends JTypeMirror> type) {
1✔
377
            this.owner = owner;
1✔
378
            this.name = name;
1✔
379
            this.modifiers = modifiers;
1✔
380
            this.type = type;
1✔
381
        }
1✔
382

383
        @Override
384
        public TypeSystem getTypeSystem() {
385
            return owner.getTypeSystem();
1✔
386
        }
387

388
        @Override
389
        public JTypeMirror getTypeMirror(Substitution subst) {
390
            return type.apply(getTypeSystem(), owner).subst(subst);
1✔
391
        }
392

393
        @Override
394
        public String getSimpleName() {
395
            return name;
1✔
396
        }
397

398
        @Override
399
        public int getModifiers() {
400
            return modifiers;
1✔
401
        }
402

403
        @Override
404
        public boolean isEnumConstant() {
405
            return false;
×
406
        }
407

408
        @Override
409
        public @NonNull JClassSymbol getEnclosingClass() {
410
            return owner;
1✔
411
        }
412

413
        @Override
414
        public String toString() {
415
            return SymbolToStrings.FAKE.toString(this);
1✔
416
        }
417

418
        @Override
419
        public boolean equals(Object o) {
420
            return SymbolEquality.FIELD.equals(this, o);
1✔
421
        }
422

423
        @Override
424
        public int hashCode() {
425
            return SymbolEquality.FIELD.hash(this);
1✔
426
        }
427
    }
428

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