This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 228737 - Closures not treated like the reusable code blocks they are by the Navigator
Summary: Closures not treated like the reusable code blocks they are by the Navigator
Status: NEW
Alias: None
Product: groovy
Classification: Unclassified
Component: Editor (show other bugs)
Version: 7.3.1
Hardware: All All
: P3 normal (vote)
Assignee: Martin Janicek
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-04-19 01:04 UTC by _ wadechandler
Modified: 2013-04-25 11:59 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description _ wadechandler 2013-04-19 01:04:20 UTC
Need some way to reference closures in the Navigator. We can get to classes, inner classes, methods, and class scoped variables and closures, and even inlined anonymous classes, but can not get to various closures from the Navigator. As an example, create some Groovy class:

public class MyGroovyClass {
    //define some high level closure you can reference
    //plus add one to it
    def someOtherClosure = {
        def yetAnotherClosure = {
            println "hello yetAnotherClosure"
        }
        yetAnotherClosure()
    }

    public void someMethod(){
        someOtherClosure()
        def someClosure = {
                
        }
        Runnable r = new Runnable(){
            public void run(){
                    
            }
        }
    }

}

Notice what shows up in the editor. This just feels odd that closures are not treated the same as methods, inner, or anonymous classes. I often find myself wanting to locate various defined closures the same way in the Navigator, and it would be efficient to me as the same can be said for those methods, classes, and variables as it relates to the Navigator.

Too, if you notice the way Runnable r is treated along with its methods, it seems this would be nice for all closures. So, take someOtherClosure as an example. It has a sub-closure called yetAnotherClosure. I would expect that tree to be reflected in some way in the Navigator. I think the way anonymous classes which have anonymous classes themselves show up is a little strange...for instance you type this:
            Runnable r = new Runnable(){
                Runnable proxy = new Runnable(){
                    public void run(){
                        
                    }
                }
                public void run(){
                    
                }
            }

in place of Runnable r...then you will see what I mean. It seems that would show up as a node in the nav tree under its correct scope perhaps, and that correct scoping is how I see closures in the Navigator working in my mind. I can discuss further if that isn't as clear as it should be.
Comment 1 Martin Janicek 2013-04-22 11:37:37 UTC
Thanks Wade, I feel these problems are valid but I'm not following you brain-storming and thus not really sure what to do :)

For this example:

class NewGroovyClass {
    //define some high level closure you can reference
    //plus add one to it
    def someOtherClosure = {
        def yetAnotherClosure = {
            println "hello yetAnotherClosure"
        }
        yetAnotherClosure()
    }

    public void someMethod(){
        someOtherClosure()
        def someClosure = {

        }
        Runnable r = new Runnable(){
            Runnable proxy = new Runnable(){
                public void run(){

                }
            }
            public void run(){

            }
        }
    }
}


I can see following navigator structure (using latest dev builds, I have made few changes in Navigator structure last week, so maybe you can't see return type or something):

NewGroovyClass
    someMethod() : void
    someOtherClosure : Object
NewGroovyClass$1
    run() : void
    proxy : Runnable
NewGroovyClass$2
    run() : void

..what exactly would you like to see instead of current structure?
Comment 2 _ wadechandler 2013-04-25 00:00:29 UTC
Martin, yeah, little brain storming out loud...or in BZ as it were... :-)

So to reiterate...

NewGroovyClass
    someMethod() : void
    someOtherClosure : Object
NewGroovyClass$1
    run() : void
    proxy : Runnable
NewGroovyClass$2
    run() : void

Notice what is there and what is missing. proxy and the other Runnable show up in the navigator, but the other closures other than the class variable or module level closure, do not. To me, those are more complex types and is why inner classes, even those defined inline within a method, are able to be found in the Java navigator. They are more than just a simple variable definition and could be fairly big. So, I would expect all the defined closures to work a lot like the inner classes.

I feel like inner classes should look a little different too. To me it seems like they would be shifted over and under the tree where they are defined much like methods, yet have a deeper or richer tree structure. Maybe:

NewGroovyClass
    someOtherClosure : Object
        yetAnotherClosure: Object
    someMethod() : void
        someClosure: Object
        r: Runnable (NewGroovyClass$1)
            proxy : Runnable (NewGroovyClass$2)
                run() : void
            run() : void

Notice how I am giving the class name off to the side and the variable name for the anonymous inner classes. For non-anonymous inner classes, then the class name itself would take the place of the variable name, but depending on where it is defined, in a method, in the parent class, in another inner class, or where ever, would determine its place in the tree just as things are defined in my example.
Comment 3 Martin Janicek 2013-04-25 08:42:48 UTC
(In reply to comment #2)
> Notice what is there and what is missing. proxy and the other Runnable show up
> in the navigator, but the other closures other than the class variable or
> module level closure, do not. To me, those are more complex types and is why
> inner classes, even those defined inline within a method, are able to be found
> in the Java navigator. They are more than just a simple variable definition and
> could be fairly big. So, I would expect all the defined closures to work a lot
> like the inner classes.
> 
> I feel like inner classes should look a little different too. To me it seems
> like they would be shifted over and under the tree where they are defined much
> like methods, yet have a deeper or richer tree structure. Maybe:
> 
> NewGroovyClass
>     someOtherClosure : Object
>         yetAnotherClosure: Object
>     someMethod() : void
>         someClosure: Object
>         r: Runnable (NewGroovyClass$1)
>             proxy : Runnable (NewGroovyClass$2)
>                 run() : void
>             run() : void

This sounds good. Only one thing I don't like much is the existence of the r: Runnable and proxy : Runnable ...they are basically simple variable declarations inside the someMethod() method and for example Java editor doesn't show such classes at all (maybe it has also/only a technical reason, because I can imagine it might be hard to decide if the local variable is just simple "Runnable x" or if it's inner class declared inside that method). I would like to try to improve the navigator so it will behave as much similar as possible with respect to the Java ones. Plus of course we need to include closures etc.

But if I will follow the same principle for closure then "someClosure: Object" would not be shown because it's defined inside someMethod() method. And "yetAnotherClosure: Object" would not be shown because it's defined inside "someOtherClosure : Object" closure. And I would end up only with:

NewGroovyClass
    someOtherClosure : Object
    someMethod() : void
        someClosure: Object

..which I understand is hardly enough for some examples :)

So I would say, I can start with showing the top level closures (like "someOtherClosure : Object" closure) inside the navigator and also I can take a look what needs to be done and if it's technically possible to include arbitrary number of the nested closures/inner classes to the correct position.

> Notice how I am giving the class name off to the side and the variable name for
> the anonymous inner classes. For non-anonymous inner classes, then the class
> name itself would take the place of the variable name, but depending on where
> it is defined, in a method, in the parent class, in another inner class, or
> where ever, would determine its place in the tree just as things are defined in
> my example.
Comment 4 Martin Janicek 2013-04-25 11:59:31 UTC
Nah what I was talking about, we already have top level closures in Navigator :)