cmoine / generic-enums

Attempt to implement https://openjdk.java.net/jeps/301 with annotation + processor
MIT License
7 stars 1 forks source link

Support generics inside variables #8

Open kobi26c opened 2 years ago

kobi26c commented 2 years ago

Hi! Very cool feature I must say!

I'm trying to achieve something but I can seem to make it work. This is my example:

@GenericEnum
public enum Test implements ActionFactory<@GenericEnumParam Object> {

    FEATURE_FLAGS(AActionClass.class, a -> new AActionClass()),
    NOT_FEATURE_FLAGS(BActionClass.class, b -> new BActionClass());

    Test(Class<? extends ActionClass> actionClass, ActionFactory<@GenericEnumParam Object> constructor) {
        this.constructor = constructor;
    }

    private final ActionFactory<@GenericEnumParam Object> constructor;

    @Override
    public @GenericEnumParam Object getAction(String s) {
        return constructor.getAction(s);
    }
}

This is the ActionFactory class:

interface ActionFactory<T> {
    T getAction(String input);
}

public class ActionClass {

    public void method() {
        System.out.println("method");
    }
}

public class AActionClass extends ActionClass {

    public void a() {
        System.out.println("A");
    }
}

public class BActionClass extends ActionClass {
    public void b() {
        System.out.println("A");
    }
}

After compile it creates TextExt with some errors:

    public static final TestExt<AActionClass> FEATURE_FLAGS=new TestExt<AActionClass>(AActionClass.class, (a)->new AActionClass(), "FEATURE_FLAGS", 0);
    public static final TestExt<BActionClass> NOT_FEATURE_FLAGS=new TestExt<BActionClass>(BActionClass.class, (b)->new BActionClass(), "NOT_FEATURE_FLAGS", 1);
    private final String __enum_name__;
    private final int __ordinal__;
    private final ActionFactory<@GenericEnumParam() Object> constructor;

    private TestExt(Class<? extends ActionClass> actionClass, ActionFactory<@GenericEnumParam() Object> constructor, String __enum_name__, int __ordinal__) {
        this.constructor = constructor;
        this.__enum_name__=__enum_name__;
        this.__ordinal__=__ordinal__;
    }

    public T getAction(String s)  {
        return constructor.getAction(s);
    }

The constructor variable is ActionFactory<@GenericEnumParam() Object> instead of ActionFactory<T>

Am I missing anything ? is this something I can achieve with current implementation or it's a new feature need to develop ?

Thanks!!

cloudpay-simon commented 2 years ago

Hi kobi26c,

I'm not 100% sure what you're trying to achieve. But after replacing Object with ActionClass and removing @GenericEnumParam, the class compiles.

@GenericEnum
public enum Test implements ActionFactory<ActionClass> {

  FEATURE_FLAGS(AActionClass.class, a -> new AActionClass()),
  NOT_FEATURE_FLAGS(BActionClass.class, b -> new BActionClass());

  private final ActionFactory<ActionClass> constructor;

  Test(Class<? extends ActionClass> actionClass, ActionFactory<ActionClass> constructor) {
    this.constructor = constructor;
  }

  @Override
  public ActionClass getAction(String s) {
    return constructor.getAction(s);
  }
}

which allows you to do ActionClass a = Test.FEATURE_FLAGS.getAction("a");

Hope this helps, Simon

kobi26c commented 2 years ago

Thanks for replying!

I don't want to work with ActionClass as an interface I want to be able to get the explicit action implementation (T) from the getAction method

cloudpay-simon commented 2 years ago

Hi kobi26c,

Ok this is the closest I can get. Not as concise.

@GenericEnum
public enum Test {

  FEATURE_FLAGS(AActionClass.class) {
    @Override
    public AActionClass getAction(String s){
      return new AActionClass();
    }
  },

  NOT_FEATURE_FLAGS(BActionClass.class) {
    @Override
    public BActionClass getAction(String s){
      return new BActionClass();
    }
  };

  Test(Class<? extends ActionClass> actionClass) {
  }

  public abstract @GenericEnumParam("T") Object getAction(String s);
}

Allows you to do: AActionClass a = TestExt.FEATURE_FLAGS.getAction("a");

This is a modified version of the org.cmoine.genericEnums.AbstractEnum sample.

Simon

kobi26c commented 2 years ago

I saw that implementation and wanted to avoid it When having over 100 enum types its not so fun :) But thanks a lot for the help