Local Variable "Drive"

DependencyでもInjectionでもないのでDriveする。

public static void main(String[] args) {
  @Drive String a = "drive [a]"; 
  System.out.println(a);
  @Drive("message") String b = "drive [message]";
  System.out.println(b);
}

@Driveが付いたローカル変数を見つけたら、その初期値をアグレッシブに書き換える。

たとえば、Driver#drive(String) というメソッドに書き換えるとすると、

public static void main(String[] args) {
  @Drive String a = org.ashikunep.irenka.lvdrive.Driver.drive("a"); 
  System.out.println(a);
  @Drive("message") String b = org.ashikunep.irenka.lvdrive.Driver.drive("message");
  System.out.println(b);
}

※写真は開発中のものです。ので、空気読まずにFQNになってます。
ともあれ、Driver#driveをi18nにしたりDIコンテナに接続したりすればいろいろ可能ですよ。

注釈に値を指定しなかった場合は変数名をdrive(String)に渡し、値を指定した場合はその値が渡される。そんなHack*1

public class DriveHack {
  /**
   * @when
   *     driver = {@link Driver#drive(String)}
   *     annotation.spec = {@link Drive}
   *     annotation in var.annotations
   */
  public void drive(
      LiteralFactory literals,
      CtMethod<?> driver,
      CtAnnotationInstance<Drive> annotation,
      CtLocalVariable<String> var) {
    
    CtExpression<?> name;
    if (annotation.getElement("value") == null) {
      name = literals.of(var.getSimpleName());
    }
    else {
      name = annotation.getElement("value").getValue();
    }
    
    var.getInitializer().substitute(driver.newInvocation(name));
  }
}

public class Driver {
  public static String drive(String name) {
    // 変換プログラム
    return "ほげほげ" + name;
  }
}

注釈に必ず値が指定されていると仮定すると、2行で。

  CtExpression<?> name = annotation.getElement("value").getValue();
  var.getInitializer().substitute(driver.newInvocation(name));

アノテーションって便利ですね。

*1:Genericsパラメータドライブをちゃんと実装すれば「annotation.spec = {@link Drive}」はいらない