Skip to content

Commit 4a361da

Browse files
committed
Made all CharacterClassEscapeRxGene objects of same type share a stateless MultiCharacterRange to sample characters instead of creating a different CharacterRangeRxGene for each CharacterClassEscapeRxGene instance
1 parent 359f2e5 commit 4a361da

1 file changed

Lines changed: 32 additions & 18 deletions

File tree

core/src/main/kotlin/org/evomaster/core/search/gene/regex/CharacterClassEscapeRxGene.kt

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import org.evomaster.core.search.service.mutator.MutationWeightControl
1111
import org.evomaster.core.search.service.mutator.genemutation.AdditionalGeneMutationInfo
1212
import org.evomaster.core.search.service.mutator.genemutation.SubsetGeneMutationSelectionStrategy
1313
import org.evomaster.core.utils.CharacterRange
14+
import org.evomaster.core.utils.MultiCharacterRange
1415
import org.slf4j.LoggerFactory
1516
import kotlin.collections.contains
1617

@@ -24,7 +25,7 @@ import kotlin.collections.contains
2425
\p{X} Find a character from X POSIX character class (eg:\p{Lower})
2526
*/
2627
class CharacterClassEscapeRxGene(
27-
val type: String
28+
val type: String
2829
) : RxAtom, SimpleGene("\\$type") {
2930

3031
companion object{
@@ -44,8 +45,20 @@ class CharacterClassEscapeRxGene(
4445
private val verticalSpaceSet = stringToListOfCharacterRanges("\n\u000B\u000C\r\u0085\u2028\u2029")
4546
private val punctuationSet = stringToListOfCharacterRanges("""!"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~""")
4647

48+
private val digitMultiCharRange = MultiCharacterRange(false, digitSet)
49+
private val wordMultiCharRange = MultiCharacterRange(false, wordSet)
50+
private val spaceMultiCharRange = MultiCharacterRange(false, spaceSet)
51+
private val horizontalSpaceMultiCharRange = MultiCharacterRange(false, horizontalSpaceSet)
52+
private val verticalSpaceMultiCharRange = MultiCharacterRange(false, verticalSpaceSet)
53+
54+
private val nonDigitMultiCharRange = MultiCharacterRange(true, digitSet)
55+
private val nonWordMultiCharRange = MultiCharacterRange(true, wordSet)
56+
private val nonSpaceMultiCharRange = MultiCharacterRange(true, spaceSet)
57+
private val nonHorizontalSpaceMultiCharRange = MultiCharacterRange(true, horizontalSpaceSet)
58+
private val nonVerticalSpaceMultiCharRange = MultiCharacterRange(true, verticalSpaceSet)
59+
4760
// US-ASCII POSIX character classes (\p{X})
48-
private val posixSets = mapOf(
61+
private val posixMultiCharRanges = mapOf(
4962
"Lower" to listOf(CharacterRange('a', 'z')),
5063
"Upper" to listOf(CharacterRange('A', 'Z')),
5164
"ASCII" to listOf(CharacterRange(0, 0x7f)),
@@ -59,35 +72,37 @@ class CharacterClassEscapeRxGene(
5972
"Cntrl" to listOf(CharacterRange(0, 0x1f)) + stringToListOfCharacterRanges("\u007f"),
6073
"XDigit" to listOf(CharacterRange('0', '9'), CharacterRange('a', 'f'), CharacterRange('A', 'F')),
6174
"Space" to spaceSet
62-
)
75+
).mapValues { (_, value) -> MultiCharacterRange(false, value) }
6376
}
6477

6578
var value: String = ""
66-
private var charClass: CharacterRangeRxGene
79+
private var multiCharRange: MultiCharacterRange
6780

6881
init {
6982
if (type[0] !in "wWdDsSvVhHp") {
7083
throw IllegalArgumentException("Invalid type: $type")
7184
}
7285

73-
val charSet = when(type[0]){
74-
'w', 'W' -> wordSet
75-
'd', 'D' -> digitSet
76-
's', 'S' -> spaceSet
77-
'v', 'V' -> verticalSpaceSet
78-
'h', 'H' -> horizontalSpaceSet
86+
multiCharRange = when(type[0]){
87+
'w' -> wordMultiCharRange
88+
'W' -> nonWordMultiCharRange
89+
'd' -> digitMultiCharRange
90+
'D' -> nonDigitMultiCharRange
91+
's' -> spaceMultiCharRange
92+
'S' -> nonSpaceMultiCharRange
93+
'v' -> verticalSpaceMultiCharRange
94+
'V' -> nonVerticalSpaceMultiCharRange
95+
'h' -> horizontalSpaceMultiCharRange
96+
'H' -> nonHorizontalSpaceMultiCharRange
7997
'p' ->
80-
if (type.substring(2, type.length - 1) !in posixSets){
98+
if (type.substring(2, type.length - 1) !in posixMultiCharRanges){
8199
throw IllegalArgumentException("$type invalid/unsupported POSIX character class")
82100
} else {
83-
posixSets[type.substring(2, type.length - 1)]!!
101+
posixMultiCharRanges[type.substring(2, type.length - 1)]!!
84102
}
85103
else -> //this should never happen due to check in init
86104
throw IllegalStateException("Type '\\$type' not supported yet")
87105
}
88-
89-
val negated = type[0].isUpperCase()
90-
charClass = CharacterRangeRxGene(negated, charSet)
91106
}
92107

93108
override fun checkForLocallyValidIgnoringChildren() : Boolean{
@@ -109,8 +124,7 @@ class CharacterClassEscapeRxGene(
109124

110125
val previous = value
111126

112-
charClass.randomize(randomness, tryToForceNewValue)
113-
value = charClass.value.toString()
127+
value = multiCharRange.sample(randomness).toString()
114128

115129
if(tryToForceNewValue && previous == value){
116130
randomize(randomness, tryToForceNewValue)
@@ -134,7 +148,7 @@ class CharacterClassEscapeRxGene(
134148
}
135149

136150
override fun getValueAsPrintableString(previousGenes: List<Gene>, mode: GeneUtils.EscapeMode?, targetFormat: OutputFormat?, extraCheck: Boolean): String {
137-
return value
151+
return value
138152
}
139153

140154

0 commit comments

Comments
 (0)