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

pmd / pmd / 486

23 Apr 2026 06:56PM UTC coverage: 79.035% (-0.01%) from 79.047%
486

push

github

adangel
[doc] basic.xml has been gone for a long time (#6607)

18603 of 24433 branches covered (76.14%)

Branch coverage included in aggregate %.

40592 of 50464 relevant lines covered (80.44%)

0.81 hits per line

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

10.81
/pmd-core/src/main/java/net/sourceforge/pmd/lang/ast/impl/antlr4/BaseAntlrNode.java
1
/*
2
 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
3
 */
4

5
package net.sourceforge.pmd.lang.ast.impl.antlr4;
6

7
import org.antlr.v4.runtime.ParserRuleContext;
8
import org.antlr.v4.runtime.Token;
9
import org.antlr.v4.runtime.tree.ErrorNode;
10
import org.antlr.v4.runtime.tree.ParseTree;
11
import org.antlr.v4.runtime.tree.TerminalNode;
12

13
import net.sourceforge.pmd.lang.ast.impl.GenericNode;
14
import net.sourceforge.pmd.lang.ast.impl.antlr4.BaseAntlrNode.AntlrToPmdParseTreeAdapter;
15
import net.sourceforge.pmd.lang.document.FileLocation;
16
import net.sourceforge.pmd.lang.document.TextRegion;
17
import net.sourceforge.pmd.util.DataMap;
18
import net.sourceforge.pmd.util.DataMap.DataKey;
19
import net.sourceforge.pmd.util.StringUtil;
20

21
/**
22
 * Base class for an antlr node. This implements the PMD interfaces only,
23
 * not the antlr ones. It wraps an antlr node (they are linked both ways).
24
 * Antlr primarily distinguishes {@link ParserRuleContext} for inner nodes,
25
 * {@link TerminalNode} for nodes that wrap tokens (and can have no children),
26
 * and {@link ErrorNode}, a subtype of {@link TerminalNode}. These each have
27
 * a base class here, which refines the type of the underlying antlr node:
28
 * {@link BaseAntlrInnerNode}, {@link BaseAntlrTerminalNode} and {@link BaseAntlrErrorNode}.
29
 * These must be implemented in each language module with a class that also
30
 * implements {@code <N>}.
31
 *
32
 * <p>During tree construction, the antlr runtime does its thing with the
33
 * underlying antlr nodes. The PMD nodes are just wrappers around those,
34
 * that respect the contract of {@link GenericNode}.
35
 *
36
 * @param <A> Type of the underlying antlr node
37
 * @param <N> Public interface (eg SwiftNode)
38
 */
39
public abstract class BaseAntlrNode<A extends AntlrToPmdParseTreeAdapter<N>, N extends AntlrNode<N>>
1✔
40
    implements AntlrNode<N> {
41

42
    private DataMap<DataKey<?, ?>> userMap;
43

44
    /**
45
     * The only node for which this is not overwritten is the root node, for
46
     * which by contract, this is -1.
47
     */
48
    private int indexInParent = -1;
1✔
49

50
    protected BaseAntlrNode() {
1✔
51
        // protected
52
    }
1✔
53

54
    /**
55
     * This implementation is only meant for debugging purposes.
56
     */
57
    @Override
58
    public String toString() {
59
        FileLocation loc = getReportLocation();
×
60
        return "!debug only! [" + getXPathNodeName() + ":" + loc.getStartPos().toDisplayStringWithColon() + "] "
×
61
            + StringUtil.elide(getAstInfo().getTextDocument().sliceTranslatedText(getTextRegion()).toString(),
×
62
            80,
63
            "(truncated)");
64
    }
65

66
    // these are an implementation detail, meant as a crutch while some
67
    // rules depend on it
68
    // Should be made protected
69

70
    public abstract Token getFirstAntlrToken();
71

72
    public abstract Token getLastAntlrToken();
73

74
    @Override
75
    public TextRegion getTextRegion() {
76
        Token firstAntlrToken = getFirstAntlrToken();
×
77
        Token lastAntlrToken = getLastAntlrToken();
×
78
        if (lastAntlrToken == null) {
×
79
            return TextRegion.fromOffsetLength(firstAntlrToken.getStartIndex(), firstAntlrToken.getStopIndex() + 1);
×
80
        } else {
81
            return TextRegion.fromBothOffsets(firstAntlrToken.getStartIndex(),
×
82
                    lastAntlrToken.getStopIndex() + 1);
×
83
        }
84
    }
85

86
    void setIndexInParent(int indexInParent) {
87
        this.indexInParent = indexInParent;
×
88
    }
×
89

90
    @Override
91
    public N getParent() {
92
        AntlrToPmdParseTreeAdapter<N> parent = asAntlrNode().getParent();
×
93
        return parent == null ? null : (N) parent.getPmdNode();
×
94
    }
95

96
    @Override
97
    public int getBeginLine() {
98
        return getFirstAntlrToken().getLine(); // This goes from 1 to n
×
99
    }
100

101
    @Override
102
    public int getEndLine() {
103
        // FIXME this is not the end line if the stop token spans several lines
104
        return getLastAntlrToken().getLine();
×
105
    }
106

107
    @Override
108
    public int getBeginColumn() {
109
        return getFirstAntlrToken().getCharPositionInLine() + 1;
×
110
    }
111

112
    @Override
113
    public int getEndColumn() {
114
        Token tok = getLastAntlrToken();
×
115
        return tok.getCharPositionInLine() + tok.getStopIndex() - tok.getStartIndex() + 1;
×
116
    }
117

118
    @Override
119
    public int getIndexInParent() {
120
        assert getParent() == null || indexInParent >= 0 : "Index not set";
×
121
        return indexInParent;
×
122
    }
123

124
    @Override
125
    public DataMap<DataKey<?, ?>> getUserMap() {
126
        if (userMap == null) {
×
127
            userMap = DataMap.newDataMap();
×
128
        }
129
        return userMap;
×
130
    }
131

132
    protected abstract A asAntlrNode();
133

134

135
    protected interface AntlrToPmdParseTreeAdapter<N extends AntlrNode<N>> extends ParseTree {
136

137
        BaseAntlrNode<?, N> getPmdNode();
138

139

140
        @Override
141
        AntlrToPmdParseTreeAdapter<N> getParent();
142
    }
143
}
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