Author |
Topic |
|
bta
Ketchup Master
Belgium
57 Posts |
Posted - Jul 24 2018 : 08:57:16 AM
|
I have a question related to filenames in a solution/project.
At this moment in time our solutions consist of only 1 project. Each cpp file in the project has a unique file name. In other words, there is only 1 classname.h and 1 classname.cpp in the project. Because we allow the same class name to exist in multiple namespaces, but still want to have filenames which are unique, we currently have the rule that the filename should include the namespace. So, if we have class X in both namespace NS1 and NS2, we prefix the filenames with the namespace: so we have ns1_x.h/cpp and ns2_x.h/cpp.
Since we recently upgraded to VS2017, where there is better nested namespace support, we are thinking of making more use of these nested namespaces. (Currently we only allow 1 level of namespaces) As one can imagine, our uniqueness of filenames becomes quite annoying and we are thinking of taking actions to drop that requirement.
From our side, our custom build system should be adapted, but we are also analyzing the impact of this change on all the other tooling we are using. One very important tool is VisualAssist. Is VAX able to handle this? How will functionalities like Find References, Rename refactorings, Add include react? Will they still work nicely?
I already did a small test and noticed that if you do not fully qualify the class name (so X (in combination with a using namespace NS1; in a cpp file) in stead of NS1::X), Visual Assist is not always including the correct headers anymore, nor does it see method implementations I already added. Note that this is not really an issue of non-uniqueness of filenames, but we didn't encounter this issue that many times before since we only allowed 1 level of namespace levels.
Any advice on going down this road? -non-uniqueness of filenames -multiple times the same class name, but in different namespaces
Thanks! Bart |
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Jul 24 2018 : 12:49:54 PM
|
Duplicate filenames in general should never be a problem. If the cpp / .h files are not paired, so you have 5 copies of "myClass.h" but only 4 copies of "myClass.cpp" then Alt-O won't always know which file to jump to, and you could have other problems with refactoring commands that are looking for the matching file.
Since you are only using one project the options to tell VA to limit its self to the current project, thus "hiding" other duplicates, won't help here. But it might be helpful to know this is possible if you do ever have more than one project.
We are working to improve our namespace handling and support, but as you have found it's not yet perfect. There are a couple of options here, depending on how you do this.
When are you seeing the namespace problem? Is this happening with a specific refactoring command, or at other times as well?
Do you have a simple code sample that would show the problem? This may well be a known bug, but I would like to be sure it's not a new bug. |
zen is the art of being at one with the two'ness |
|
|
bta
Ketchup Master
Belgium
57 Posts |
Posted - Jul 26 2018 : 07:06:18 AM
|
It is basically something like this: Have bart.h and bart.cpp in folder1. Have bart.h and bart.cpp in folder2.
in Folder1: bart.h contains:
//folder1/bart.h
#pragma once
namespace Folder1
{
class Bart
{
public:
explicit Bart(int i);
~Bart();
Bart(const Bart &other) = delete;
Bart(Bart &&other) = delete;
auto operator=(const Bart &other)->Bart& = delete;
auto operator=(Bart &&other)->Bart& = delete;
int getI() const
{
return m_i;
}
private:
int m_i{0};
};
}
have an bart.cpp in folder1 containing
#include "folder1/bart.h"
using namespace Folder1;
Then have a bart.h in folder2 containing
// folder2/bart.h
#pragma once
namespace Folder2
{
class Bart
{
public:
explicit Bart(double i);
~Bart();
Bart(const Bart &other) = delete;
Bart(Bart &&other) = delete;
auto operator=(const Bart &other)->Bart& = delete;
auto operator=(Bart &&other)->Bart& = delete;
double getI() const;
private:
double m_i{0.0};
};
}
and a bart.cpp in folder2 containing:
#include "folder2/bart.h"
using namespace Folder2;
Now put the cursor on the class names and make use of Create Method Implementations... refactoring (I use shortcut Alt+Shift+Q). Do that on both classes and the methods will nicely be created. Save all files, and but the cursor back on the class names and try the shortcut again. It will not propose to create the method implementations = correct.
The thing now is that it creates the methods with namespace included. So
Folder1::Bart::Bart()
{
}
As I already have the using namespace Folder1, I typically remove these namespace prefixes for all of the methods. If I do this for both cpp files, save, and then stand on the class name again, then for Bart in Folder1 it still doesn't propose to create methods, but for Bart in Folder2 it suddenly does. So it doesn't see that the methods are already present.
Note that the thing I mentioned about not always including the correct headers anymore, is wrong. It seems to work fine. Both in the case I have some
Folder1::Bart b;
as in the case
using namespace Folder1;
{
// ....
Bart b;
// ....
}
I first made a mistake and had the same using namespace Folder1 statement in both bart.cpp files, which is obviously causing the confusion.
Also the remark I made about not seeing method implementations even without non-uniqueness is something you already know. It had to do with = default implementation of ctor and dtor in the cpp file. If you have that, it still proposes to create an implementation.
Bart |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Jul 27 2018 : 10:02:11 AM
|
Thank you for the code samples and the clear description, I see what you mean now, and what is happening. VA adding the namespace when doing Create Implementation, even though there is a using namespace line in the cpp file is currently a known problem:
case=20637
I am rather surprised to see VA offering Create Implementation on the class in the second namespace, that is not supposed to happen, especially when Alt-g does take you to the correct implementation from the declaration, so VA does know about the cpp file and the implementations. I have put in a bug report for this:
case=117999
I don't understand what you mean about not including the correct headers. Are you triggering Add Include at some point in your test?
There is at least one problem with VA matching up the declarations and implementations here, which is why Create Implementation is being offered when it should not be offered, but what are you seeing with = default on the constructors? I am not seeing any instances of the word "default" in the code sample, so I am not sure what you are looking at here. |
zen is the art of being at one with the two'ness |
|
|
bta
Ketchup Master
Belgium
57 Posts |
Posted - Jul 30 2018 : 02:52:08 AM
|
With the thing about not including the correct headers: I am indeed triggering the Add Include when standing on the type Bart or fully qualified Folder1::Bart. But as said, I made a mistake in the bart.cpp file and after correcting it VA is adding the correct include in both cases. So no issue here. |
|
|
feline
Whole Tomato Software
United Kingdom
19022 Posts |
Posted - Jul 30 2018 : 08:10:03 AM
|
That makes sense, thank you for explaining. I wanted to make sure I had understood all of the problems you are seeing here. |
zen is the art of being at one with the two'ness |
|
|
ChrisG
Whole Tomato Software
USA
299 Posts |
|
|
Topic |
|
|
|