Skip to content

Commit

Permalink
fix: edge cases for JavaTypeName and JavaMemberName
Browse files Browse the repository at this point in the history
  • Loading branch information
jGleitz committed Feb 6, 2020
1 parent 52cdedb commit 3e784e4
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
42 changes: 30 additions & 12 deletions src/main/kotlin/JavaNotations.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,13 @@ import javax.lang.model.SourceVersion
* using [SourceVersion.isKeyword].
*/
object JavaTypeName: StringNotation by UpperCamelCase {
override fun print(word: Word) = UpperCamelCase.print(word).makeValidJavaIdentifier()
override fun print(word: Word) = UpperCamelCase.print(
Word(word.parts.mapIndexed { index, wordPart ->
if (index == 0) wordPart.keepOnlyJavaIdentifierChars()
else wordPart.keepOnlyJavaIdentifierContinuationChars()
})
)
.neutralizeJavaReservedKeywords()

override fun toString() = this::class.java.simpleName!!
}
Expand All @@ -28,11 +34,14 @@ object JavaMemberName: BaseStringNotation(camelCaseSplitRegex) {
override fun transformPartAfterParse(index: Int, part: String) = part.toLowerCase(Locale.ROOT)

override fun print(word: Word) = word.parts
.foldIndexed(StringBuffer()) { index, left, right ->
val rightPart =
if (left.contains(Regex("[a-zA-Z]"))) right.toFirstUpperOtherLowerCase()
else right.toLowerCase()
left.append(printBeforePart(index, rightPart)).append(rightPart)
.foldIndexed(StringBuffer()) { index, existing, part ->
val filteredPart =
if (index == 0) part.keepOnlyJavaIdentifierChars()
else part.keepOnlyJavaIdentifierContinuationChars()
val nextPart =
if (existing.contains(Regex("[a-zA-Z]"))) filteredPart.toFirstUpperOtherLowerCase()
else filteredPart.toLowerCase()
existing.append(printBeforePart(index, nextPart)).append(nextPart)
}.toString().makeValidJavaIdentifier()
}

Expand Down Expand Up @@ -79,15 +88,24 @@ object JavaConstantName: StringNotation by ScreamingSnakeCase {
override fun toString() = this::class.java.simpleName!!
}

private fun String.makeValidJavaIdentifier() = this.keepOnlyJavaIdentifierChars().neutralizeJavaReservedKeywords().ifEmpty { "__" }
private fun String.makeValidJavaIdentifier() = this.keepOnlyJavaIdentifierChars().neutralizeJavaReservedKeywords()

private fun String.keepOnlyJavaIdentifierChars() = this.chars()
.skipWhile { !Character.isJavaIdentifierStart(it) }
.filter { Character.isJavaIdentifierPart(it) }
.collect({ StringBuilder() }, { left, right -> left.appendCodePoint(right) }, { left, right -> left.append(right) })
.toString()

private fun String.neutralizeJavaReservedKeywords() = if (SourceVersion.isKeyword(this)) this + "_" else this
.keepOnlyJavaIdentifierContinuationChars()
.collectToString()

private fun String.keepOnlyJavaIdentifierContinuationChars() = this.chars().keepOnlyJavaIdentifierContinuationChars().collectToString()
private fun IntStream.keepOnlyJavaIdentifierContinuationChars() = this.filter { Character.isJavaIdentifierPart(it) }
private fun IntStream.collectToString() =
this.collect({ StringBuilder() }, { left, right -> left.appendCodePoint(right) }, { left, right -> left.append(right) })
.toString()

private fun String.neutralizeJavaReservedKeywords() = when {
this == "" -> "__"
SourceVersion.isKeyword(this) -> this + "_"
else -> this
}

private inline fun IntStream.skipWhile(crossinline condition: (Int) -> Boolean): IntStream {
var found = false
Expand Down
4 changes: 3 additions & 1 deletion src/test/kotlin/JavaNotationsTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class JavaTypeNameTest: BaseNotationTest(
printOnlyWords = listOf(
Word("I’m using", "Bad", "chaRacters!") to "ImusingBadCharacters",
Word("1", "type", "name", "4", "you") to "TypeName4You",
Word("handles", "§eight", "correctly") to "HandlesEightCorrectly",
Word("removes", "upperCase") to "RemovesUppercase",
Word("") to "__",
Word("1") to "__",
Expand All @@ -21,6 +22,7 @@ class JavaMemberNameTest: BaseNotationTest(
printOnlyWords = listOf(
Word("I’m using", "Bad", "chaRacters!") to "imusingBadCharacters",
Word("1", "Member", "name", "4", "you") to "memberName4You",
Word("handles", "§eight", "correctly") to "handlesEightCorrectly",
Word("_", "underscore", "start") to "_underscoreStart",
Word("$", "dollar", "start") to "\$dollarStart",
Word("a", "letter", "start") to "aLetterStart",
Expand Down Expand Up @@ -80,7 +82,7 @@ class JavaConstantNameTest: BaseNotationTest(
Word("") to "__",
Word("1") to "__",
Word("8if") to "IF",
Word("enum") to "enum_",
Word("enum") to "ENUM",
Word("_") to "__" ifJvmVersionIsAtLeast 9
)
)

0 comments on commit 3e784e4

Please sign in to comment.