Author Topic: push-tag in Java only finds public members in other files  (Read 9784 times)

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
push-tag in Java only finds public members in other files
« on: July 14, 2006, 12:52:03 PM »
Suppose I have the following two Java files:

Foo.java
Code: [Select]
public class Foo
{
    public Foo()
    {
    }

    public Foo(String abc)
    {
    }

    protected Foo(int def)
    {
    }
}

Bar.java
Code: [Select]
public class Bar
{
    public static void main(String[] args)
    {
        Foo foo = new Foo(3);
     }
}

If I put the cursor on the Foo(3) in Bar's main() method and execute the push-tag command, I get a popup that shows me three things:

1. constructor Foo()
2. constructor Foo(String abc)
3. class Foo

It does not show me "constructor Foo(int def)", which is the one I actually want to go to.  I believe it's not showing it because it's protected instead of public.

Is there a way to have it show me protected (and even private or package) members?

jbezem

  • Community Member
  • Posts: 87
  • Hero Points: 8
Re: push-tag in Java only finds public members in other files
« Reply #1 on: July 14, 2006, 01:38:57 PM »
Do you see those elements in your 'Defs' windows at the left?
Maybe if you cannot see them there, making them visible there will also change the 'push-tag' selection.
Right-click in the 'Defs' window, and in "Quick filers" choose 'all tags'.

HTH,

Johan

ScottW, VP of Dev

  • Senior Community Member
  • Posts: 1471
  • Hero Points: 64
Re: push-tag in Java only finds public members in other files
« Reply #2 on: July 14, 2006, 02:15:36 PM »
Hi Rob,

I set up a project to test this problem, but I could not reproduce it. See the screen shot in the attachment. We don't have any settings that would filter out protected functions from that list.

In the Projects Tab, select the workspace, right-click, and select Retag Workspace. Are you still having the problem?

If so, what version are you using? What platform? Can you zip up your workspace and attach it so I can try to reproduce it?

--Scott

Dennis

  • Senior Community Member
  • Posts: 3961
  • Hero Points: 517
Re: push-tag in Java only finds public members in other files
« Reply #3 on: July 14, 2006, 02:34:29 PM »
If I slightly modify your posted example, I can get the behavior you are seeing:

Foo.java
Code: [Select]
package a.b.c;

public class Foo
{
    public Foo()
    {
    }

    public Foo(String abc)
    {
    }

    protected Foo(int def)
    {
    }
}

Bar.java
Code: [Select]
package x.y.z;
import a.b.c.Foo;

public class Bar {
    public static void main(String args[]) {
        Foo foo = new Foo(3);
    }
}

However, since Foo and Bar are in different packages, the protected constructor is not visible (in fact, the code no longer compiles), so it is correct (and, in fact, intentional) that it is filtered out.

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Re: push-tag in Java only finds public members in other files
« Reply #4 on: July 15, 2006, 02:44:09 AM »
The classes are definitely in packages (as opposed to the example I gave).  The question I can't answer right now (I'm at home and the code is at work) is whether they are in the same package or different ones.  It's possible that they're in different packages but that Bar is a subclass of Foo (which allows protected access in Java).

I'll take a look on Monday when I'm back in the office.

RobFreundlich

  • Community Member
  • Posts: 47
  • Hero Points: 2
Re: push-tag in Java only finds public members in other files
« Reply #5 on: July 17, 2006, 01:55:03 PM »
I'll take a look on Monday when I'm back in the office.

I've explored this further.  Here's what I've found (see the attached zipfile).  Assume Foo as follows:

Code: [Select]
package a.b.c;

public class Foo
{
    public Foo()
    {
    }

    public Foo(String abc)
    {
    }

    protected Foo(int def)
    {
    }
}

In the following table, SubFoo* refers to a subclass of Foo.

classnew Foo(3) legal Java?push-tag shows protected constructor?push-tag on super(3) shows protected constructor?
a.b.c.BarYesNoN/A
a.b.c.SubFooSamePackageYesYesYes
x.y.z.SubFooDifferentPackageNoYesYes

When Foo isn't in a package, and Bar isn't in a package (see my original example), then push-tag works properly.

So the problem seems to be that for protected members of packaged classes, push-tag cares only about whether the current class is a subclass of the member's class - it is broken for classes that are in the same package but are not subclasses of the member's class.

I suspect the root of this lies in the difference between the meaning of "protected" in C++ and Java.  In C++, there's no "package" concept, and so protecteds are only visible to subclasses.  However, in Java, protecteds are visible to subclasses and anyone in the same class.

I've found that developers who started in C++ and migrated to Java tend to be unaware of the difference (it makes a great interview question :)).  Given SlickEdit's strong C++ focus, I can see why push-tag might work this way (assuming I'm right, of course).