24

With intellij idea, how do I find out what makes a variable be visible?

An example of when it is hard:

  • Suppose you look at class A, and you see a variable something. If you jump to source you see that it's defined in trait X. But you don't extend trait X directly. What do you extend, then, that makes this variable visible? If you have a deeply nested hierarchy, tracking can be hard.

Any recommendations or solutions?

EDIT: Please vote for the feature if you're interested: http://youtrack.jetbrains.com/issue/IDEA-124369

VasiliNovikov
  • 9,681
  • 4
  • 44
  • 62
  • 1
    so it's about scala integration, not java? – Igor Konoplyanko Apr 23 '14 at 12:02
  • It applies to java, too. You do have options on how to make a variable/type visible in a file. – VasiliNovikov Apr 23 '14 at 12:55
  • I use IDEA every day and have for a long time and if that feature is available, I'm unaware of it. JetBrains is very responsive about feature requests, so you should probably ask for it. – Randall Schulz Apr 23 '14 at 12:55
  • do you mean CTRL+CLICK – Farvardin Apr 23 '14 at 13:18
  • 3
    @طاهر - `Ctrl`+`Click` (or `Ctrl`+`B`) takes you to the source code of the item. OP is looking for where it is brought (i.e. "imported" in most cases) into the file. – Javaru Apr 23 '14 at 14:48
  • I concur with @RandallSchulz (who is one of the few IDEA users I know of that has been using it longer than me ;)) The closest you will get is to do an _Edit > Find > Find Usages in File_ (`Ctrl`+`F7`). This will jump you to the first usage (often the import statement). You can use F3 to jump through them until you find the origin. You can also use the _Highlight Usages in File_ as well (`Ctrl`+'Shift`+`F7`). Of course, neither work for implicit imports such as for `java.lang.String`. In the end, a feature request is your best bet. – Javaru Apr 23 '14 at 14:48
  • 1
    This would be a really nice feature. If you log a request let us know so we can vote for it. – sourcedelica Apr 23 '14 at 22:31
  • 1
    @sourcedelica I created the issue on jetbrains: http://youtrack.jetbrains.com/issue/IDEA-124369 – VasiliNovikov Apr 24 '14 at 07:37
  • What would you expect to get in [this](https://scastie.scala-lang.org/toshetah/MlyxWF57QoyIy8LBVIuKzw) example for `trait C`? and what about `trait D`? – Tomer Shetah Dec 23 '20 at 14:29

7 Answers7

1

I don't think that IntelliJ IDEA has any shortcut for "finding what makes a variable visible".

However you can determine it using the "Find Usages" option (Alt + F7). For example:

import java.nio._
object TempObj extends App {
   def func = 2
   val p = file.Paths.get("some-path")
   func
}

So Find Usages on "file", tells you that its from the Package "file" (in heading of the new Tab it also shows the complete package name, ex: Find Usages of java.nio.file in Project Files). Whereas Find Usages on func will tell you that its a Method (And the Tab heading now says: Find Usages of func() in Project and Libraries)

So now in way you can determine, what exactly makes the variable visible. This also works for imports since it shows the package from which it is imported and you can then look for import of that packages.

KarateKid
  • 3,138
  • 4
  • 20
  • 39
  • IMO, this is just the same as jumping to source (`Ctrl B`). You jump and then you know the package name. Still, you don't know what made this variable visible in your context. For example: `trait A{def whereAmI=1}; trait B extends A; class Mystery extends B with Other with Other2 with Other3 {println(whereAmI)}` Now looking at the source of `Mystery`, I can't understand where the variable is from. Is it from `B`? Or from `Other`? Or maybe from an object that extneds `A` and we imported the object contents? – VasiliNovikov Sep 07 '16 at 07:32
  • ... Actually, "Find Usages" was already proposed earlier. Unfortunately, it does not work, because of the reasons described. – VasiliNovikov Sep 07 '16 at 07:36
  • Yes, you are right so the short answer is no you can not find it at the moment. – KarateKid Sep 07 '16 at 11:51
0

I know of two almost-solutions to this problem.

Go-to-declaration, as you mentioned, solves this problem in the case of local variables.

More generally, the "find usages" feature gives you a neat little breakdown by type and file of different uses of the variable. From this you can see if it's involved in a static import.

It's not perfect, but with a moment's thought these two are generally sufficient to figure out what you want.

Chris Kitching
  • 2,559
  • 23
  • 37
  • Unfortunately, neither `find usages` nor `go-to-declaration` don't fully solve the problem. These approaches still don't cover "underscore" import statements like `import smth._`. They don't help traversing the tree of mix-ins, too... – VasiliNovikov Apr 06 '15 at 14:04
  • In which case, you're up against a limitation of IntelliJ's implementation. Sorry. About all you can do is use "Find in path" (CTRL+SHIFT+F by default) to do a string search for what you want. At least IDEA makes such searches *fast* :/ – Chris Kitching Apr 06 '15 at 15:51
  • Yup, the way we currently do this kind of work is by using "find all usages" etc.. Comments convinced me that there is no such functionality built-in, so I at least created a "feature request" on their site.. – VasiliNovikov Apr 06 '15 at 19:23
0

Use ctrl+b or F4 to jump to source code. Alternatively you can use ctrl+shift+a to get option/action. You can find shortcuts at http://gaerfield.github.io/ide-shortcuts/ as well. Hope it will help.

Bhaskar
  • 159
  • 1
  • 2
  • 17
  • Hi, sorry, no, the question is different. Roughly speaking, I want to jump to an import/mixin statement in the current file/view rather than underlying source code. More detailed, see the question description itself. – VasiliNovikov Aug 30 '16 at 13:10
0

From what I understood you want to see the code that creates an Object you use, for instance Mystery someMystery;.
That gives you two options to populate someMystery:

  1. someMystery = ... where ... is your code to populate someMystery and if that is the case you should follow that code (with ctrl+B as far as you need to) to the point where it actually creates the Mystery object.
  2. Use CDI to populate that object instance for you, in which case you should look into the CDI mechanism in order to see in what way the object instance is populated.

In either way IMO there is no way to know for sure if the someMystery instance is of some more concrete class than Mystery, because it is decided in runtime, not in compile time, so your next bet would be to run the program in debug and see what object goes into someMystery, although you are not guaranteed to get the same type of object every time.

PS. My answer is based entirely on my java understanding of the topic, can't say if it is valid for scala also.

  • Not quite. I'm looking for what makes a variable _be visible_ at compile time in the current block of code. An example of when it can be hard to understand is a deep `extends` hierarchy. You know that, finally, this is a member of `trait X`. But you don't extend `X` directly. Where does it come to your code then? Anyway, it's stated in the issue. – VasiliNovikov Oct 04 '17 at 10:39
  • P.S. I've edited the text to try make it more clear. – VasiliNovikov Oct 04 '17 at 10:43
0

This might not be exactly the answer you were hoping to get.

However, quoting yourself,

If you have a deeply nested hierarchy, tracking can be hard.

Have you considered using composition over inheritance? Perhaps this would remove the need for the feature you are looking for.

ljleb
  • 182
  • 1
  • 14
0

Deeply nested hierarchy doesn't sound good. I understand your pain about that.

When you override vals or defs there is a little circle next to the line number that shows where it is from even when it is from nested hierarchy. Hovering over vals with the command key down also shows you a little tooltip where it is from.

Does this help?

https://youtu.be/r3D9axSlBo8

sparker
  • 1,245
  • 11
  • 17
  • Hey, thanks for the answer. It doesn't address the problem, however. The problem is to see what makes a variable be visible, not where the variable is defined, as highlighted in the example. In your video example, on the second 18, it would be desired to see that `aX` is available because you mixed in `C` (which in turn has `A` mixed in). – VasiliNovikov Dec 28 '20 at 12:17
-3

if you want class, field or method to be visible, you need to implement them as public. If it was your question.

  • Sorry, no, the question was about IDE support and code navigation. So, code is already written and now you navigate through it. – VasiliNovikov May 03 '14 at 08:35