@@ -11,6 +11,7 @@ import org.evomaster.core.search.service.mutator.MutationWeightControl
1111import org.evomaster.core.search.service.mutator.genemutation.AdditionalGeneMutationInfo
1212import org.evomaster.core.search.service.mutator.genemutation.SubsetGeneMutationSelectionStrategy
1313import org.evomaster.core.utils.CharacterRange
14+ import org.evomaster.core.utils.MultiCharacterRange
1415import org.slf4j.LoggerFactory
1516import 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 */
2627class 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