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

pmd / pmd / 119

15 Aug 2025 10:06AM UTC coverage: 78.488% (+0.01%) from 78.476%
119

push

github

adangel
[java] ShortVariable - improve detection of unnamed variables

Refs #5914

Co-authored-by: Juan Martín Sotuyo Dodero <juan.sotuyo@pedidosya.com>

17911 of 23661 branches covered (75.7%)

Branch coverage included in aggregate %.

39213 of 49120 relevant lines covered (79.83%)

0.81 hits per line

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

45.26
/pmd-core/src/main/java/net/sourceforge/pmd/util/AssertionUtil.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.util;
6

7

8
import java.util.Collection;
9
import java.util.function.Function;
10
import java.util.regex.Pattern;
11

12
import org.apache.commons.lang3.StringUtils;
13
import org.apache.commons.lang3.exception.ContextedRuntimeException;
14
import org.checkerframework.checker.nullness.qual.NonNull;
15

16
public final class AssertionUtil {
17

18
    private static final Pattern PACKAGE_PATTERN = Pattern.compile("[\\w$]+(\\.[\\w$]+)*|");
1✔
19
    private static final Pattern BINARY_NAME_PATTERN = Pattern.compile("[\\w$]+(?:\\.[\\w$]+)*(?:\\[])*");
1✔
20
    private static final Pattern BINARY_NAME_NO_ARRAY = Pattern.compile("[\\w$]++(?:\\.[\\w$]++)*");
1✔
21

22
    private static final boolean ASSERT_ENABLED;
23

24
    private static boolean areAssertsEnabled() {
25
        try {
26
            assert false;
1✔
27
            return false;
×
28
        } catch (AssertionError e) {
1✔
29
            return true;
1✔
30
        }
31
    }
32

33
    static {
34
        ASSERT_ENABLED = areAssertsEnabled();
1✔
35
    }
1✔
36

37
    private AssertionUtil() {
38
        // utility class
39
    }
40

41
    /**
42
     * Return true if the VM runs with assertions enabled.
43
     */
44
    public static boolean isAssertEnabled() {
45
        return ASSERT_ENABLED;
×
46
    }
47

48
    /** @throws NullPointerException if any item is null */
49
    public static void requireContainsNoNullValue(String name, Collection<?> c) {
50
        int i = 0;
1✔
51
        for (Object o : c) {
1✔
52
            if (o == null) {
1!
53
                throw new NullPointerException(name + " contains a null element at index " + i);
×
54
            }
55
            i++;
1✔
56
        }
1✔
57
    }
1✔
58

59
    /** @throws IllegalArgumentException if empty */
60
    public static void requireNotEmpty(String name, Collection<?> c) {
61
        if (c.isEmpty()) {
1!
62
            throw new IllegalArgumentException(name + " is empty");
×
63
        }
64
    }
1✔
65

66
    public static boolean isValidJavaPackageName(CharSequence name) {
67
        requireParamNotNull("name", name);
×
68
        return PACKAGE_PATTERN.matcher(name).matches();
×
69
    }
70

71
    /**
72
     * @throws IllegalArgumentException if the name is not a binary name
73
     */
74
    public static void assertValidJavaBinaryName(CharSequence name) {
75
        if (!isJavaBinaryName(name)) {
×
76
            throw new IllegalArgumentException("Not a Java binary name '" + name + "'");
×
77
        }
78
    }
×
79

80
    /**
81
     * @throws IllegalArgumentException if the name is not a binary name
82
     */
83
    public static void assertValidJavaBinaryNameNoArray(CharSequence name) {
84
        if (!BINARY_NAME_NO_ARRAY.matcher(name).matches()) {
×
85
            throw new IllegalArgumentException("Not a Java binary name '" + name + "'");
×
86
        }
87
    }
×
88

89
    private static boolean isJavaBinaryName(CharSequence name) {
90
        return name.length() > 0 && BINARY_NAME_PATTERN.matcher(name).matches();
×
91
    }
92

93
    private static boolean isValidRange(int startInclusive, int endExclusive, int minIndex, int maxIndex) {
94
        return startInclusive <= endExclusive && minIndex <= startInclusive && endExclusive <= maxIndex;
×
95
    }
96

97
    private static String invalidRangeMessage(int startInclusive, int endExclusive, int minIndex, int maxIndex) {
98
        return "Invalid range [" + startInclusive + "," + endExclusive + "[ in [" + minIndex + "," + maxIndex + "[";
×
99
    }
100

101

102
    /** Throws {@link IllegalStateException} if the condition is false. */
103
    public static void validateState(boolean condition, String failed) {
104
        if (!condition) {
1✔
105
            throw new IllegalStateException(failed);
1✔
106
        }
107
    }
1✔
108

109

110
    /**
111
     * @throws IllegalArgumentException if [startInclusive,endExclusive[ is
112
     *                                  not a valid substring range for the given string
113
     */
114
    public static void validateStringRange(CharSequence string, int startInclusive, int endExclusive) {
115
        if (!isValidRange(startInclusive, endExclusive, 0, string.length())) {
×
116
            throw new IllegalArgumentException(invalidRangeMessage(startInclusive, endExclusive, 0, string.length()));
×
117
        }
118
    }
×
119

120
    /**
121
     * Like {@link #validateStringRange(CharSequence, int, int)} but eliminated
122
     * at runtime if running without assertions.
123
     */
124
    public static void assertValidStringRange(CharSequence string, int startInclusive, int endExclusive) {
125
        assert isValidRange(startInclusive, endExclusive, 0, string.length())
×
126
            : invalidRangeMessage(startInclusive, endExclusive, 0, string.length());
×
127
    }
×
128

129
    /**
130
     * Returns true if the charsequence is a valid java identifier.
131
     *
132
     * @param name Name (non-null)
133
     *
134
     * @throws NullPointerException If the name is null
135
     */
136
    public static boolean isJavaIdentifier(CharSequence name) {
137
        int len = name.length();
×
138
        if (len == 0 || !Character.isJavaIdentifierStart(name.charAt(0))) {
×
139
            return false;
×
140
        }
141

142
        for (int i = 1; i < len; i++) {
×
143
            if (!Character.isJavaIdentifierPart(name.charAt(i))) {
×
144
                return false;
×
145
            }
146
        }
147

148
        return true;
×
149
    }
150

151
    public static int requireOver1(String name, final int value) {
152
        if (value < 1) {
1!
153
            throw mustBe(name, value, ">= 1");
×
154
        }
155
        return value;
1✔
156
    }
157

158

159
    /**
160
     * @throws IllegalArgumentException If {@code value < 0}
161
     */
162
    public static int requireNonNegative(String name, int value) {
163
        if (value < 0) {
1✔
164
            throw mustBe(name, value, "non-negative");
1✔
165
        }
166
        return value;
1✔
167
    }
168

169

170
    /**
171
     * @throws IndexOutOfBoundsException If {@code value < 0}
172
     */
173
    public static int requireIndexNonNegative(String name, int value) {
174
        if (value < 0) {
1!
175
            throw mustBe(name, value, "non-negative", IndexOutOfBoundsException::new);
×
176
        }
177
        return value;
1✔
178
    }
179

180
    /**
181
     * @throws IndexOutOfBoundsException If {@code value < 0 || value >= maxValue}
182
     */
183
    public static int requireInNonNegativeRange(String name, int value, int maxValue) {
184
        return requireInExclusiveRange(name, value, 0, maxValue);
×
185
    }
186

187
    /**
188
     * @throws IndexOutOfBoundsException If {@code value < 1 || value >= maxValue}
189
     */
190
    public static int requireInPositiveRange(String name, int value, int maxValue) {
191
        return requireInExclusiveRange(name, value, 1, maxValue);
1✔
192
    }
193

194
    // the difference between those two is the message
195

196
    /**
197
     * @throws IndexOutOfBoundsException If {@code value < minValue || value > maxValue}
198
     */
199
    public static int requireInInclusiveRange(String name, int value, int minValue, int maxValue) {
200
        return requireInRange(name, value, minValue, maxValue, true);
1✔
201
    }
202

203
    /**
204
     * @throws IndexOutOfBoundsException If {@code value < minValue || value > maxValue}
205
     */
206
    public static int requireInExclusiveRange(String name, int value, int minValue, int maxValue) {
207
        return requireInRange(name, value, minValue, maxValue, false);
1✔
208
    }
209

210
    public static int requireInRange(String name, int value, int minValue, int maxValue, boolean inclusive) {
211
        if (value < 0 || inclusive && value > maxValue || !inclusive && value >= maxValue) {
1!
212
            String message = "in range [" + minValue + "," + maxValue;
1✔
213
            message += inclusive ? "]" : "[";
1!
214
            throw mustBe(name, value, message, IndexOutOfBoundsException::new);
1✔
215
        }
216
        return value;
1✔
217
    }
218

219
    public static RuntimeException mustBe(String name, Object value, String condition) {
220
        return mustBe(name, value, condition, IllegalArgumentException::new);
1✔
221
    }
222

223
    public static <E extends RuntimeException> E mustBe(String name, Object value, String condition, Function<String, E> exceptionMaker) {
224
        return exceptionMaker.apply(String.format("%s must be %s, got %s", name, condition, value));
1✔
225
    }
226

227
    @NonNull
228
    public static <T> T requireParamNotNull(String paramName, T obj) {
229
        if (obj == null) {
1!
230
            throw new NullPointerException("Parameter " + paramName + " is null");
×
231
        }
232

233
        return obj;
1✔
234
    }
235

236
    public static @NonNull AssertionError shouldNotReachHere(String message) {
237
        return shouldNotReachHere(message, null);
×
238
    }
239

240
    public static @NonNull AssertionError shouldNotReachHere(String message, Throwable cause) {
241
        String prefix = "This should be unreachable";
×
242
        message = StringUtils.isBlank(message) ? prefix
×
243
                                               : prefix + ": " + message;
×
244
        return new AssertionError(message, cause);
×
245
    }
246

247
    public static @NonNull ContextedAssertionError contexted(AssertionError e) {
248
        return ContextedAssertionError.wrap(e);
1✔
249
    }
250

251
    public static @NonNull ContextedStackOverflowError contexted(StackOverflowError e) {
252
        return ContextedStackOverflowError.wrap(e);
×
253
    }
254

255
    public static @NonNull ContextedRuntimeException contexted(RuntimeException e) {
256
        return e instanceof ContextedRuntimeException ? (ContextedRuntimeException) e
1!
257
                                                      : new ContextedRuntimeException(e);
1✔
258
    }
259

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