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

Eric Milles updated GROOVY-8433:
--------------------------------
    Fix Version/s: 3.0.10

> Anonymous inner class results in cast exception with @Category applied
> ----------------------------------------------------------------------
>
>                 Key: GROOVY-8433
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8433
>             Project: Groovy
>          Issue Type: Bug
>            Reporter: Eric Milles
>            Assignee: Eric Milles
>            Priority: Major
>             Fix For: 3.0.10, 4.0.0
>
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> In working with a library that required extension of an SAM type to add a 
> function binding, I thought of using {{@Category}} to soften the integration. 
>  What I found is that the implicit {{this}} parameter that is passed to the 
> constructor of an anon. inner class is being transformed from the containing 
> class to the category class due to the application of the {{@Category}} 
> transform.
> Below I have boiled it down to the fewest moving parts I can.  
> {{LibraryContext}} is the type that needs functions bound to it and the 
> interface for doing so is {{LibraryFunction}} which requires constructor 
> params so I cannot use SAM Closure coercion.  My first take was to create 
> {{Factory.Binder}} to get the details out of the way.  That resulted in the 
> cast exception below.  When I converted {{Binder}} to define static methods 
> with a first param of {{LibraryContext}} all is well.
> So I thought I would raise the issue that anon. inners and {{@Category}} are 
> not currently compatible.
> {code}
> Caught: org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot 
> cast object 'scripts.LibraryContext@6a28ffa4' with class 
> 'scripts.LibraryContext' to class 'scripts.Factory$Binder'
> org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast 
> object 'scripts.LibraryContext@6a28ffa4' with class 'scripts.LibraryContext' 
> to class 'scripts.Factory$Binder'
>       at 
> scripts.Factory$Binder.bindStringFunction(CategoryTransform.groovy:18)
>       at scripts.Factory$_create_closure1.doCall(CategoryTransform.groovy:10)
>       at scripts.Factory$_create_closure1.doCall(CategoryTransform.groovy)
>       at scripts.Factory.create(CategoryTransform.groovy:9)
>       at scripts.Factory$create.call(Unknown Source)
>       at scripts.CategoryTransform.run(CategoryTransform.groovy:42)
> {code}
> {code:java}
> package scripts
> class Factory {
>   private Factory() {}
>   static LibraryContext create() {
>     LibraryContext context = new LibraryContext()
>     use (Binder) {
>       context.bindStringFunction('', { String[] strings -> '' })
>     }
>     return context
>   }
>   @Category(LibraryContext)
>   private static class Binder {
>     void bindStringFunction(String name, 
> java.util.function.Function<String[], String> func) {
>       def stringFunction = new LibarayFunction(name, 0) { // cast exception 
> here due to implicit first param of "this"
>         @Override
>         String compute(String... args) {
>             func.apply(args)
>         }
>       }
>       this.bind(name, stringFunction)
>     }
>   }
> }
> class LibraryContext {
>   void bind(String name, Object value) {
>   }
> }
> abstract class LibarayFunction {
>   LibarayFunction(String name, int argc) {
>   }
>   abstract String compute(String... argv);
> }
> Factory.create()
> {code}



--
This message was sent by Atlassian Jira
(v8.20.1#820001)

Reply via email to