How to use an altered Roslyn in Visual Studio - c#

C# isn't enough for me, so I've taken advantage of the newly-open sourced Roslyn to extend it, say by modifying it to use French quotes.
But I don't want to build my newly-French-quoted files on the command line! I want Intellisense! I want a nice UI! In short, I want to get Visual Studio to use my Roslyn, not Microsoft's.
Can I do this yet? If so, how?

Quoted straight from this link in your question:
ADVANCED USAGE
It is also possible to update your copy of Visual Studio to use your
own built version of Roslyn (for example, to see how the IDE reacts to
your changes), but it’s slightly complicated:
First of all, you’ll need to use the release fork, not the master
fork. This is because the compiler code is constantly changing in
reaction to feedback, and that includes changes to the APIs that are
used by the non-open IDE bits in the Roslyn preview in order to access
compiler information (until the APIs get locked down as we get closer
to completion). When these APIs change, the ability to communicate
between the two is lost. The release fork, however, accurately
reflects the state of the code at the time that the Roslyn preview was
snapped, and so is safe to use as a baseline for this sort of thing.
(You can see the fork on the Roslyn CodePlex site by choosing “Source
Code” and then opening the “Browsing changes in” dropdown – it’s
called “releases\build-preview.”)
To switch to this fork in Git, you will need to execute the following
two commands from an appropriate Git prompt in your enlistment:
Git fetch
Git checkout – track origin/releases/build-preview
Your git repository will now have the contents of the
releases/build-preview branch. Once you’ve done this, you can switch
back and forth between the branches using Git checkout master and git
checkout releases/build-preview. (Details on Git usage are beyond the
scope of this blog; see
http://www.git-scm.com/book/en/Git-Branching-Remote-Branches for more
information on branching in Git.)
Second, you’ll need to disable Visual Studio’s strong-name assembly
checking for the relevant assemblies first. There’s a script to help
with that, which you can find checked into the source code at
Src/Tools/Microsoft.CodeAnalysis.Toolset.Open/Scripts/Prepare.bat.
With all of that done, make your changes. Then, after building, ensure
that CompilerPackage is set as the startup project, and then
F5/Ctrl+F5 to launch a VS instance containing the changes.
Please note that we will never accept pull requests for the release
fork – we need to keep it pristine and accurately reflecting the state
of the code relative to the Roslyn preview bits. Anything you actually
want considered for submission would need to be ported to a fork
created from the master first.
Interesting times ahead. Though I have a certain amount of trepidation about finding myself in a company where they use an entirely customised compiler to do awful, awful things. The gun to shoot yourself in the foot with has just been upgraded...

Related

Specific Requirements for custom Roslyn Code Analyzer to run in live analysis?

I've got a Roslyn based Code Analyzer and Codefix. When directly creating the ReportDiagnostic from an AnalyzerCodeBlock, they would show up in live analysis (Problems in Jetbrains Rider).
However, it needs to parse additional data from the solution to build a dependency tree to make the decision. So now it works like this:
RegisterCompilationStartAction -> then it registers a RegisterCodeBlockStartAction to build a dependency tree
RegisterOperationAction -> Instead of generating the ReportDiagnostic directly, it puts the particular calls into a ConcurrentBag to analyze later.
RegisterCompilationEndAction -> When called, this analyzes the calls from RegisterOperationAction with the dependency tree generated in the RegisterCodeBlockStartAction and generates ReportDiagnostics with the combined information.
Now it only works on build, not in live analysis. I would love to get this back working in live analysis (I have enable solution-wide analysis enabled) since allowing use of the codefixes are incredibly useful.
Any idea of a known reason (like using any CompilationStart-End) this automatically doesn't work in live mode, or is there a way to refactor this into a different structure compatible with live analysis?
CompilationStart isn't a problem. It doesn't cause an analyzer to be build-only. However, CompilationEnd is the problem. They're build only, and also their associated code fixes won't show in the IDE. This is for performance reasons.
Related discussion: https://github.com/dotnet/roslyn/issues/51653

Can a Roslyn Source Generator discover the IDE's spacing/etc preferences?

I'm writing a Roslyn source generator, and as a matter of principle I'd like to make sure the generated source (which is now visible, debuggable, etc) adheres at least somewhat to the user's configuration of tabs vs spaces, brace locations, etc. I don't plan on supporting everything, but the obvious ones: sure.
So; I'm implementing ISourceGenerator and ISyntaxReceiver, which means I have access to the GeneratorInitializationContext, GeneratorExecutionContext and SyntaxNode APIs. However, I cannot find any way to get these IDE settings from here. Is this possible?
This might not even be possible because of the reality that I'm talking about IDE settings and there isn't always an IDE - for example, the user could just be running dotnet build at the command line.
(or perhaps alternatively; is it possible to trigger a "format document" equivalent on the generated code before handing it back to the caller?)
As observed by the conversation, there's no good way to do this (or at least not as of this writing). A generator could try to use the values from an .editorconfig to know the formatting settings if you want to piece it together, but you'd have to write some of that yourself at this point. My suggestion would be until we build in support for this, just don't worry about it, and feel free to direct user complaints to this or the bug.
No matter what, the debugging problem makes things tricky: the file open in the IDE needs to match the file that was produced during the build, since the debugger expects that to line up. The .editorconfig at least means both sides can see the same value.

Output a Roslyn MSBuildWorkspace to different folder

When executing
mSBuildWorkspace.TryApplyChanges(solution);
Visual Studio changes the solution in place. This means that if I want to output to a different location, I need to first copy the whole solution to the requested target and only then work on it. This is error prone as the solution might have relative path links to dependencies, which can break when moving the solution.
So is there a way to tell MSBuildWorkspace to output the changes to a different folder than the source?
There's no built-in support for this.
Option #1: Instead of instead of calling TryApplyChanges you could call Solution.GetChanges to figure out what changed compared to what was originally loaded, and then call the various methods to get the changed documents and apply the edit yourself. This means you're on the hook to actually apply the edits -- source file edits are easy (just write the updated text) but if you care about more complicated things like project changes (adding/removing references) you don't really have a way to leverage MSBuildWorkspace's support for those sorts of things.
Option #2: Roslyn's open source, so you'd have to modify MSBuildWorkspace yourself to allow such a redirection, which would let you potentially try to reuse some of the more complicated logic around project manipulation. Or you can just copy/paste the implementation of the applying, and then use Solution.GetChanges and the reused code.

Perforce branching

I need to make some test changes on app. The app has version control (by Perforce). How to make a branch (from Perforce) that I don't intend on check back in so that I can do some test modification.
It depends on what you mean by not intending to check it back in. Do you mean never, or just not into the main branch?
If you really just want to make some local changes, and then throw them away, without needed any form of version control on the changes themselves, then you don't need to branch at all. Just sync up, check out what you're changing, and then revert the files afterwards. You can even re-sync the files while you're working (resolving conflicts) if you want to check your local changes in the later build. Just don't submit anything, and you're good (just remember that P4 has no backup of your local changes, so if your PC dies and you didn't back it up, tough).
If you want to be able to switch between your local changes and your normal build, you could 'shelve' your changes, which essentially submits them into P4, but keeps them in a changelist rather than having them actually integrated into the main branch. That way you can revert back to the "real" version of the files, and re-sync your own changes again later - possibly even on a different machine. This is a lightweight way of being able to make local changes, while still having a copy on the P4 server without polluting the depot.
If however you want a proper change-tracked branch of your own, you could integrate the version you want to base it on over into a fresh part of the depot, and then use a client-spec which syncs with that while working on it. You are free to integrate between your branches in either direction, whenever you want. You can branch either the whole tree, or just a sub-set of it, using client-specs to sort out which bits go where.
Alternatively the recent versions of P4 have "streams", which are an alterative way of handling your depot, more suited to running multiple development and release branches in parallel. It's probably not what you're looking for.
In terms of exactly how to do these things, I recommend checking out P4's website, which has pretty good documentation and lots of tutorials.
Actually you do not need to create new branch for test your change. Just make a client containing your app and sync your local computer. After that you need to change on specific files or add new or delete by shelve. Then just build your app with shelve. If you find your change at build artifact and if you think that your change is correct then you can submit it to perforce.
The easiest thing is to go to the "steams" tab. Create a new stream and check the check box for branch from where you want to branch from. Super easy.

MSBuild task to get update FileAssemblyVersion for only projects with changes

Is there any way, using msbuild or otherwise, to detect which projects have changes in the current build and update the FileAssemblyVersion attribute in AssemblyInfo.cs for those projects only?
Assuming you've set up incremental [get and] compiles, the next step would be to hook into the MSBuild sequence. Have a look in FrameworkDir\Microsoft.Common.Targets. The problem is that things just are not set up to work in this way - the fact that there are _TimestampBeforeCompile and _TimeStampAfterCompile steps which just show that you cant determine a priori if something is going to compile. While you could theoretically hook in before [the language specific] CoreCompile [e.g., in Microsoft.CSharp.targets], the problem would be that you need to have the same Inputs as it does in order to determine if its going to happen, which would mean lots of cut and pasting and keeping in sync with system files. The other thing to be wary of is noted in the comment at the top of the _ComputeNonExistentFileProperty target.
So, outside of doing some very deep modifications to the sequence (e.g., hooking in a 'post build' bit which forces a second compile if a custom _TimeStampAfterCompile of yours detects that a compilation took place, I'd say there's no easy, recommended or supported way.
Having said that, the AssemblyFileVersion (you refer to FileAssemblyVersion, which doesnt exist :P) is easy to modify after the compile as its just a resource - you'll find tools for that. But I assume you're really talking about doing both it and the AssemblyVersion, which cant be tweaked after the fact in the same way.

Categories