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

hazendaz / jmockit1 / 496

15 Nov 2025 05:33PM UTC coverage: 72.192% (-0.008%) from 72.2%
496

push

github

web-flow
Merge pull request #412 from hazendaz/renovate/major-spring-core

Update spring core to v7 (major)

5677 of 8360 branches covered (67.91%)

Branch coverage included in aggregate %.

11922 of 16018 relevant lines covered (74.43%)

0.74 hits per line

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

0.0
/main/src/main/java/mockit/coverage/modification/CFGTracking.java
1
/*
2
 * MIT License
3
 * Copyright (c) 2006-2025 JMockit developers
4
 * See LICENSE file for full license text.
5
 */
6
package mockit.coverage.modification;
7

8
import static mockit.asm.jvmConstants.Opcodes.ICONST_0;
9
import static mockit.asm.jvmConstants.Opcodes.ICONST_1;
10
import static mockit.asm.jvmConstants.Opcodes.INVOKEVIRTUAL;
11

12
import edu.umd.cs.findbugs.annotations.NonNull;
13

14
import java.util.ArrayList;
15
import java.util.List;
16

17
import mockit.asm.controlFlow.Label;
18
import mockit.coverage.lines.BranchCoverageData;
19
import mockit.coverage.lines.LineCoverageData;
20
import mockit.coverage.lines.PerFileLineCoverage;
21

22
import org.checkerframework.checker.index.qual.NonNegative;
23

24
final class CFGTracking {
25
    @NonNull
26
    private final PerFileLineCoverage lineCoverageInfo;
27
    @NonNull
28
    private final List<Label> visitedLabels;
29
    @NonNull
30
    private final List<Label> jumpTargetsForCurrentLine;
31
    @NonNull
32
    private final List<Integer> pendingBranches;
33
    @NonNegative
34
    private int lineExpectingInstructionAfterJump;
35
    private boolean assertFoundInCurrentLine;
36
    private boolean ignoreUntilNextLabel;
37
    @NonNegative
38
    private int foundPotentialBooleanExpressionValue;
39
    @NonNegative
40
    private int ignoreUntilNextSwitch;
41

42
    CFGTracking(@NonNull PerFileLineCoverage lineCoverageInfo) {
×
43
        this.lineCoverageInfo = lineCoverageInfo;
×
44
        visitedLabels = new ArrayList<>();
×
45
        jumpTargetsForCurrentLine = new ArrayList<>(4);
×
46
        pendingBranches = new ArrayList<>(6);
×
47
    }
×
48

49
    void startNewLine() {
50
        if (!pendingBranches.isEmpty()) {
×
51
            pendingBranches.clear();
×
52
        }
53

54
        jumpTargetsForCurrentLine.clear();
×
55
    }
×
56

57
    void afterNewLabel(@NonNegative int currentLine, @NonNull Label label) {
58
        if (ignoreUntilNextLabel || ignoreUntilNextSwitch > 0) {
×
59
            ignoreUntilNextLabel = false;
×
60
            return;
×
61
        }
62

63
        visitedLabels.add(label);
×
64

65
        int jumpTargetIndex = jumpTargetsForCurrentLine.indexOf(label);
×
66

67
        if (jumpTargetIndex >= 0) {
×
68
            label.jumpTargetLine = label.line > 0 ? label.line : currentLine;
×
69
            int targetBranchIndex = 2 * jumpTargetIndex + 1;
×
70
            pendingBranches.add(targetBranchIndex);
×
71
            assertFoundInCurrentLine = false;
×
72
        }
73

74
        foundPotentialBooleanExpressionValue = 0;
×
75
    }
×
76

77
    void afterGoto() {
78
        assertFoundInCurrentLine = false;
×
79

80
        if (foundPotentialBooleanExpressionValue == 1) {
×
81
            foundPotentialBooleanExpressionValue = 2;
×
82
        }
83
    }
×
84

85
    void afterConditionalJump(@NonNull MethodModifier methodModifier, @NonNull Label jumpSource,
86
            @NonNull Label jumpTarget) {
87
        int currentLine = methodModifier.currentLine;
×
88

89
        if (currentLine == 0 || ignoreUntilNextLabel || ignoreUntilNextSwitch > 0
×
90
                || visitedLabels.contains(jumpTarget)) {
×
91
            assertFoundInCurrentLine = false;
×
92
            return;
×
93
        }
94

95
        jumpSource.jumpTargetLine = currentLine;
×
96

97
        if (!jumpTargetsForCurrentLine.contains(jumpTarget)) {
×
98
            jumpTargetsForCurrentLine.add(jumpTarget);
×
99
        }
100

101
        LineCoverageData lineData = lineCoverageInfo.getOrCreateLineData(currentLine);
×
102
        int sourceBranchIndex = lineData.addBranchingPoint(jumpSource, jumpTarget);
×
103
        pendingBranches.add(sourceBranchIndex);
×
104

105
        if (assertFoundInCurrentLine) {
×
106
            BranchCoverageData branchData = lineCoverageInfo.getBranchData(currentLine, sourceBranchIndex + 1);
×
107
            branchData.markAsUnreachable();
×
108
        }
109

110
        lineExpectingInstructionAfterJump = 0;
×
111
        generateCallToRegisterBranchTargetExecutionIfPending(methodModifier);
×
112
        lineExpectingInstructionAfterJump = currentLine;
×
113
    }
×
114

115
    void generateCallToRegisterBranchTargetExecutionIfPending(@NonNull MethodModifier methodModifier) {
116
        if (ignoreUntilNextLabel || ignoreUntilNextSwitch > 0) {
×
117
            return;
×
118
        }
119

120
        foundPotentialBooleanExpressionValue = 0;
×
121

122
        if (!pendingBranches.isEmpty()) {
×
123
            for (Integer pendingBranchIndex : pendingBranches) {
×
124
                methodModifier.generateCallToRegisterBranchTargetExecution(pendingBranchIndex);
×
125
            }
×
126

127
            pendingBranches.clear();
×
128
        }
129

130
        if (lineExpectingInstructionAfterJump > 0) {
×
131
            if (methodModifier.currentLine > lineExpectingInstructionAfterJump) {
×
132
                lineCoverageInfo.markLastLineSegmentAsEmpty(lineExpectingInstructionAfterJump);
×
133
            }
134

135
            lineExpectingInstructionAfterJump = 0;
×
136
        }
137
    }
×
138

139
    boolean hasOnlyOneLabelBeingVisited() {
140
        return visitedLabels.size() == 1;
×
141
    }
142

143
    void registerAssertFoundInCurrentLine() {
144
        assertFoundInCurrentLine = true;
×
145
        ignoreUntilNextLabel = true;
×
146
    }
×
147

148
    void beforeNoOperandInstruction(@NonNull MethodModifier methodModifier, @NonNegative int opcode) {
149
        if ((opcode == ICONST_0 || opcode == ICONST_1) && foundPotentialBooleanExpressionValue == 0) {
×
150
            generateCallToRegisterBranchTargetExecutionIfPending(methodModifier);
×
151
            foundPotentialBooleanExpressionValue = 1;
×
152
        } else {
153
            generateCallToRegisterBranchTargetExecutionIfPending(methodModifier);
×
154
        }
155
    }
×
156

157
    void afterMethodInstruction(@NonNegative int opcode, @NonNull String owner, @NonNull String name) {
158
        if (opcode == INVOKEVIRTUAL && "hashCode".equals(name) && "java/lang/String".equals(owner)
×
159
                && ignoreUntilNextSwitch == 0) {
160
            ignoreUntilNextSwitch = 1;
×
161
        }
162
    }
×
163

164
    void beforeLookupSwitchInstruction() {
165
        if (ignoreUntilNextSwitch == 1) {
×
166
            ignoreUntilNextSwitch = 2;
×
167
        }
168
    }
×
169
}
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