@@ -72,8 +72,8 @@ extension String {
7272
7373 let validString = String ( UnicodeScalarView ( sanitizedScalars) )
7474
75- //Special case for a single underscore.
76- //We can't add it to the map as its a valid swift identifier in other cases.
75+ // Special case for a single underscore.
76+ // We can't add it to the map as its a valid swift identifier in other cases.
7777 if validString == " _ " { return " _underscore_ " }
7878
7979 guard Self . keywords. contains ( validString) else { return validString }
@@ -90,6 +90,7 @@ extension String {
9090 func safeForSwiftCode_idiomatic( options: SwiftNameOptions ) -> String {
9191 let capitalize = options. isCapitalized
9292 if isEmpty { return capitalize ? " _Empty_ " : " _empty_ " }
93+
9394 // Detect cases like HELLO_WORLD, sometimes used for constants.
9495 let isAllUppercase = allSatisfy {
9596 // Must check that no characters are lowercased, as non-letter characters
@@ -112,7 +113,6 @@ extension String {
112113 case accumulatingFirstWord( AccumulatingFirstWordContext )
113114 case accumulatingWord
114115 case waitingForWordStarter
115- case fallback
116116 }
117117 var state : State = . preFirstWord
118118 for index in self [ ... ] . indices {
@@ -137,8 +137,9 @@ extension String {
137137 . init( isAccumulatingInitialUppercase: !capitalize && char. isUppercase)
138138 )
139139 } else {
140- // Illegal character, fall back to the defensive strategy.
141- state = . fallback
140+ // Illegal character, keep and let the defensive strategy deal with it.
141+ state = . preFirstWord
142+ buffer. append ( char)
142143 }
143144 case . accumulatingFirstWord( var context) :
144145 if char. isLetter || char. isNumber {
@@ -202,8 +203,9 @@ extension String {
202203 // In the middle of an identifier, curly braces are dropped.
203204 state = . accumulatingFirstWord( . init( isAccumulatingInitialUppercase: false ) )
204205 } else {
205- // Illegal character, fall back to the defensive strategy.
206- state = . fallback
206+ // Illegal character, keep and let the defensive strategy deal with it.
207+ state = . accumulatingFirstWord( . init( isAccumulatingInitialUppercase: false ) )
208+ buffer. append ( char)
207209 }
208210 case . accumulatingWord:
209211 if char. isLetter || char. isNumber {
@@ -222,8 +224,9 @@ extension String {
222224 // In the middle of an identifier, these are dropped.
223225 state = . accumulatingWord
224226 } else {
225- // Illegal character, fall back to the defensive strategy.
226- state = . fallback
227+ // Illegal character, keep and let the defensive strategy deal with it.
228+ state = . accumulatingWord
229+ buffer. append ( char)
227230 }
228231 case . waitingForWordStarter:
229232 if [ " _ " , " - " , " . " , " / " , " + " , " { " , " } " ] . contains ( char) {
@@ -235,19 +238,15 @@ extension String {
235238 buffer. append ( contentsOf: char. uppercased ( ) )
236239 state = . accumulatingWord
237240 } else {
238- // Illegal character, fall back to the defensive strategy.
239- state = . fallback
241+ // Illegal character, keep and let the defensive strategy deal with it.
242+ state = . waitingForWordStarter
243+ buffer. append ( char)
240244 }
241- case . modifying, . fallback : preconditionFailure ( " Logic error in \( #function) , string: ' \( self ) ' " )
245+ case . modifying: preconditionFailure ( " Logic error in \( #function) , string: ' \( self ) ' " )
242246 }
243247 precondition ( state != . modifying, " Logic error in \( #function) , string: ' \( self ) ' " )
244- if case . fallback = state { return safeForSwiftCode_defensive ( options: options) }
245248 }
246- if buffer. isEmpty || state == . preFirstWord { return safeForSwiftCode_defensive ( options: options) }
247- // Check for keywords
248- let newString = String ( buffer)
249- if Self . keywords. contains ( newString) { return " _ \( newString) " }
250- return newString
249+ return String ( buffer) . safeForSwiftCode_defensive ( options: options)
251250 }
252251
253252 /// A list of word separator characters for the idiomatic naming strategy.
0 commit comments