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


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$ {

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