[ 
https://issues.apache.org/jira/browse/GROOVY-8863?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16696259#comment-16696259
 ] 

Paul King commented on GROOVY-8863:
-----------------------------------

I had a quick look at this. I did a quick spike to see if we could hack 
AsmClassGenerator. I added an additional call to cv.visitInnerClass within the 
places which use types: visitField, visitConstructorOrMethod for params, 
visitStdMethod for return type, visitCastExpression, visitClassExpression, 
visitAnnotationDefaultExpression for class constants. Doing it this way is a 
kind of a hack since we don't record such usages in earlier visitor passes. 
This worked in most cases but still broke a bunch of tests. I wasn't setting 
the access modifiers properly (limitation of spike) which explains some of the 
breakages but others broke due to loss of information in the classnode. Inner 
classes aren't identified correctly as InnerClassNodes by ClassSignatureParser. 
My hack used a simplistic approach of looking for $ in the class name. This 
would need to be made quite a bit smarter for the hack approach to work to 
account for inner inner classes, closures in classes, local inner classes etc. 
To me it indicates that we should fix the loss of information during class 
resolution.

> Groovy compiler doesn't generate InnerClasses attribute for nested class 
> names mentioned in the class file
> ----------------------------------------------------------------------------------------------------------
>
>                 Key: GROOVY-8863
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8863
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 2.5.3
>            Reporter: Alexander Udalov
>            Priority: Major
>
> It seems that the Groovy compiler does not generate correct InnerClasses 
> attributes when Groovy code uses inner classes, even if those are Java 
> classes compiled separately.
> For example, the following code:
> {{class Test {}}
> {{    void f(Thread.State t) {}}}
> {{}}}
> (where java.lang.Thread.State is just an example nested class from JDK) will 
> compile by Groovy to a class file Test.class which has no InnerClasses 
> attribute. If compiled by Java though, it has the following:
> {{InnerClasses:}}
> {{    public static final #10= #9 of #18; //State=class 
> java/lang/Thread$State of class java/lang/Thread}}
> While I couldn't find a statement requiring this attribute to be present for 
> all nested classes mentioned in the class file in the JVMS, I believe 
> [§4.7.6|https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.7.6]
>  sort of hints at that with the following:
> {quote}If the constant pool of a class or interface C contains at least one 
> {{CONSTANT_Class_info}} entry 
> ([§4.4.1|https://docs.oracle.com/javase/specs/jvms/se11/html/jvms-4.html#jvms-4.4.1])
>  which represents a class or interface that is not a member of a package, 
> then there must be exactly one {{InnerClasses}} attribute in the 
> {{attributes}} table of the {{ClassFile}} structure for C.
> {quote}
> In this case, there's certainly a CONSTANT_Class_info entry in the 
> Groovy-generated class file which represents a non-top-level class, but the 
> InnerClasses attribute is missing, so I'd say this violates the spec.
> We've met this issue when refactoring the internal implementation of class 
> file reader in the Kotlin compiler, where we [got 
> rid|https://github.com/JetBrains/kotlin/commit/9df02b236620e413ef70cea0d1d8ed93cd0b474e]
>  of the heuristic that calculated the full class name by replacing dollar 
> characters with dots, and started to rely only on the InnerClasses attribute 
> to correctly map JVM names to the "real" names of classes. This looked 
> correct because at least class files generated by javac always have 
> InnerClasses for all nested classes mentioned in the class file (not only in 
> signatures, even those used only in method bodies!). However, for Groovy this 
> [turned out|https://youtrack.jetbrains.com/issue/KT-27874] not to be the 
> case. We'll probably workaround this problem somehow, for example by 
> attempting to determine the class name twice, first by InnerClasses attribute 
> values and second, by the aforementioned heuristic, but it'll be nice to get 
> rid of the latter code in the future once this issue is fixed.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

Reply via email to