@@ -73,6 +73,24 @@ index 47904b61..185a3790 100644
7373 </executions>
7474 </plugin>
7575 </plugins>
76+ diff --git a/jflex/src/main/java/jflex/state/StateSet.java b/jflex/src/main/java/jflex/state/StateSet.java
77+ index 26b7591c..cfba5a35 100644
78+ --- a/jflex/src/main/java/jflex/state/StateSet.java
79+ +++ b/jflex/src/main/java/jflex/state/StateSet.java
80+ @@ -407,4 +407,13 @@ public final class StateSet implements Iterable<Integer> {
81+ public Iterator<Integer> iterator() {
82+ return states();
83+ }
84+ +
85+ + /**
86+ + * Provide the max value that can be stored without a resize
87+ + *
88+ + * @return an int of the max value
89+ + */
90+ + public int getCurrentMaxState() {
91+ + return (bits.length << BITS) | ~(0xFFFFFFFF << BITS);
92+ + }
93+ }
7694diff --git a/jflex/src/test/java/jflex/core/unicode/BUILD.bazel b/jflex/src/test/java/jflex/core/unicode/BUILD.bazel
7795index 109146e2..4af8ce29 100644
7896--- a/jflex/src/test/java/jflex/core/unicode/BUILD.bazel
@@ -306,7 +324,7 @@ index e9962397..1f4d2443 100644
306324 }
307325
308326diff --git a/jflex/src/test/java/jflex/state/StateSetQuickcheck.java b/jflex/src/test/java/jflex/state/StateSetQuickcheck.java
309- index 2537700d..0ac0e12c 100644
327+ index 2537700d..d15c4438 100644
310328--- a/jflex/src/test/java/jflex/state/StateSetQuickcheck.java
311329+++ b/jflex/src/test/java/jflex/state/StateSetQuickcheck.java
312330@@ -11,9 +11,13 @@ package jflex.state;
@@ -323,35 +341,40 @@ index 2537700d..0ac0e12c 100644
323341 import com.pholser.junit.quickcheck.generator.InRange;
324342 import com.pholser.junit.quickcheck.generator.Size;
325343 import com.pholser.junit.quickcheck.runner.JUnitQuickcheck;
326- @@ -157,7 +161,8 @@ public class StateSetQuickcheck {
327- @Property
328- public void removeAdd(
329- @Size(max = 90) @InRange(minInt = 0, maxInt = 100) StateSet s,
330- - @InRange(minInt = 0, maxInt = 100) int e) {
344+ @@ -167,6 +171,32 @@ public class StateSetQuickcheck {
345+ assertThat(s).isEqualTo(sPre);
346+ }
347+
348+ + @Property
349+ + public void removeAddResize(
350+ + @Size(max = 90) @InRange(minInt = 0, maxInt = 100) StateSet s,
331351+ @InRange(minInt = 0, maxInt = 100) int e,
332352+ @From(OffsetGen.class) int largeOffset) {
333- assumeTrue(s.hasElement(e));
334- StateSet sPre = new StateSet(s);
335- s.remove(e);
336- @@ -165,6 +170,17 @@ public class StateSetQuickcheck {
337- assertThat(s).isNotEqualTo(sPre);
338- s.addState(e);
339- assertThat(s).isEqualTo(sPre);
353+ + assumeTrue(s.hasElement(e));
354+ + StateSet sPre = new StateSet(s);
355+ + s.remove(e);
356+ + assertThat(sPre.contains(s)).isTrue();
357+ + assertThat(s).isNotEqualTo(sPre);
358+ + s.addState(e);
359+ + assertThat(s).isEqualTo(sPre);
340360+
341361+ // add larger state value to force resize
342- + if ((Integer.MAX_VALUE - largeOffset) <= s.bits.length) { // avoid overrun wrap
343- + largeOffset = Integer.MAX_VALUE - s.bits.length;
362+ + int largerState;
363+ + try {
364+ + largerState = Math.addExact(s.getCurrentMaxState(), largeOffset);
365+ + } catch (ArithmeticException arithmeticException) {
366+ + largerState = Integer.MAX_VALUE;
344367+ }
345- + int largerState =
346- + ((s.bits.length + largeOffset) << StateSet.BITS) & Integer.MAX_VALUE; // & resets sign bit
347368+ s.addState(largerState);
348369+ assertThat(s).contains(largerState);
349370+ s.remove(largerState);
350371+ assertThat(s).isEqualTo(sPre);
351- }
352-
372+ + }
373+ +
353374 @Property
354- @@ -181,10 +197,27 @@ public class StateSetQuickcheck {
375+ public void clearMakesEmpty(StateSet set) {
376+ set.clear();
377+ @@ -181,10 +211,27 @@ public class StateSetQuickcheck {
355378 }
356379
357380 @Property
@@ -380,20 +403,19 @@ index 2537700d..0ac0e12c 100644
380403 }
381404
382405 @Property
383- @@ -208,6 +241,12 @@ public class StateSetQuickcheck {
406+ @@ -208,6 +255,11 @@ public class StateSetQuickcheck {
384407 StateSet comp = s1.complement(s2);
385408 // only elements of s2 are in the complement
386409 assertThat(s2.contains(comp)).isTrue();
387410+
388411+ // ensure that comp does not contain s1
389- + StateSet empty = new StateSet();
390- + if (!empty.contains(s1)) { // if s1 is {}, then it will always be contained in comp
412+ + if (s1.containsElements()) { // if s1 is {}, then it will always be contained in comp
391413+ assertThat(comp.contains(s1)).isFalse();
392414+ }
393415 }
394416
395417 @Property
396- @@ -228,6 +267 ,13 @@ public class StateSetQuickcheck {
418+ @@ -228,6 +280 ,13 @@ public class StateSetQuickcheck {
397419 public void containsElements(StateSet s, @InRange(minInt = 0, maxInt = 34) int e) {
398420 s.addState(e);
399421 assertThat(s.containsElements()).isTrue();
0 commit comments