phax / jcodemodel

A heavily extended fork of the com.sun.codemodel (from 2013/09)
Other
93 stars 34 forks source link

Add API to reference enum constants of a JDirectClass #28

Closed WonderCsabo closed 8 years ago

WonderCsabo commented 8 years ago

Sometimes in code generation, we have to reference an enum constant of a class which is not generated, just referenced. Currently there is no way to do this, only for defined (generated classes). Currently we have to use an ugly workaround:

AbstractJClass referencedClass = ...
IJExpression expression = JExpr.direct(referencedClass.fullName() + "." + "ONE_CONSTANT");
phax commented 8 years ago

Would referencedClass.staticRef ("ONE_CONSTANT") work for you??

WonderCsabo commented 8 years ago

Nope. I must use a JEnumConstant, because i want to pass it to JAnnotationUse#param(String, JEnumConstant).

Actually, i think we may have to introduce JEnumConstantRef (or something like that) for this, since JEnumConstant is mutable and represents a constant in a defined (generated) class, not just a simple reference of an direct (unknown) enum.

phax commented 8 years ago

I think I didn't fully grasp the problem so I can't offer you a good solution. Can you please paste a code snippet that you want to generate and highlight the enum constant in there. If you have a current code snippet to generate it would also make my life easier :) thanks

WonderCsabo commented 8 years ago

In AndroidAnnotations, we extend classes by generated classes, and override methods in them. For maintaining compatibility with other libraries, we copy all annotations to the generated class and the overriden methods. For example:

@Log(LogLevel.WARN) // LogLevel is an enum
void someMethod() {
  //
}
// overriden method:
@Log(LogLevel.WARN)
void someMethod() {
  super.someMethod();
  //
}

To achieve this, we add the annotation parameter here. As you can see, i have to call the deprecated JAnnotationUse#param(String, IJExpression) method. Instead of that, it would be nice to pass the enum constant to JAnnotationUse#param(String, JEnumConstant). But i cannot pass the JEnumConstant, because there is no way to create it from an unknown, user class. It is only available for defined classes.

phax commented 8 years ago

Ok, I think I got it. First I "un-deprecated" the JAnnotationUse#param(String, IJExpression) method - if you use, fine for me. As there is an overload JAnnotationUse#param(String, JEnumConstant) I see two possibilities:

  1. call param (String, new JEnumConstant (type, name)) or
  2. call param (String, type.staticRef (name))

Does that do the trick?

WonderCsabo commented 8 years ago
  1. The constructor of JEnumConstant is protected, so i cannot call it (and let's forget Reflection), but it is the right way in codemodel! These kind of things should be created by factory methods.
  2. This will do the trick of course. However i still think the most clear way would be introducing an enumConstantRef method, which would return a JEnumConstant or JEnumConstantRef instance. I know that from perspective of the final generated source, the enum constant ref is just the same as a static field ref, but it would be still nicer in the API, more expressive.
phax commented 8 years ago

JExpr.enumConstant (JDefinedClass, String) is now in the trunk. It is based on class EnumConstantRef which is a very limited version of EnumConstant. Will be part of 2.7.11

WonderCsabo commented 8 years ago

Thanks! But unfortunately this will not help me. As i tried to emphasize, i am working with unknown classes, so not JDefinedClasses, but only AbstractJClasses. So this new method and the class should work with an AbstractJClass.

If i would work with defined classes, i would just use JEnumConstants created by me (since i am who defined the class, its enum constants can be only added by me) as it is also an IJExpression hence can generate use of itself.

phax commented 8 years ago

Sorry. Now with AbstractJClass :) This project is not my major business and it always takes me some time to get back into the thinking of the original authors :)

WonderCsabo commented 8 years ago

No problem. Yeah, i know you are not the original author. Actually i just migrate AndroidAnnotations from com.sun.codemodel to use your fork. The original project seems to be dead, but yours is very much alive, thanks! So that is why i am opening the issues in a row. :)

phax commented 8 years ago

No problem. I know its dead that's I forked it to get some more accessor methods myself.

WonderCsabo commented 8 years ago

When we can expect the next release? On Sep 14, 2015 15:37, "Philip Helger" notifications@github.com wrote:

No problem. I know its dead that's I forked it to get some more accessor methods myself.

— Reply to this email directly or view it on GitHub https://github.com/phax/jcodemodel/issues/28#issuecomment-140077890.

phax commented 8 years ago

When we found a solution for issue #30 I can build one - no problem

sviperll commented 8 years ago

@WonderCsabo By the way, I've been extensively using jcodemodel in annotation processor, namely adt4j. What I ended up doing is mercilessly convert all class references to JDefinedClasses, see JCodeModelJavaxLangModelAdapter#getClass method.

WonderCsabo commented 8 years ago

@sviperll thanks, very nice solution!

phax commented 8 years ago

@sviperll Do you think it would be valuable to include the content of your com.github.sviperll.meta.java.model package (+ 2 referenced classes) directly in jcodemodel? I Think it would make sense. I would give your access rights to the repo so that you can manage it here. What do you think?

WonderCsabo commented 8 years ago

@phax what about creating a gitter room for such conversations, so we are not off topic in the issues. :)

phax commented 8 years ago

How to do this? I have no clue :)

WonderCsabo commented 8 years ago

https://gitter.im/excilys/androidannotations#createroom

sviperll commented 8 years ago

@phax I've actually planned to include this into jcodemodel from the beginning. I've made it into standalone package to primarily speed up iteration to find better design. I'll try to move it into jcodemodel during upcomming week.

phax commented 8 years ago

@sviperll I added the first version: https://github.com/phax/jcodemodel/commit/80e54668ed0247b07d317fc1056f75843912a448

WonderCsabo commented 8 years ago

What about the Gitter room? :smile:

Maybe we should create a new artifact for this, for example jcodemodel-processing. So keep everything directly related to generation in the main artifact, and move helpers which are only using jcodemodel for easing annotation processing, to another artifact.

phax commented 8 years ago

https://gitter.im/phax/jcodemodel

sviperll commented 8 years ago

I've added methods to JCodeModel class to access new functionality 88fa7eb305734639f58060be5eeabb6ff66fd89a

phax commented 8 years ago

Thanks. Looks good. Is there anything else missing, or may I create a release on this?

sviperll commented 8 years ago

@phax Everything seems present. You can proceed with the release.

phax commented 8 years ago

Small problem: the changes require me to go for Java 1.6 - is there any problem from your side?