Kotlin Structural Search: Why can't it match statements?
I'm trying to use structural replace to automate some repetitive refactors, but it doesn't quite do what I want.
As a toy example, Suppose I write the search template:
val $ident$ = 42
In the source code, I have the line
val myVal = 42
And sure enough, it matches the template. I save this template as "Assign42" However, if I now rewrite the template as
$declStatement$
and as the filter add a reference to Assign42. I now expect the above statement in my code to still be matched, but it isn't. I have found a similar issue when trying to refactor classes. Whereas in Java templates,
class $Class$ {
$stmt$
}
is no Problem, the same template is not Accepted for Kotlin, and IDEA tells me that a declaration is expected. However, intuitively I expect ANY statement to be matched against $stmt$, as in, $stmt$ might well be a var or function declaration.
I assume there is some technical difference between Java and Kotlin that causes this discrepancy. What is it? Is there some way to match arbitrary statements with a template?
请先登录再写评论。
official site
The matches() method requires a full string match, and your regexps only match an empty location followed with any 0+ chars other than line break chars followed with either an upper- or lowercase letters or a digit. You need to match and consume the whole string.
One fix is to modify just the regexps and use the rest of code as is:
val noUpper = "(?s)[^A-Z]*[A-Z].*".toRegex()
val noLower = "(?s)[^a-z]*[a-z].*".toRegex()
val noDigit = "(?s)\\D*\\d.*".toRegex()
Or, use find() (that allows partial matches inside longer strings) with a bit simpler regexes:
val noUpper = "[A-Z]".toRegex()
val noLower = "[a-z]".toRegex()
val noDigit = "\\d".toRegex()
and then
when {
noUpper.find(password) == null -> {
throw WebApplicationException("Password missing uppercase letter")
}
noLower.find(password) == null -> {
throw WebApplicationException("Password missing digit")
}
noDigit.find(password) == null -> {
throw WebApplicationException("Password missing lowercase letter")
}
else -> return true
}