View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
5    */
6   package mockit.coverage.lines;
7   
8   import edu.umd.cs.findbugs.annotations.NonNull;
9   import edu.umd.cs.findbugs.annotations.Nullable;
10  
11  import java.io.Serializable;
12  import java.util.ArrayList;
13  import java.util.List;
14  
15  import mockit.coverage.CallPoint;
16  import mockit.coverage.Configuration;
17  
18  import org.checkerframework.checker.index.qual.NonNegative;
19  
20  public class LineSegmentData implements Serializable {
21      private static final long serialVersionUID = -6233980722802474992L;
22      private static final int MAX_CALL_POINTS = Integer.parseInt(Configuration.getProperty("maxCallPoints", "10"));
23  
24      // Constant data:
25      private boolean unreachable;
26      protected boolean empty;
27  
28      // Runtime data:
29      @NonNegative
30      int executionCount;
31      @Nullable
32      private List<CallPoint> callPoints;
33  
34      public final void markAsUnreachable() {
35          unreachable = true;
36      }
37  
38      final void markAsReachable() {
39          unreachable = false;
40      }
41  
42      public boolean isEmpty() {
43          return empty;
44      }
45  
46      final void markAsEmpty() {
47          empty = true;
48      }
49  
50      final boolean acceptsAdditionalCallPoints() {
51          return callPoints == null || callPoints.size() < MAX_CALL_POINTS;
52      }
53  
54      @NonNegative
55      final int registerExecution(@Nullable CallPoint callPoint) {
56          int previousExecutionCount = executionCount++;
57  
58          if (callPoint != null) {
59              addCallPoint(callPoint);
60          }
61  
62          return previousExecutionCount;
63      }
64  
65      private void addCallPoint(@NonNull CallPoint callPoint) {
66          if (callPoints == null) {
67              callPoints = new ArrayList<>(MAX_CALL_POINTS);
68          }
69  
70          for (int i = callPoints.size() - 1; i >= 0; i--) {
71              CallPoint previousCallPoint = callPoints.get(i);
72  
73              if (callPoint.isSameLineInTestCode(previousCallPoint)) {
74                  previousCallPoint.incrementRepetitionCount();
75                  return;
76              }
77          }
78  
79          callPoints.add(callPoint);
80      }
81  
82      public final boolean containsCallPoints() {
83          return callPoints != null;
84      }
85  
86      @Nullable
87      public final List<CallPoint> getCallPoints() {
88          return callPoints;
89      }
90  
91      @NonNegative
92      public final int getExecutionCount() {
93          return executionCount;
94      }
95  
96      final void setExecutionCount(@NonNegative int executionCount) {
97          this.executionCount = executionCount;
98      }
99  
100     public final boolean isCovered() {
101         return unreachable || !empty && executionCount > 0;
102     }
103 
104     final void addExecutionCountAndCallPointsFromPreviousTestRun(@NonNull LineSegmentData previousData) {
105         executionCount += previousData.executionCount;
106 
107         if (previousData.callPoints != null) {
108             if (callPoints != null) {
109                 callPoints.addAll(0, previousData.callPoints);
110             } else {
111                 callPoints = previousData.callPoints;
112             }
113         }
114     }
115 }