Whole Tomato Software Forums
Whole Tomato Software Forums
Main Site | Profile | Register | Active Topics | Members | Search | FAQ
Username:
Password:
Save Password
Forgot your Password?

 All Forums
 Visual Assist
 Feature Requests
 C++ refactoring / transform function
 New Topic  Reply to Topic
 Printer Friendly
Author Previous Topic Topic Next Topic  

smacl
New Member

3 Posts

Posted - Jan 26 2011 :  04:32:35 AM  Show Profile  Visit smacl's Homepage  Reply with Quote
I've recently refactored a largish code base to replace one error logging function containing literal text, with a similar function referencing an external file. I ended up writing a tool to do this, but could see it as a very useful enhancement to VAX. This involved taking the output from Visual Assists find all references option, and use it to refactor the code base. The general problem can be stated as something like this

G??For a C++ code base, find every occurence of function fn taking parameters a,b,...n
G??Remove the occurence of fn from the source file
G??Extract the parameters as text variables
G??Add a few more variables such as instance number, source file name, etc...
G??At the point where fn was removed, write a formatted string that can include any available variables in any order
G??Append similar formatted strings to one or more external text files (e.g. resource files etc...)

I'm guessing the above functionality would be easy enough to implement, and mught be a good first step in providing a 'transform' refactoring option. This started as a brief discussion on StackOverflow here;

http://stackoverflow.com/questions/4713697/any-good-c-refactoring-tools-that-could-handle-this-scenario/4802682#4802682

feline
Whole Tomato Software

United Kingdom
13875 Posts

Posted - Jan 27 2011 :  11:43:16 AM  Show Profile  Reply with Quote
To be honest this does not sound easy to implement to me, but partly because I am not actually sure of the scope of this general outline.

If I understand correctly it would capable of performing incredibly complex code modifications, which makes it very complex, and raises a scary number of edge cases and complications. Ignoring that, it is not at all clear how you could define the steps in a simple manor for VA to understand.

I am tempted to agree with some of the comments on stackoverflow, that this sounds more like a job for a regular expression search and replace than anything else. The IDE regular expression find and replace dialog lets you pick up "pieces" of the search string and insert them into the replacement string.

zen is the art of being at one with the two'ness
Go to Top of Page

smacl
New Member

3 Posts

Posted - Jan 28 2011 :  03:43:47 AM  Show Profile  Visit smacl's Homepage  Reply with Quote
The general problem is very similar to the one described in Fowlers Refactoring, ISBN 0-201-48567-2 'Introduce Parameter Object', p295. The specific case that I was dealing with had the added fun of having multiple parameters declared as a combination of ellises and either literal text or a resource reference depending on which override of the function was being used. I'm guessing that this is a pretty common refactor, certainly one I've encountered many times.

It took me about two days to write a C++ program that coupled with the VA find references output worked very well for the cases I was after. I've done something similar in the past, using find with regex, but it was less reliable and had many problems, such as finding occurences in commented out blocks. The difficult part is parsing the source, which I'd figured you already do, rather than doing the substitution. The notion that you can use a regex or sed to reliably parse a C++ code base is IMHO pure wrong, I wouldn't recommend it to anyone. Been there, done that, still have the scars.

I can understand your reluctance in adding a facility that gives the user the ability to user to trash a code base, and this is more than reasonable, particularly given the current limitations of the VA parser (i.e. case 2732) FWIW, the approach that I used was to use the main code base as input and create a second copy of the code base as output. I could then refine the refactor until the output passed all my automated tests.

Anyway, I've solved my problem at this end and have a solution if I need to do something similar again. VA formed a very important part of this solution.

Apologies if any of the above appears critical of VA, it is not intended as such, just poking around for ways of improving it. I consider VA to be the best productivity tool for C++ out there bar none, and remain a staunch fan.
Go to Top of Page

feline
Whole Tomato Software

United Kingdom
13875 Posts

Posted - Feb 01 2011 :  3:08:58 PM  Show Profile  Reply with Quote
I have a copy of Refactoring, and have just had a look at 'Introduce Parameter Object'. At a basic level this is something that you can get help with from VA, perhaps by calling Rename. In a large code base though, where does the parameter object come from? Is it always defined?

An example inspired by the book, starting with:

double getFlowBetween(Date start, Date end)
{
    if(start > end)
    {
    }
}

you could use Rename on "start" and turn it into "range.start", and you can then use Find References to locate all of the calls to getFlowBetween that need to be updated.

But this still leaves you with the "hard" problems. The new object "DateRange" has to be declared, created at the correct places, passed sensibly, and used correctly. I am not sure how even a very clever parser is going to get you over these problems, since these are all decisions that need to be made, not simple pre-defined steps that a tool can perform, since they are not actually well defined.

zen is the art of being at one with the two'ness
Go to Top of Page
  Previous Topic Topic Next Topic  
 New Topic  Reply to Topic
 Printer Friendly
Jump To:
Whole Tomato Software Forums © 2014 Whole Tomato Software, Inc Go To Top Of Page
Snitz Forums 2000