Author |
Topic |
|
tailsu
Senior Member
37 Posts |
Posted - Sep 05 2007 : 07:52:47 AM
|
Many programmers prefer having inline methods defined after the class declaration, not in it, so its interface is clear of code.
Currently this operation goes as follows: 1. Refactor: Create implementation. 2. Copy+paste back to header (or .inl, or *Impl.h) file 3. Prepend inline to the method header.
It'd be nice if VA could do this all at once.
Also, it would be nice if Refactor: Create Implementation could work even if there is no corresponding source file - just append the implementation to the same file (with inline semantics even). |
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Sep 05 2007 : 08:52:24 AM
|
The problem here is that you have already started to point out some of the complications.
Where do the implementations go? To the header file? To the inl file? To the cpp file? If the programmer wants inline functions then do they want them inside the class or outside of the class?
If you are looking for inline functions then why is there a matching cpp file? Obviously there is a matching cpp file, since this is where VA is placing the implementations. Does this mean you actually want some functions to be inline in the header file, and some functions to be in the cpp file, without the inline function?
This is verging on turning Create Implementation into a wizard, where the user is asked a series of questions. This is something we have tried very hard to avoid doing. We have tried to keep the refactoring operations very "simple", so you don't have to answer a load of questions every time you trigger a refactoring operation. |
zen is the art of being at one with the two'ness |
|
|
tailsu
Senior Member
37 Posts |
Posted - Sep 05 2007 : 11:29:54 AM
|
My guess is that the posted outline of my idea was half-baked, so I present a specific design.
First. No wizard here. Just, besides having Create Implementation in the menu, there will be an inline alternative right beneath it. Then I'll just map the first to Shift-Alt-Z, and the other to Shift-Alt-X, and the simplicity of the refactoring operations (as in 'not having options') remains.
Second. The inline implementations should always go outside the class. This way VA would save us the trouble to copy the whole method declaration (which gets even harder when the return type is nested in the class) *plus* the class name (this is especially onerous when the class is a template and templates don't usually have .cpp's). And creating implementations within the class is just opening a '{' instead of writing ';' - that's easier than opening the refactoring menu so there's no need for such an action.
Third. I've noticed that the 'Open corresponding .h/.cpp file' works also when there is only a File.h/FileImpl.h pair, so my guess is that VA's features don't shun being over-specific. When 'Create Inline Implementation' is invoked it could just check if there exists an .inl or Impl.h file with the same base name - if so, drop the implementation there; if not - put it right into the header.
My last suggestion comes naturally - if there is no .cpp file then Create Implementation and Create Inline Implementation will do exactly the same thing.
Well.. technically all that this feature will do is decide in which header (.inl, *Impl.h) the implementation will go, create an implementation, prepend 'inline' if the class is not a template et voila.
Cheers :) |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Sep 05 2007 : 2:27:16 PM
|
First the new inline refactoring point. Does anyone else want to comment on this? My suspicion is that there is not enough real interest in a "Create Inline Implementation" to warrant adding this refactoring to VA. VA already does this automatically for template classes, so we don't need to consider that case.
Let me assume for the moment you are using VS2005. Consider the following code in the header file:
class testCreateImplementation
{
const int getWidth() const;
};
Run Create Implementation on the function and you get:
const int testCreateImplementation::getWidth() const
{
|
}
where | is the caret. Now if you have an IDE macro that issued the following commands:
Down arrow once CTRL+SHIFT+] SHIFT+Up arrow twice CTRL+X VA's alt-o command CTRL+END CTRL+V
The new implementation would be picked up and moved to the header file, and placed outside of the class. I know these commands will work in VS2005, I just checked them. The keyboard shortcut for selecting the matching brackets and everything between them may be different in your IDE or keyboard scheme though.
See this FAQ for some information on calling VA with an IDE macro:
http://docs.wholetomato.com?W382
It is easy enough to make the macro a fraction cleverer, and have it add the inline keyword, plus pick up a line or two of white space.
The hard part is generating the correct implementation, as you say, but VA has already done that for you
As for Create Implementation finding an alternative file to use, this is an interesting point. Do you often have this situation?
I have just been running some tests here, and as you say alt-o can find the file. However alt-o also understands other C++ extensions that you define:
http://docs.wholetomato.com?W328
so it easy to imagine some very strange situations developing, and Create Implementation may not always do what you want. I don't want Create Implementation to start asking which file to use when it finds more than one file exists. |
zen is the art of being at one with the two'ness |
|
|
tailsu
Senior Member
37 Posts |
Posted - Sep 06 2007 : 04:26:10 AM
|
Well, I can live with a macro. Of course if VA provided this functionality it'd be much easier for me, but if no one else wants it, then I guess the VA dev team can just focus on more useful features :)
Recently I'm developing a header only library. 'Create Implementation' does nothing when there is no source file. My way of cheating VA is to create an unused source file and Create into it, then copy. Finally, I delete the source. It's, well, bothersome. If VA could at least create an implementation into the header file if no source is present, just that would make me happy.
I, too, think that Create Implementation shouldn't discriminate between multiple source files. However, sometimes I have multiple headers that are implemented in a single source file (with a different name from all headers) to decrease compiling time and CI just doesn't work for them.
If the Create Inline Implementation idea is dismissed, then I at least propose that Create Implementation (Move implementation should too) just dumps the implementation into the same file when it has no other meaningful options.
How about it? |
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
Posted - Sep 06 2007 : 12:59:19 PM
|
To be honest I am not sure what to say here. You make a good point, and in your situation this new behaviour makes a lot of sense, and is exactly what you want.
The "fun" starts when you ask "why is there no cpp file?"
Is this because the programmer is working without cpp files (as in your case) or is it because they are going to have a cpp file, they just forgot to add it to the solution (it exists on the hard drive) or they have not yet created it?
I suspect that this is going to be the case 90% of the time or more, when you look across all users. If I am correct in this assumption then the current behaviour makes sense, since it tells the user something is "wrong", which it is. |
zen is the art of being at one with the two'ness |
|
|
sl@sh
Tomato Guru
Switzerland
204 Posts |
Posted - Sep 07 2007 : 04:37:37 AM
|
How about this suggestion:
VA already automatically treats templeate functions as inline and creates implementations inside the header as a result. What about 'Create Implementation' on a function that already has the 'inline' keyword? To me it would seem obvious to create the implementation inside the header! As pointed out, the preferred location would be at the end of the file, not inside the class.
No ambiguities, no wizard, no new refactoring command, not even an option needed. For those who prefer the implementation to appear right inside the class, typing a '{' will work just as well - they won't need refactoring at all.
There's only two things to do: 1. VA needs to treat 'inline' functions the same way it already does treat template functions. 2. Users will need to explicitely include the 'inline' keyword in their function definitions, if they intend to use 'Create Implementation'
|
|
|
feline
Whole Tomato Software
United Kingdom
19021 Posts |
|
|
Topic |
|
|
|