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

James Daugherty edited comment on GROOVY-11508 at 10/25/24 2:33 AM:
--------------------------------------------------------------------

 

As for the static method behavior, given this code:
{code:java}
import groovy.transform.CompileStatic
import java.util.Map
import java.util.List

trait GormEntity<Integer> {
    abstract static String getEntityName()

    static List<Integer> getAll() {
        [3]
    }
}

trait GormEntity2<Integer> {
    abstract static String getEntityName()

    static List<Integer> getAll() {
        [2]
    }
}

class Parent implements GormEntity, GormEntity2 {
    String name
}

Parent p = new Parent() {code}
Groovy 3 generates this code on the parent class for the getAll() method:
{code:java}
@TraitBridge(
    traitClass = GormEntity2.class,
    desc = "()Ljava/util/List;"
)
public static List<Object> getAll() {
    CallSite[] var0 = $getCallSiteArray();
    return 
(List)ScriptBytecodeAdapter.castToType(var0[2].call(GormEntity2$Trait$Helper.class,
 Parent.class), List.class);
}{code}
Groovy 4 generates this code on the parent class for the getAll() method:
{code:java}
@TraitBridge(
    traitClass = GormEntity2.class,
    desc = "()Ljava/util/List;"
)
public static List<Object> getAll() {
    return 
((Class)GormEntity2$Trait$Helper.class.invoke<invokedynamic>(GormEntity2$Trait$Helper.class,
 
Parent.class)).cast<invokedynamic>(GormEntity2$Trait$Helper.class.invoke<invokedynamic>(GormEntity2$Trait$Helper.class,
 Parent.class));
} {code}
So it seems that v3 & v4 are consistent with copying the last declared trait's 
static method to the class.


was (Author: jdaugherty):
 

As for the static method behavior, given this class:
{code:java}
import groovy.transform.CompileStatic
import java.util.Map
import java.util.List

trait GormEntity<Integer> {
    abstract static String getEntityName()

    static List<Integer> getAll() {
        [3]
    }
}

trait GormEntity2<Integer> {
    abstract static String getEntityName()

    static List<Integer> getAll() {
        [2]
    }
}

class Parent implements GormEntity, GormEntity2 {
    String name
}

Parent p = new Parent() {code}
Groovy 3 generates this code on the parent class for the getAll() method:
{code:java}
@TraitBridge(
    traitClass = GormEntity2.class,
    desc = "()Ljava/util/List;"
)
public static List<Object> getAll() {
    CallSite[] var0 = $getCallSiteArray();
    return 
(List)ScriptBytecodeAdapter.castToType(var0[2].call(GormEntity2$Trait$Helper.class,
 Parent.class), List.class);
}{code}
Groovy 4 generates this code on the parent class for the getAll() method:
{code:java}
@TraitBridge(
    traitClass = GormEntity2.class,
    desc = "()Ljava/util/List;"
)
public static List<Object> getAll() {
    return 
((Class)GormEntity2$Trait$Helper.class.invoke<invokedynamic>(GormEntity2$Trait$Helper.class,
 
Parent.class)).cast<invokedynamic>(GormEntity2$Trait$Helper.class.invoke<invokedynamic>(GormEntity2$Trait$Helper.class,
 Parent.class));
} {code}
So it seems that v3 & v4 are consistent with copying the last declared trait's 
static method to the class.

> Multiple traits with related generic types cannot be used
> ---------------------------------------------------------
>
>                 Key: GROOVY-11508
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11508
>             Project: Groovy
>          Issue Type: Bug
>          Components: Compiler
>    Affects Versions: 4.0.0
>            Reporter: James Daugherty
>            Assignee: Eric Milles
>            Priority: Major
>
> When updating Grails from Groovy 3.x to 4.x we discovered that GROOVY-5106 
> prevents us from updating to Groovy 4 for the 
> [grails-data-mapping|https://github.com/grails/grails-data-mapping] (GORM) 
> project.  Groovy-5106 does not take into account relationships between 
> generic types and groovy does not support inheritance in generic types on 
> traits so we have no workable solution for using Groovy 4.
>  
> For example, the following is not possible in Groovy 4:
> {code:java}
> class Parent extends GormEntity<Parent> {
> }
> class Child extends GormEntity<Child> {
> } 
> class GormEntity<? extends GormEntity> { // ? extends GormEntity is not 
> allowed
> }{code}
>  
> We have documented the impacts of this issue on the grails-data-mapping 
> project here:  [https://github.com/grails/grails-data-mapping/issues/1811]   
> We have discovered that the original change could be reverted and continue to 
> work with the latest Java & Groovy. 
>  
> For Grails Data Mapping (GORM), there is support for inheritance between a 
> Parent & Child domain object.  This is often implemented like this:
> {code:java}
> class Parent extends GormEntity<Parent> {
> }
> class Child extends GormEntity<Child> {
> }
> trait GormEntity<D> { // Simplified for this ticket
>     static D get(Serializable id)
>    
>     static List<D> getAll()
> }
>  {code}
> This allows someone to do the following in code:
> {code:java}
> Parent.get(1L) // Will find either a Child or Parent
> Child.get(1L) // Will find only child types{code}
>  
> Since Groovy-5106 does not take into account inheritance, can this change be 
> reverted or changed to a warning until inheritance is taken into account?



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

Reply via email to