View unanswered posts | View active topics


Reply to topic  [ 30 posts ]  Go to page 1, 2  Next
[FD3] Refactor Plugin 
Author Message
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post [FD3] Refactor Plugin
Coming from the discussion at http://www.flashdevelop.org/community/viewtopic.php?f=5&t=5248, I've hacked my way through creating a simple refactoring plugin.

Refactor Project Page (Google Code)

Description
With it you can right-click any class member or local variable, and a new "Refactor" submenu will appear allowing you to find all references to, rename, or encapsulate the member.

Rename Works on:
  • functions
  • fields
  • getters/setters (simultaneously it seems)
  • local variables
  • function parameters
  • static and instance level
What Rename does NOT do:
  • Rename Classes or Constructors
  • Namespaces/packages
  • Check runtime references (e.g., myClassInstance["myMemberName"])
  • Check if you're renaming to a name that already exists
  • Check for an invalid new name (you could probably replace with a syntactically garbage name)

Find All References works/doesn't work in the same way as Rename, except you can also use it to find references to Classes/Constructors.

Encapsulate Field applies only to class fields. Works the same way as the existing getter/setter generator, except if the new property has a new name, then it will automatically redirect all references to the original field to point to the new property as well. If the new property has the same name as the old field (i.e., the generator renamed the field), no renaming happens as all the references are already implicitly pointing to the new property.



Any changes are made temporarily. The files will remain open and marked as changed, you would have to hit "Save All" afterward to commit these changes.

I've never touched FlashDevelop for other languages (HaXe, etc.), so if anyone wants to give those a shot, feel free! (note: the search for files is hard-coded at "*.as" right now, so if the language uses something else, it won't work. Is this something you think we can switch to *.* or is there a listing of valid extensions per language?)

In terms of development, I would see this plugin not necessarily implementing it the best way; more of a proof of concept I suppose. As pointed out in that refactoring thread, the implementation is pretty crude. It essentially executes a whole word/case sensitive search for the member in all project files, then resolves each result to see if it points to the member, then replaces the text. In the process it has to open all the files as they are checked due to the current implementation of FD. I tried working around it but it was a bit too stubborn in its ways. :wink: (note: if it's a local variable or function parameter, it will only search the single file instead of the whole project) (As of version 0.2.4, it tracks files opened in this way and closes them if in the end they do not contain actual references)

As of version 0.2.0, the code structure has been reorganized to allow for easier addition of refactoring tools and to cascade their usages. For example, "Rename" works in conjunction with a "Find All References". "Encapsulate Field" works in conjunction with a "Rename".


If you look at the source code, there are many "TODO" flags. Either questions from me or comments on things that should be considered for changing. I'm hoping that this becomes a bit of a collaborative effort to bring real refactoring support to this great IDE! If anyone has questions/comments/concerns regarding the implementation, by all means bring them up! Since this is my first plugin, if you have comments about my method of implementation they'll be much appreciated!

Thanks in advance to anyone who tries it out!


Current version: 0.2.5
This is a beta release. As such, be sure to have a backup of your project or have it under source version control. Though so far, in my usages of the plugin, it has not caused major issues other than the ones listed in the known bugs.

Download Current Version
Source Code


Tested on FlashDevelop versions:
  • 3.0.2 RTM
  • SVN build 664

Known Bugs/Issues

Version History
  • 0.2.5 - August 22, 2009
    - Added a dialogue reporting the process of the current refactoring operation.
  • 0.2.4 - August 22, 2009
    - Results panel now shows actual changes (used to show the previous state)
    - Highlights the proper words (used to highlight old word positions)
    - Closes any temporary files that needed to be opened to check for references, but did not contain any.
    - Fixed issue where if the Results Panel was collapsed, it would not expand to report changes
  • 0.2.3 - August 17, 2009
    - Now works on modified/unsaved files (but not on temporary new "untitled" documents)
  • 0.2.2 - August 17, 2009
    - Added "Encapsulate Field"
  • 0.2.1 - August 17, 2009
    - "Find All References" now works on classes/constructors as well.
  • 0.2.0 - August 17, 2009
    - Refactored internal structure to ease addition of new refactoring methods
    - Added "Find All References" command
  • 0.1.0 - August 16, 2009
    - initial implementation of renaming


Last edited by FizixMan on Thu Oct 01, 2009 2:13 pm, edited 35 times in total.



Mon Aug 17, 2009 1:31 am
Profile WWW
Member

Joined: Mon Oct 16, 2006 12:02 am
Posts: 279
Location: Lviv, Ukraine
Post Re: [FD3] Refactor - Rename Plugin
very quick test:
- It reverts last modifications if renaming is running in unsaved file.
- functions renaming doesn't work in AS3


Mon Aug 17, 2009 7:43 am
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor - Rename Plugin
Thanks for trying it out. I'll take a look at those when I get a chance, probably tonight.

I also noticed that it renamed for me a reference in a string literal (should be disabled!)

EDIT: I think the string changes are from an issue with the Find in Files methods. See viewtopic.php?f=6&t=5287

EDIT2: Though regardless of the Find in Files it SHOULD have kicked out those entries because when it would try to resolve the definition of the literal string, it should have failed and decided that they're unrelated...


Mon Aug 17, 2009 6:02 pm
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor - Rename Plugin
Canab, I've fixed the issue with reverting unsaved modifications in a file. Though if you are attempting to refactor that new modification, it probably won't work. In fact, I'm getting some pretty inconsistent results. I think this mainly stems from the fact that the "Find in Files" method searches from whatever the saved state is on the drive -- it does not take into account unsaved modifications currently open.

One workaround is to automatically invoke a "Save all" before running, but I think might be a bad idea.

I can't recreate the issue with the AS3 function renaming. I created a sample AS3 project and was able to rename the functions fine. Do you have a specific case you can post?


Tue Aug 18, 2009 12:12 am
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor - Rename Plugin
Worked on it again tonight.

Added a "Find All References" command. I also just did a quick test, the Find All References works on classes/constructors, but it's not included in the uploaded release. I'll probably clean up a 0.2.1 update with that exposed, probably Wednesday.

Completely refactored the structure of the plugin. It should be much more readable/usable now. It should be easier to add new refactoring methods to it as well. For example, now the "Rename" command works by first executing a "Find All References" then renames those. I can imagine other refactorings, such as Encapsulate Field would work similarly.

EDIT: Did the update to 0.2.1. Can now execute "Find All References" on classes/constructors.


Tue Aug 18, 2009 2:27 am
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
Oi, chalk up more spam for me!

Added a new update that has an "Encapsulate Field" command. This handles the case where the normal getter/setter generation creates the new property with a new name than what the original field was. In this case, we would want our references to the old name to point to our new property name. In the case that the property name is the same name as the original field (i.e., the original field got renamed instead), then no reference renaming occurs as they already implicitly point to the new property.


Tue Aug 18, 2009 5:25 am
Profile WWW
Member

Joined: Wed Aug 01, 2007 3:37 pm
Posts: 1134
Location: Roseville, CA
Post Re: [FD3] Refactor Plugin
This is looking great ...

If you don't mind me asking, would the following be possible now, or is close to being possible?

  • Rename all of the variables and methods inside of a class (one by one is fine)
  • Correct references to the class and its methods in other classes so the code still works correctly


Tue Aug 18, 2009 4:43 pm
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
elyon wrote:
Rename all of the variables and methods inside of a class (one by one is fine)

I could see running multiple Rename operations, but the problem comes the "Find in Files" that uses the saved state of the files. Each run of the Rename doesn't save (and I don't know if you'd want that to happen for this operation or not)

Perhaps we could modify the Find in Files to use the current unsaved state in FlashDevelop if the file is open there, otherwise read from the hard drive. In this case, as loon as the declaration resolution still works in unsaved files (I think it does), then this should work.

elyon wrote:
Correct references to the class and its methods in other classes so the code still works correctly

I'm not sure I understand what you mean by this. The rename currently should correct member references in other classes. Unless you mean it can find all instances where other classes are referencing non-existent members, pick up on these and prompt for replacement? I don't think that would be possible. We'd have to know where all instances of that class are being used and check all the members accessed on that instance. Best I can think of is finding all references to the class (and therefore, all the declarations of the class). Then running Find All References to each of those declarations. Then for all of those, check if any members are accessed. Then of those, find out whether or not they exist as members of our original class. I suppose, in theory, it could work, but I have no idea the kind of time to actually process that.


Tue Aug 18, 2009 5:04 pm
Profile WWW
Member

Joined: Wed Aug 01, 2007 3:37 pm
Posts: 1134
Location: Roseville, CA
Post Re: [FD3] Refactor Plugin
Let me clarify what I would intend to do:

  • Copy the project to another directory
  • Rename/refactor the variables and methods in certain files
  • Compile the project

Saving to the hard drive would not be an issue, since I would be working in a different directory. I want to be able to specify a subset of classes that I will completely obfuscate so the source code is completely unintelligible but it still compiles.


Tue Aug 18, 2009 6:11 pm
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
I can imagine creating a "Obfuscate" command that will rename members and local variables. We'd probably want to have it run through some GUI to let users choose specific members to not rename because they're dynamically referenced at run-time. At that point we'd probably want to save that as some obfuscation project file as I can imagine there would be many recompiles and it would be a pain/dangerous to keep manually skipping the same members.

If we have it execute a "Save All" command on each iteration, I don't see why some managing logic couldn't be whipped up that would inspect each class and successively call many "Rename" operations. I have a feeling for large projects it could take a long time, so we'll want to have some progress indicator somehow.


Tue Aug 18, 2009 6:26 pm
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
I've got it working now where it uses the modified versions of files if they are currently open in FlashDevelop. It's uploaded as an updated 0.2.3 version. This should pave the way to running multiple Rename (or possibly obfuscation) operations successively.

A note to Phillipe and Mika, I had to copy the PluginCore.FRService namespace and make slight modifications to the FRConfiguration class to read the files from the editor if they're open. I thought at first I would just create a new class and inherit from FRConfiguration, but the class doesn't have the necessary method marked as virtual to override its implementation.

I don't know if that's something worth considering (or if you already have and rejected it) to make some of these core classes virtual and extensible. If you do do that, I'll happily point to those and clear out my copy of the FRService classes. If you don't have the time to do it, but want to, let me know and I can alter them (though I may not know which aspects you'd want to keep sealed and which ones you think are worthwhile to expose to subclasses) and submit a patch.


Thu Aug 20, 2009 2:38 am
Profile WWW
Admin

Joined: Wed Aug 31, 2005 7:27 am
Posts: 7503
Location: Paris, France
Post Re: [FD3] Refactor Plugin
I suppose we should consider integrating your FRService fix so it first tries to modify files already open.


Thu Aug 20, 2009 6:56 am
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
I think you'd want to consider it as having it as one of the options in Find in Files rather than using that behaviour always.

Also, the version I uploaded here just checks to see if the TabbedDocument is open and "editable", but doesn't check if it's "modified". Probably faster than re-reading it from the disk, but I don't know we should only grabbed modified ones.

One final consideration: what do we do about documents that are open (but not the active document in FD), but have changed outside the program. Do we "Find in Files" using the updated state from the hard disk or the old, but open state in FD? I guess if we have it as an option, then it doesn't matter (should always do one or the other).


Thu Aug 20, 2009 11:55 am
Profile WWW
Member

Joined: Thu Jul 26, 2007 7:06 pm
Posts: 215
Location: Toronto, Ontario, Canada
Post Re: [FD3] Refactor Plugin
Updated to version 0.2.4

This version now keeps track of files as they are opened. If the newly opened file doesn't contain an actual reference back to your declaration (i.e., it happens to have the same name, but it's a completely different declaration) they will be closed.

The reported results show the actual resultant changes. Originally it would show the references before they were changed.

The highlighted words in the editor are now highlighted properly. Originally it would highlight the positions of the old words. So if your new name was of a different length, then all the highlights would be in the wrong position.

Also fixed the issue where if you had your results panel collapsed, it wouldn't expand to report the results of the refactor or found references.


With this done, I think the next thing to tackle will be a half-decent GUI. I think it should allow you to preview changes before they are made. Also right now, the changes are asynchronous, so the GUI should lock FlashDevelop (modal) and the progression of the refactor.

EDIT: Added a progress dialogue and updated the version to 0.2.5
EDITx2: Opened a Google Code project to track the plugin progress.


Sat Aug 22, 2009 5:18 pm
Profile WWW
Member

Joined: Fri Mar 09, 2007 8:02 am
Posts: 204
Post Re: [FD3] Refactor Plugin
excellent!! I always change my variable or function names. Thanks!!


Fri Sep 04, 2009 4:28 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 30 posts ]  Go to page 1, 2  Next

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.