The plugin, called 'Refactor Lambdas' does the following :
- Looks for duplicated lambda expressions
- Once detected, breaks them out into a separate function
- Names the function something based on what the function is doing
- Has some capacity to do fuzzy matching (if 2 lambdas are both the same logically but use variables from the outer scope with different names and the same type, it can still refactor those 2 lambda expressions)
Showing may be easier than explaining in this situation. Here's how the plugin would react to a scaffolded controller from the MVC scaffolding project (A gallery of images is below if you don't have Flash)
Here's a link to the repository on BitBucket
I would enjoy having this as apart of ReSharper so I think it's actually a worthwhile plugin. Also you could get really crazy and search the entire codebase, with a fuzzy search, and condense all duplicated lambdas. It would have to be torn apart but I think this is a good end-goal to have with this project.
Some Todos in case anyone is interested. This would be a good project for someone to get their feet with in open source :
- Unit tests are good but need a little work. I could not find an easy way to unit test without specifying cursor position in each test; yuck. Still has >90% test coverage and does all testing in memory. Could use some negative tests.
- Fuzzy matching could be improved when deciding if 2 lambdas are equivalent.
- Make it work on files with multiple classes (not really super important--right now it just takes the first class and does the search there)
- Speed considerations? Any way to detect this code issue more efficiently?
I'll release this as a Visual Studio plugin on the gallery once Roslyn is finished and pushed out to Visual Studio 2012 and is enabled by default. Comments?
Wouldn't this work on VS 2010 ?
ReplyDeleteNot without a big rewrite. You could rewrite it as a plugin that simply uses Roslyn to parse the code and not Roslyn language services like I have here.
ReplyDeleteIt won't even work in 2012 unless you have the Roslyn command-line argument set (and Roslyn downloaded). And even then it won't work in modules that use things like 'dynamic'.