[ 
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 cn.@superClass // Resource<com.example.Derived$Attributes> -> 
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), but using {{.@superClass}} returns the 
generic copy and {{.superClass}} (which is used by the rest of the compilation 
process) the raw copy.

  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}
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.

        Summary: Generic types are cleared on read when a ClassNode is assigned 
as a superClass  (was: Generic types are cleared when a ClassNode is assigned 
as a superClass)

> Generic types are cleared on read 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 cn.@superClass // Resource<com.example.Derived$Attributes> -> 
> 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), but using {{.@superClass}} returns 
> the generic copy and {{.superClass}} (which is used by the rest of the 
> compilation process) the raw copy.



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

Reply via email to