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

pmd / pmd / 173

25 Sep 2025 07:45AM UTC coverage: 78.654% (-0.003%) from 78.657%
173

push

github

web-flow
chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin from 3.14.0 to 3.14.1 (#6091)

chore(deps): bump org.apache.maven.plugins:maven-compiler-plugin

Bumps [org.apache.maven.plugins:maven-compiler-plugin](https://github.com/apache/maven-compiler-plugin) from 3.14.0 to 3.14.1.
- [Release notes](https://github.com/apache/maven-compiler-plugin/releases)
- [Commits](https://github.com/apache/maven-compiler-plugin/compare/maven-compiler-plugin-3.14.0...maven-compiler-plugin-3.14.1)

---
updated-dependencies:
- dependency-name: org.apache.maven.plugins:maven-compiler-plugin
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

18175 of 23959 branches covered (75.86%)

Branch coverage included in aggregate %.

39693 of 49614 relevant lines covered (80.0%)

0.81 hits per line

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

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

7
import static net.sourceforge.pmd.util.AssertionUtil.isAssertEnabled;
8

9
import org.slf4j.Logger;
10
import org.slf4j.LoggerFactory;
11

12
/**
13
 * A simple double-checked initializer, that parses something (a class,
14
 * or a type signature).
15
 */
16
@SuppressWarnings({"PMD.AvoidUsingVolatile", "PMD.AvoidCatchingThrowable"})
17
abstract class ParseLock {
18

19
    private static final Logger LOG = LoggerFactory.getLogger(ParseLock.class);
1✔
20

21
    private volatile ParseStatus status = ParseStatus.NOT_PARSED;
1✔
22
    private final String name;
23

24
    protected ParseLock(String name) {
1✔
25
        this.name = name;
1✔
26
    }
1✔
27

28
    public void ensureParsed() {
29
        getFinalStatus();
1✔
30
    }
1✔
31

32

33
    private void logParseLockTrace(String prefix) {
34
        if (LOG.isTraceEnabled()) {
1!
35
            LOG.trace("{} {}: {}", Thread.currentThread().getName(), String.format("%-15s", prefix), this);
×
36
        }
37
    }
1✔
38

39
    void checkWeAreNotParsingAnother() {
40
       // by default do nothing, overridden by CheckedParseLock
41
    }
1✔
42

43

44
    void releaseLock() {
45
        // by default do nothing, overridden by CheckedParseLock
46
    }
1✔
47

48
    private ParseStatus getFinalStatus() {
49
        ParseStatus status = this.status;
1✔
50
        if (!status.isFinished) {
1✔
51
            logParseLockTrace("waiting on");
1✔
52

53
            try {
54
                checkWeAreNotParsingAnother();
1✔
55
                synchronized (this) {
1✔
56
                    logParseLockTrace("locked");
1✔
57

58
                    status = this.status;
1✔
59
                    if (status == ParseStatus.NOT_PARSED) {
1!
60
                        this.status = ParseStatus.BEING_PARSED;
1✔
61
                        try {
62
                            boolean success = doParse();
1✔
63
                            status = success ? ParseStatus.FULL : ParseStatus.FAILED;
1✔
64
                            finishParse(!success);
1✔
65
                        } catch (Throwable t) {
×
66
                            status = ParseStatus.FAILED;
×
67
                            LOG.error("Parsing failed in ParseLock#doParse() of {}", name, t);
×
68
                            finishParse(true);
×
69
                        }
1✔
70

71
                        // the status must be updated as last statement, so that
72
                        // other threads see the status FULL or FAILED only after finishParse()
73
                        // returns. Otherwise, some fields might not have been initialized.
74
                        this.status = status;
1✔
75

76
                        assert status.isFinished : "Inconsistent status " + status;
1!
77
                        assert postCondition() : "Post condition not satisfied after parsing sig " + this;
1!
78
                    } else if (status == ParseStatus.BEING_PARSED) {
×
79
                        throw new IllegalStateException("Thread is reentering the parse lock " + this);
×
80
                    }
81
                }
1✔
82
            } finally {
83
                logParseLockTrace("released");
1✔
84
                releaseLock();
1✔
85
            }
86
        }
87
        return status;
1✔
88
    }
89

90
    public boolean isFailed() {
91
        return getFinalStatus() == ParseStatus.FAILED;
1✔
92
    }
93

94
    public boolean isNotParsed() {
95
        return status == ParseStatus.NOT_PARSED;
1✔
96
    }
97

98
    // will be called in the critical section after parse is done
99
    protected void finishParse(boolean failed) {
100
        // by default do nothing
101
    }
1✔
102

103
    /** Returns true if parse is successful. */
104
    protected abstract boolean doParse() throws Throwable; // SUPPRESS CHECKSTYLE IllegalThrows
105

106
    /** Checked by an assert after parse. */
107
    protected boolean postCondition() {
108
        return true;
1✔
109
    }
110

111
    @Override
112
    public String toString() {
113
        return "ParseLock{name=" + name + ",status=" + status + '}';
×
114
    }
115

116
    private enum ParseStatus {
1✔
117
        NOT_PARSED(false),
1✔
118
        BEING_PARSED(false),
1✔
119
        FULL(true),
1✔
120
        FAILED(true);
1✔
121

122
        final boolean isFinished;
123

124
        ParseStatus(boolean finished) {
1✔
125
            this.isFinished = finished;
1✔
126
        }
1✔
127
    }
128

129
    /**
130
     * Subclasses of this assert that any thread can hold at most one lock at a time. Threads cannot even reenter in the
131
     * lock they currently own. This prevents deadlocks while parsing ClassStub. However, all the instances of all derived
132
     * subclasses are mutually exclusive. This is meant for the parse lock of ClassStub, and should therefore only be extended
133
     * by that one.
134
     */
135
    abstract static class CheckedParseLock extends ParseLock {
136
        private static final ThreadLocal<ParseLock> CURRENT_LOCK = new ThreadLocal<>();
1✔
137

138
        protected CheckedParseLock(String name) {
139
            super(name);
1✔
140
        }
1✔
141

142
        @Override
143
        final void checkWeAreNotParsingAnother() {
144
            if (isAssertEnabled()) {
1!
145
                ParseLock lock = CURRENT_LOCK.get();
1✔
146
                if (lock != null) {
1!
147
                    throw new AssertionError("Parsing " + lock + " requested parsing of " + this);
×
148
                }
149
                CURRENT_LOCK.set(this);
1✔
150
            }
151
        }
1✔
152

153

154
        @Override
155
        final void releaseLock() {
156
            if (isAssertEnabled()) {
1!
157
                ParseLock lock = CURRENT_LOCK.get();
1✔
158
                assert lock == this : "Tried to release different parse lock " + lock + " from " + this; // NOPMD CompareObjectsWithEquals
1!
159
                CURRENT_LOCK.remove();
1✔
160
            }
161
        }
1✔
162
    }
163
}
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

© 2025 Coveralls, Inc