[ 
https://issues.apache.org/jira/browse/GROOVY-10763?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Christopher Smith updated GROOVY-10763:
---------------------------------------
    Description: 
I have an annotation that, if an annotated class has no {{extends}}, should 
make it extend {{Resource<A>}}, where {{A}} is determined by Logic. I attempted 
to create the {{ClassNode}} representing the intended base class and assign it 
as the derived class's {{superClass}}:
{code:groovy}
println resource.superClass  // java.lang.Object

def sc = makeClassSafeWithGenerics(TYPE_RESOURCE, attr)
println sc  // Resource<com.example.Derived$Attributes> -> Resource<A>
println sc.genericsTypes  // [com.example.Derived$Attributes]
cn.superClass = sc

def sc2 = cn.superClass
println sc2        // Resource<A>
println sc2 == sc  // true, but compares only the erasure
println sc2 === sc // false
{code}

The compiler then proceeds to write out a {{.class}} file extending the raw 
{{Resource}} type. The compiler writes the correct {{Resource<Attributes>}} if 
it is typed out inline in the input file.

I've confirmed that the {{ClassNode TYPE_RESOURCE}} is not a redirect or a 
genericsPlaceholder, so the {{superClass}} assignment appears to be a direct 
field assignment (once {{redirect()}} returns {{this}}), and 
{{getUnresolvedSuperClass}} appears to read the field directly 
({{lazyInitDone}} is already true). I cannot figure out how the reference for 
{{sc}} (generic) is getting replaced with a raw copy, but it happens 
immediately (not later in the compilation process) and is carried through to 
the bytecode.

  was:
I have an annotation that, if an annotated class has no {{extends}}, should 
make it extend {{Resource<A>}}, where {{A}} is determined by Logic. I attempted 
to create the {{ClassNode}} representing the intended base class and assign it 
as the derived class's {{superClass}}:
{code:groovy}
def sc = makeClassSafeWithGenerics(TYPE_RESOURCE, attr)
println sc  // Resource<com.example.Derived$Attributes> -> Resource<A>
println sc.genericsTypes  // [com.example.Derived$Attributes]
cn.superClass = sc

def sc2 = cn.superClass
println sc2        // Resource<A>
println sc2 == sc  // true, but compares only the erasure
println sc2 === sc // false
{code}

The compiler then proceeds to write out a {{.class}} file extending the raw 
{{Resource}} type. The compiler writes the correct {{Resource<Attributes>}} if 
it is typed out inline in the input file.

I've confirmed that the {{ClassNode TYPE_RESOURCE}} is not a redirect or a 
genericsPlaceholder, so the {{superClass}} assignment appears to be a direct 
field assignment (once {{redirect()}} returns {{this}}), and 
{{getUnresolvedSuperClass}} appears to read the field directly 
({{lazyInitDone}} is already true). I cannot figure out how the reference for 
{{sc}} (generic) is getting replaced with a raw copy, but it happens 
immediately (not later in the compilation process) and is carried through to 
the bytecode.


> Generic types are cleared when a ClassNode is assigned as a superClass
> ----------------------------------------------------------------------
>
>                 Key: GROOVY-10763
>                 URL: https://issues.apache.org/jira/browse/GROOVY-10763
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 4.0.5
>            Reporter: Christopher Smith
>            Priority: Major
>
> I have an annotation that, if an annotated class has no {{extends}}, should 
> make it extend {{Resource<A>}}, where {{A}} is determined by Logic. I 
> attempted to create the {{ClassNode}} representing the intended base class 
> and assign it as the derived class's {{superClass}}:
> {code:groovy}
> println resource.superClass  // java.lang.Object
> def sc = makeClassSafeWithGenerics(TYPE_RESOURCE, attr)
> println sc  // Resource<com.example.Derived$Attributes> -> Resource<A>
> println sc.genericsTypes  // [com.example.Derived$Attributes]
> cn.superClass = sc
> def sc2 = cn.superClass
> println sc2        // Resource<A>
> println sc2 == sc  // true, but compares only the erasure
> println sc2 === sc // false
> {code}
> The compiler then proceeds to write out a {{.class}} file extending the raw 
> {{Resource}} type. The compiler writes the correct {{Resource<Attributes>}} 
> if it is typed out inline in the input file.
> I've confirmed that the {{ClassNode TYPE_RESOURCE}} is not a redirect or a 
> genericsPlaceholder, so the {{superClass}} assignment appears to be a direct 
> field assignment (once {{redirect()}} returns {{this}}), and 
> {{getUnresolvedSuperClass}} appears to read the field directly 
> ({{lazyInitDone}} is already true). I cannot figure out how the reference for 
> {{sc}} (generic) is getting replaced with a raw copy, but it happens 
> immediately (not later in the compilation process) and is carried through to 
> the bytecode.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to