Author |
Topic |
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Apr 03 2020 : 04:09:11 AM
|
Hello, here is an issue a bit annoying (but the result is OK). Let's consider a class declared and defined only in a .cpp file. Normally this class is only used within this .cpp file (unless it's been #include into another .cpp file, but it should be super rare).
The problem is that any find references (or replace) on the class itself or any of its members will trigger a search within the whole solution even if normally the symbols should be only used within this .cpp file. This can be annoying in a large solution where the search can take several seconds instead of being almost instant and so I have to press stop everytime. It happens to me quite often with many private implementations.
As mentioned above, #include a .cpp mostly never happen. Generally any source file included into another one has an extension file like: .hpp, .hxx, .inl, ...
In my opinion, find references on a symbol declared in a .cpp file should be restrain to only this .cpp file and not looking anywhere else.
PS: by writing this, I was thinking that class can be forward declared somewhere else and so find references on the class itself should look in the whole solution. However this is not possible with members variables and functions which cannot be forward declared. So my remark only applies to class members. |
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Apr 03 2020 : 07:22:21 AM
|
Are you aware of the command:
VAssistX -> Find References in File
which will do the local find, basically instantly, that you are looking for?
The next step is turning Off searching all projects, in the Find References Results window, which will limit the scope of all searches to just the current project, which will probably generally help.
Do you often come across classes defined in a cpp file, or is this a fairly rare case in your code? Thinking about it, I cannot think of many normal cases where this assumption about scope would break down, but I have seen people including cpp files directly, bizarre as it is. So I am wary of an assumption that might cause more problems than it solves. |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Apr 03 2020 : 09:40:48 AM
|
I forget about Find References in File, I should map it as shortcut .
Regarding the Rename functionality (actually this was my main concern) there's no such alternative. And I see one limitation about the dialog is that the checkbox "Search all projects" is disabled until the search is finished. But I guess it's easier to not change options during the search. |
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Apr 03 2020 : 09:47:47 AM
|
Does limiting the search scope to just the current project help enough?
My first thought is that a slower, but more reliable search for Rename is probably best, since while you will use Find References in File a lot, Rename is likely to be run less often, but it is more important to catch cases where searching all files is important. Does this thinking make sense? |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Apr 06 2020 : 08:22:15 AM
|
I guess you're right. You can close this thread.
Actually, the most frustrating thing is that Find References / Rename pull find a lot of similar but unrelated symbols (with ? question mark in front of) all over the solution which make harder to actually find the true references in the list.
Let say I have a quite generic function named "SetName()" from class "A", VA will find a lot of references to a function with the same name but from different classes. Some occurrences are legitimately ambiguous because they are used in template code, but some other don't. I might open another bug for this if I can find a small repro. It happens quite often in my large code base, but I'm unable to reproduce it with a small example.
Anyway, thanks for your support. |
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Apr 06 2020 : 11:53:21 AM
|
Just trying to find the best solution, without possibly making something else more complex
I would like to look at some of these false positive problems with you. If you jump to one of the question mark items in the Find References Results list, e.g. you end up at:
MyOtherType foo; foo.SetName();
if you place the caret into "foo" before "SetName" what, if anything, is VA showing in its context and definition fields? These are normally at the top of the editor window, where the Alt-M list appears.
In theory, VA will understand the type of "foo", so it will know that this call to "SetName" isn't the one we are looking for. But I suspect this is not working sometimes in your code. Is there any obvious signs of problems with VA around where this call exists? Alt-M or VA Outline showing the wrong information for the file?
Perhaps some macro calls above? I am looking for hints as to what is confusing our parser. |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Apr 06 2020 : 1:27:11 PM
|
Ok so I did a test with a Foo::SetName() function, the context and definition are correct.
I've put the cursor on SetName, the Find references find about 40 wrong results (with quesiton mark). When I go to these references:
(a) For some the context is empty but that's normal it's in template code. But that's ok if they appear as unknown. (b) For some the context and definition look correct when I put the cursor on them. (c) For other the context and definition are empty, this mostly happen when the variable is declare with auto:
if(auto bar = GetBar()) // bar is a Bar*
bar->SetName(...); If I change the type to Bar* then the context is OK, and so this occurrence will not show up again when Find References. (d) There's also some auto case with structured bindings. (e) I found a case where, the type of the variable is explicit:
Bar bar;
bar.SetName(...); but it's inside a google test function where macros can be the cause.
So to me: (a) and (e) are Ok (I should spend some time to configure va_stdafx.h for (e)). (c) and (d) I don't know if you handle auto variables and structured bindings? I can make small example for these cases. (b) is the most intriguing but I can't figure out why. What could be the issue if the context of these variable is well defined?
|
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Apr 06 2020 : 2:29:44 PM
|
We do aim to handle auto variables. For the line:
if(auto bar = GetBar()) // bar is a Bar*
if you place the caret into "GetBar()" does VA correctly identify this function, and its return type? What happens if you try Alt-G on this function call? I would expect VA to work fine here, but clearly something is going on.
As a simple comparison, I have the following test case here, in VS2015, in the header file I have:
class testFindInAuto
{
public:
testFindInAuto* GetFindAuto() const { return new testFindInAuto; }
int getAutoHeight() const { return 1; }
int getAutoWidth() const { return 2; }
}; and in the matching cpp file I have:
void testingAutoAssignment()
{
testFindInAuto localFindAuto;
// Test - caret into "auto" shows the type of "barOne"
// Test - caret into "barOne" shows the variable declaration, with auto replaced with actual type
auto barOne = localFindAuto.GetFindAuto();
barOne->getAutoHeight();
// Test - again here, caret into "auto" and "barTwo"
if (auto barTwo = localFindAuto.GetFindAuto())
{
barTwo->getAutoWidth();
}
} can you try this simple example on your system, and see if you get the same handling of auto? I just want to check we have the same basic behaviour before looking further.
Google test macros could well explain the odd results you are seeing, and please let me know, preferably with a simple example, if you need any help setting up your va_stdafx.h file for these cases.
We do try and handle template code correctly as well, so perhaps worth a closer look once we have dealt with the other cases first. |
zen is the art of being at one with the two'ness |
|
|
tony.riviere
Ketchup Master
France
58 Posts |
Posted - Apr 14 2020 : 10:52:27 AM
|
Your simple example works fine. If now I add a "SetName()" function in the class, then it will find many unrelated references. I guess my other files are not parsed correctly somewhere, and not necessarily with Google Test macros. Just to mention that IntelliSense isn't doing better (except it's a lot slower ^^), it find also unrelated references, but not exactly the same ones.
How can I troubleshot if VA is parsing correctly a file? Is there some logs? |
|
|
feline
Whole Tomato Software
United Kingdom
19014 Posts |
Posted - Apr 15 2020 : 09:32:17 AM
|
Can you please jump to a couple of the unrelated references, and have a look at them? Is there any obvious pattern to these references?
If you place the caret into the function call "SetName()" what, if anything, does VA show in its context and definition fields? These are normally shown at the top of the editor window, and are where the Alt-M list appears. I suspect VA will either show nothing, or the wrong information, which is why these calls are showing up in the Find References Results. Since VA doesn't properly understand the call, it cannot tell if it is related to your search or not.
Assuming the "SetName()" call is happening on an object, can you move the caret back before the dot or -> and see what, if anything, VA shows in the context and definition field for the object? If VA doesn't understand this symbol, or doesn't know that this symbol's type has a "SetName()" method this would explain the problem, and help us to find out where things have gone wrong.
In these files can you also look at VA Outline and the Alt-M list, and see if these seem correct? If there is something confusing VA's parser it sometimes shows up here as well. For example if something strange at the top of the file confuses our parser, everything further down the file may be wrong. |
zen is the art of being at one with the two'ness |
|
|
|
Topic |
|
|
|