CodeConverter
CodeConverter copied to clipboard
Convert ASP.NET (+core) cshtml/vbhtml files
Related info for aspx is probably relevant here: https://github.com/icsharpcode/CodeConverter/issues/175
May be necessary to use things like
- https://docs.microsoft.com/en-us/dotnet/api/system.web.compilation.buildprovider?redirectedfrom=MSDN&view=netframework-4.7.2,
- https://github.com/dotnet/roslyn/issues/11324#issuecomment-263020905 to get the syntax tree, or may already be in the syntax trees and just need special treatment.
Out of scope: ASP Net Classic will not be supported
Background
For each file that currently has an open editor, we receive a whole project object (same file path as the one containing the vbhtml) with a bit of boilerplate and then a projection of each code block in the vbhtml
e.g. About.vbhtml
@Code
ViewData("Title") = "About" & CStr(1)
End Code
<main aria-labelledby="title">
<h2 id="title">@ViewData("Title").</h2><h3 id="title">@ViewData("Title2").</h3>
<h3>@ViewData("Message")</h3>
<p>Use this area to provide additional information.</p>
</main>
About.vbhtml.__projection.g.vb:
#ExternalSource("C:\Users\gph77\source\repos\CodeConverterTests\ExampleVbHtml\Views\Home\About.vbhtml",1)
Me.ViewData("Title") = "About" & CStr(1)
#End ExternalSource
#ExternalSource("C:\Users\gph77\source\repos\CodeConverterTests\ExampleVbHtml\Views\Home\About.vbhtml",2)
Global.ASP._Page_Views_Home_About_vbhtml.__o = Me.ViewData("Title")
#End ExternalSource
#ExternalSource("C:\Users\gph77\source\repos\CodeConverterTests\ExampleVbHtml\Views\Home\About.vbhtml",3)
Global.ASP._Page_Views_Home_About_vbhtml.__o = Me.ViewData("Title2")
#End ExternalSource
#ExternalSource("C:\Users\gph77\source\repos\CodeConverterTests\ExampleVbHtml\Views\Home\About.vbhtml",4)
Global.ASP._Page_Views_Home_About_vbhtml.__o = Me.ViewData("Message")
So we need:
- A method to get the syntax tree (even if it's as hacky as code to open a bunch of editor windows...but preferably not all at once)
- Using the mechanism the dotnet build process uses to get all the vbhtml projects would be much preferable to forcing editors to open! Most promising: RazorSourceDocument.Create, RazoreCodeDocument.Create, then try to get a syntax tree and visit things like RazorDirectiveSyntax
- A method to identify code blocks in the vbhtml and create a version with each part of the converted code overwriting it
- Rather than try to parse vbhtml to find the code blocks, use an existing service which must exist in order to create the projected vb file in the first place. Best lead: Get document's ISpanMappingService - though document.Services and the interface are internal, as is IRazorSpanMappingService, IRazorDocumentMappingService
- Nice to have: To update any file name references like:
Layout = "~/Views/Shared/_Layout.vbhtml"
- Visual Studio has code to parse these and know they are paths in the project since ctrl+click goes to them. That code may well be closed source
Using internals
Given a bunch of internal interfaces, this may be a good time to try out the new way of accessing such things (with appropriate guards of course): https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.unsafeaccessorattribute?view=net-8.0#examples
Side note
There's a snippet here which tells us how we should be getting the right one of these projects normally (currently it just grabs the first!) https://github.com/dotnet/roslyn/blob/e102ec27b9a89b4ee462f93bcd3295a66c439329/src/VisualStudio/Core/Def/Implementation/HierarchyItemToProjectIdMap.cs#L76-L87
This solution could probably also cover https://github.com/icsharpcode/CodeConverter/issues/219