phax / jcodemodel

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

Retrieve inner class reference #60

Closed fbaro closed 5 years ago

fbaro commented 6 years ago

I was looking for a way to get a reference to an inner class from another class, but I was not able to find it. I was looking for something like codeModel.ref("x.y.z.AClass").getInner("Inner"), which would give a reference to x.y.z.AClass$Inner. Would it be possible to add it? Or it's already there and I did not find it?

phax commented 6 years ago

With codeModel.ref("x.y.z.AClass").classes() you could iterate the inner classes, but not very sexy. An improved API would be better I guess....

fbaro commented 6 years ago

Yep I knew the classes() method, and I'm actually using it. Unfortunately it's available only on AbstractJClassContainer, while codeModel.ref() returns and AbstractJClass. I'm doing a cast, but depending on what codeModel.ref() actually returns, it might not work.

phax commented 6 years ago

So I added a getInner(String) method to AbstractJClass and initial tests worked fine. Can you test the SNAPSHOT version or do you need the release?

fbaro commented 6 years ago

I'll check the snapshot, thank you very much!

fbaro commented 6 years ago

I checked it out: it works for my specific use case, but it breaks on something more general like this:

AbstractJClass c1 = codeModel.ref(java.util.Map.Entry.class);
AbstractJClass c2 = codeModel.ref(java.util.Map.class).getInnerClass("Entry");
assertEquals(c1.fullName(), c2.fullName());
assertEquals(c1, c2); // Maybe this too?

By the way I already have a workaround in place, so no hurry on my side.

phax commented 6 years ago

This is an issue because inner classes are not automatically referenced when you reference codeModel.ref(java.util.Map.class). Additionally not even super or outer classes are automatically added into the reference space of code model. So codeModel.ref(java.util.Map.class).getInnerClass("Entry") works as expected by delivering null!

fbaro commented 6 years ago

I'm a bit unconvinced on this... after all, we are basically just trying to construct a sort of type-safe placeholder for the "java.util.Map.Entry" string, which will then be printed in the generated file. It appears to me that there should not be any substantial difference between the two ways of constructing such a string, or even with codeModel.ref("java.util.Map.Entry"). I thought the result should be the same, even in the case that the referenced classes are not visible in the classloader.

phax commented 5 years ago

Inner classes are a construct of the Java source files, but when compiled, they reside as 2 independent files on disk and only a "similiar" name links them together. They are - when compiled - indeed 2 separate independent classes.