2

I am trying to migrate an annotation from a field to it's getter using Intellij's fancy structural replace:

From:

class MyClass {
   @SomeAnnotation
   private final double a;
   @SomeAnnotation
   private final double b;

   public double getA() {
       return a;
   }

   public double getB() {
      return b;
   }
}

To:

class MyClass {
   private final double a;
   private final double b;

   @SomeAnnotation
   public double getA() {
       return a;
   }

   @SomeAnnotation
   public double getB() {
      return b;
   }
}

I am most of the way there with:

Search template:

class $Class$ {
    @SomeAnnotation
    private final $type$ $fieldName$;

    public $type$ $getter$() {
        return $value$;
    }
}

Replace template:

class $Class$ {
    private final $type$ $fieldName$;

    @SomeAnnotation
    public $type$ $getter$() {
        return $value$;
    }
}

There is also a filter on getter that matches get.*, and a Script on the whole template to try to make sure we find the matching getter:

if (getter.name.toLowerCase().contains(fieldName.get(0).name.toLowerCase())) {
    return true;
}
return false;

The problem is that this only matches the first getter, and the script doesn't get a chance to try with all of them.

Any way I could alter my search for this to work?

1 Answers1

2

I am not an expert on IntelliJ Structural Search, but I suspect this is too much for it (though you could always just run it over and over again until it stops changing things).

I think this is a job for a tool like OpenRewrite or similar, which allows you to read the AST and generate new code.

Marquis Wang
  • 10,878
  • 5
  • 30
  • 25
  • 1
    Running it over and over won't work, as it only ever matches the first getter (so if I remove the script, all annotations end up on the first getter). OpenRewrite looks cool though! – Alexandre de Champeaux Oct 12 '21 at 22:00