So what I need is some why to write a solution analyzer for Visual Studio, that can:
detect move class and move method refactorings.
display the recommended refactorings in Visual Studio.
apply the refactorings.
I have a console application that can do this (using the Roslyn compiler), but I want to integrate the logic inside Visual Studio. From what I have read, the current code fix/refactoring/analyzers support only document level of refactoring, but for me that is not enough information to recommend one of the mentioned refactorings. I need information about the whole solution.
So my question is what is the best way to do this? Can you recommend a starting point? Some articles related to the topic? Any advice would help me a lot.
Short Answer: There is no reasonable way to do this with the Roslyn API
Long Answer:
The api as it is currently implemented only allows analyzers to know about things in the current compilation (a project in Visual Studio). If you call RegisterCompilationAction from within the Initalize method in your analyzer, you will be able to look at all the symbols within the compilation.
Why can't analyzers see the scope for an entire solution? The simplest answer is: because the compiler can't, and analyzers run inside the compiler. This is done so that analyzers can be run on continuous integration servers without Visual Studio installed. MSBuild reads the solution file and then invokes the compiler once for each project. The compiler is never aware of project dependencies and the compiler team does not want to be in that business, they are happy to leave it to MSBuild.
People have tried to work around this by loading their solution using MSBuildWorkspace and attempting to look at documents across projects that way. This will fail occasionally because MSBuildWorkspace is not thread-safe. It will also cause memory usage to skyrocket. People have tried to cache MSBuildWorkspace instances to partially resolve this problem but the cache needs to be invalidated every time a new compilation is created (essentially in the event of all but the most trivial changes). Basically, going down this path is rife with pain and is unsupported.
Enough people have asked for this feature that its something we think we need to do eventually. There is no reasonable way to accomplish it today unless you are willing to write a Visual Studio extension that imports the Visual Studio Workspace and attempts to run its own analysis engine. Please file feature request on https://github.com/dotnet/roslyn
Related
I am using Roslyn for some code generation in one of my C# projects. Currently Roslyn will take the entire project, compile it from scratch, then spit out the code I want. This takes a full recompile to do, which is a little slow. When Visual Studio compiles a project it doesn't do it from scratch every time, it does something smart and only re-compiles the parts that have changed. Is there some way to do this with Roslyn?
Visual Studio (in the upcoming version) uses Roslyn to compile the code (to IL). For a single project that is not incremental and never was.
I may be wrong as I'm not sure about Roslyn, but you may be able to seperate the Roslyn code into another solution and have a seperate solution for your own code.
After that you can simply build the solution that changes all the time.
the book I'm reading went briefly over command line building, specifically controlling the linker.
But any class and .cs file containing classes or resources seems to link just fine if they reside inside my project, can I just ignore the command line builder for now until I'm more profficient in C# or is this something I need to know right now?
CommandLine builder using csc.exe in my knowledge is not used by even experienced professionals. Everyone goes the route of Visual Studio latest versions and it is safe to ignore commandline building.
But you can try and understand how it works. Because, in the end this is the one which is used by your GUI tools like Visual Studio to do the build.
I would generally say it is worth knowing how to use the command line building, but it is not a necessity. I started off just using Visual Studio and wasn't even aware of command line building for C#. However, since I learned to use it and write Command Script files to execute it, I actually use it fairly often - especially when working on large projects that have multiple dependencies in need of building. In that situation, it saves opening multiple Visual Studio instances.
Agreed with Muthu. Building via CSC.exe is good option and works for simple setups or for learning, but if you have a complex solution structure in Visual Studio using inter-project dependencies, post build events, etc. its best to just invoke the Visual Studio build call itself via the command line. The command is devenv.exe and you'll find lots of documentation on it.
If you are trying to learn C# complier/linker innards maybe you'll be more interested in Project Roslyn from Microsoft as they try to open the "black box" of the compiler.
I've inherited a rather complex AsP.Net 3.5 web application derived from
Several DLLs. I've used .Net Reflector to examine the DLL contents. However, I am looking for a code analysis tool that might help identify key class files, show how the application makes database calls (it's not obvious from the codebase), and generally suggests ways to improve the codebase.
Does such a (free?) tool exist?
Take a look at NDepend (no, it's not free). It might not do everything you want, but it's a great code analysis tool.
I like AQTime from http://www.automatedqa.com/ for this. There's a free trial. The architecture tools in Visual Studio 2010 Ultimate also allow you to generate graphs from assemblies.
Edit: You can also right-click on any method in VS 2010 and select Generate Sequence Diagram ... which is very helpful sometimes.
how come you use reflector to examine the DLL's rather than visual studio?
There's a reflector plugin to decompile the DLL's back to projects: FileDisassembler
Stepping thru the code in the VS debugger is the best code analysis tool, otherwise possibly even Rd-Gate Perf Profiler to record call stacks over time.
+1 for the architecture tools in Visual Studio 2010
IDE Configuration:
Visual Studio 2008 + Resharper 4.5.1 + Agent Smith 1.1.8.
There is no any sophisticated configuration for last to add-ins.
Solution description:
33 class libraries + web site with 200+ pages.
Symptoms: After an hour of work under tuned on Resharper the IDE starts to throw the OutOfMemoryExection exceptions. Normal work is impossible only reopen Visual Studio can help.
Does anybody has such problem? Is it possible to configure Resharper to consume less memory? What Resharper feature does consume the most memory?
Welcome to the World of ReSharper. This lesson is called, "You get what you pay for".
Various features of ReSharper do require knowledge of your entire solution. This information takes memory. The solution-wide analysis may be the most memory-intensive, but even changing the signature of a public method requires knowing all the code that calls that method.
One thing you can do sometimes is to use smaller, "sub-solutions". If you are refactoring your DAL layer for instance, you only need the DAL and any unit test projects. What I sometimes do is to select the solution in Solution Explorer and use File->Save Solution As to save it with a different name in the same folder. I then remove projects until I'm left with those I want. Do not save the projects you're removing (save them before you start). When you've got the set you want, just do a Save All.
If it becomes too much of an annoyance, you can also get ReSharper to display the memory usage in the status bar. That feature has been available for a long time.
If you're on 64-bit Windows (or you're happy to run 32-bit Windows with the /3GB switch), then you can configure Visual Studio to be /LARGEADDRESSAWARE, which, rather than 2GB, will give it 4GB (or 3GB on /3GB) of address space to play with.
See, for example, http://old.stevenharman.net/blog/archive/2008/04/29/hacking-visual-studio-to-use-more-than-2gigabytes-of-memory.aspx, which gives the following:
editbin /LARGEADDRESSAWARE devenv.exe
Also, see the JetBrains page on the topic: http://www.jetbrains.net/confluence/display/ReSharper/OutOfMemoryException%2BFix
I have seen this and similar problems in the past with earlier versions of Resharper (and other similar add-ins) and large solutions, and is one of the reasons I try to stay away from them. The only solutions I know of were to restart Visual Studio, uninstall Resharper, or keep it turned off except for when you really need to use it.
For what it's worth, Visual Studio 2010 should help with these types of problems.
(This question is rather similar, but the only answer does not seem to be answering my needs).
I am thinking of using Thrift in C#, and am considering how exactly the build process would work. Do C# projects in Visual Studio 2008 support custom build actions that generate C# classes?
I found the "Custom Tool" option, but I'm not sure it's what I'm looking for ... it only allows design-time usage (not integral to the build process, but rather right-click "Run Custom Tool").
Update
Prebuild events that Fionn suggested are indeed suboptimal, as they don't take dependencies into account and prolong the build process. Also, they are managed from a central location instead of per-file.
What if you simply put your code generation to the pre-build events.
They are found in the "Build Events" section of the Project Properties in Visual Studio.
Also they support some macros which you will see if you use "Edit Pre-build ..." button.
The simplest and safest option is to include the generation in the "Pre Build Events" as Fionn mentions. Pros: code is always correct, Cons: Slow as this will mean at each compile that you re-generate the source code, and then rebuild all dependencies, as the generated code as altered.
Another option is to manually regenerate the code files, and if you have a build machine/continuous integration rebuild the code files each build. Pros: Faster builds, if there are few changes Cons: out of date generated code, and hours of wasted debugging trying to solve what's wrong.
Reading the C# project help, it seems that you need a plugin that provides the Custom Tool action you want. But in C++ projects you can define your own custom step MS-Help. So you could develop a VisualStudio plugin (or find one) or add a C++ project to your solution, and add a custom build step to that project, and then include the output in your normal C# project.
The first google for 'visual studio custom tool code gen' has a how-to write your own Custom Tool which would be a good starting point.
MS Build is highly configurable. Visual Studio itself is also very extensible. You can use the CodeDOM to emit classes. Depending on how much time you want to put into customizing VS and the build process, there is very little you cannot do.