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

pmd / pmd / 277

27 Nov 2025 01:37PM UTC coverage: 78.778% (+0.03%) from 78.749%
277

push

github

adangel
[java] UseArraysAsList: skip when if-statements (#6228)

18419 of 24233 branches covered (76.01%)

Branch coverage included in aggregate %.

40090 of 50038 relevant lines covered (80.12%)

0.81 hits per line

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

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

7
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
8

9
import java.util.List;
10

11
import org.apache.commons.lang3.ArrayUtils;
12
import org.checkerframework.checker.nullness.qual.NonNull;
13
import org.checkerframework.checker.nullness.qual.Nullable;
14

15
/**
16
 * Resolves symbols from their global name. This abstracts over whether
17
 * we're looking on a classpath, in a file tree, in a serialized index, etc.
18
 */
19
public interface SymbolResolver {
1!
20

21
    /**
22
     * Resolves a class symbol from its canonical name. Periods ('.') will
23
     * not be interpreted as nested-class separators, so this performs at
24
     * most one classloader lookup. Note that external symbol resolvers
25
     * do not need to implement lookup for primitive types, for local
26
     * and anonymous classes, or for array classes. This is handled by
27
     * the AST implementation or by the type system. Looking up such symbols
28
     * is undefined behaviour.
29
     */
30
    @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName);
31

32
    /**
33
     * @since 7.5.0
34
     */
35
    @Nullable JModuleSymbol resolveModule(@NonNull String moduleName);
36

37
    /**
38
     * Resolves a class symbol from its canonical name. Periods ('.') may
39
     * be interpreted as nested-class separators, so for n segments, this
40
     * performs at most n classloader lookups.
41
     */
42
    default @Nullable JClassSymbol resolveClassFromCanonicalName(@NonNull String canonicalName) {
43
        JClassSymbol symbol = resolveClassFromBinaryName(canonicalName);
1✔
44
        if (symbol != null) {
1✔
45
            return symbol;
1✔
46
        }
47
        int lastDotIdx = canonicalName.lastIndexOf('.');
1✔
48
        if (lastDotIdx < 0) {
1✔
49
            return null;
1✔
50
        } else {
51
            JClassSymbol outer = resolveClassFromCanonicalName(canonicalName.substring(0, lastDotIdx));
1✔
52
            if (outer != null) {
1✔
53
                String innerName = canonicalName.substring(lastDotIdx + 1);
1✔
54
                return outer.getDeclaredClass(innerName);
1✔
55
            }
56
        }
57

58
        return null;
1✔
59
    }
60

61

62
    /**
63
     * Produce a symbol resolver that asks the given resolvers in order.
64
     *
65
     * @param first  First resolver
66
     * @param others Rest of the resolvers
67
     */
68
    static SymbolResolver layer(SymbolResolver first, SymbolResolver... others) {
69
        assert first != null : "Null first table";
1!
70
        assert others != null : "Null array";
1!
71
        assert !ArrayUtils.contains(others, null) : "Null component";
1!
72

73
        return new SymbolResolver() {
1✔
74
            private final List<SymbolResolver> stack = listOf(first, others);
1✔
75

76
            @Override
77
            public @Nullable JClassSymbol resolveClassFromBinaryName(@NonNull String binaryName) {
78
                for (SymbolResolver resolver : stack) {
1✔
79
                    JClassSymbol sym = resolver.resolveClassFromBinaryName(binaryName);
1✔
80
                    if (sym != null) {
1✔
81
                        return sym;
1✔
82
                    }
83
                }
1✔
84
                return null;
1✔
85
            }
86

87
            @Override
88
            public @Nullable JModuleSymbol resolveModule(@NonNull String moduleName) {
89
                for (SymbolResolver resolver : stack) {
1✔
90
                    JModuleSymbol symbol = resolver.resolveModule(moduleName);
1✔
91
                    if (symbol != null) {
1✔
92
                        return symbol;
1✔
93
                    }
94
                }
1✔
95
                return null;
1✔
96
            }
97

98
            @Override
99
            public void logStats() {
100
                stack.forEach(SymbolResolver::logStats);
×
101
            }
×
102
        };
103
    }
104

105
    /**
106
     * Called at the end of the analysis in order to log out statistics of the resolved symbols.
107
     */
108
    void logStats();
109
}
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