-
Notifications
You must be signed in to change notification settings - Fork 218
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Issue/172 #1110
Issue/172 #1110
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
%comspec% /C "C:\Program Files\Microsoft Visual Studio\2022\Preview\VSSDK\VisualStudioIntegration\Tools\Bin\CreateExpInstance.exe" /Reset /VSInstance=17.0_56947084 /RootSuffix=Roslyn && PAUSE |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
using System; | ||
using System.Collections.Immutable; | ||
using System.IO; | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Text.RegularExpressions; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using Microsoft.AspNetCore.Razor.Language; | ||
using Microsoft.CodeAnalysis; | ||
using Xunit; | ||
|
||
|
||
namespace ICSharpCode.CodeConverter.Tests.CSharp; | ||
|
||
public class SpikeTests | ||
{ | ||
|
||
[Fact] | ||
public async Task ConvertRazorFileAsync() | ||
{ | ||
var codeDocument = GetCodeDocument(""" | ||
@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>@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> | ||
|
||
""", "anything.vbhtml"); | ||
|
||
var syntaxTree = codeDocument.GetSyntaxTree(); | ||
var getRoot = syntaxTree.GetType().GetProperty("Root", BindingFlags.Instance | BindingFlags.NonPublic).GetMethod; | ||
var root = getRoot.Invoke(syntaxTree, BindingFlags.Instance | BindingFlags.NonPublic, null, null, null); | ||
var getDocument = root.GetType().GetProperty("Document", BindingFlags.Instance | BindingFlags.Public).GetMethod; | ||
var document = getDocument.Invoke(root, BindingFlags.Instance | BindingFlags.NonPublic, null, null, null); | ||
var getChildren = document.GetType().GetProperty("Children", BindingFlags.Instance | BindingFlags.Public).GetMethod; | ||
var children = getChildren.Invoke(document, BindingFlags.Instance | BindingFlags.NonPublic, null, null, null); | ||
|
||
|
||
} | ||
|
||
[UnsafeAccessor(UnsafeAccessorKind.Method)] | ||
private static extern object get_Root(RazorSyntaxTree codeDocument); | ||
|
||
|
||
private RazorCodeDocument GetCodeDocument(string source, string filePath) | ||
{ | ||
var taghelper = TagHelperDescriptorBuilder.Create("TestTagHelper", "TestAssembly") | ||
//.BoundAttributeDescriptor(attr => attr.Name("show").TypeName("System.Boolean")) | ||
//.BoundAttributeDescriptor(attr => attr.Name("id").TypeName("System.Int32")) | ||
//.TagMatchingRuleDescriptor(rule => rule.RequireTagName("taghelper")) | ||
//.Metadata(TypeName("TestTagHelper")) | ||
.Build(); | ||
|
||
var engine = CreateProjectEngine(_ => { | ||
//return builder.Features.Add(new VisualStudioEnableTagHelpersFeature()); | ||
} | ||
); | ||
|
||
var sourceDocument = TestRazorSourceDocument.Create(source, normalizeNewLines: true); | ||
var importDocument = TestRazorSourceDocument.Create("@addTagHelper *, TestAssembly", filePath: filePath, relativePath: filePath); | ||
|
||
var codeDocument = engine.ProcessDesignTime(sourceDocument, FileKinds.Legacy, importSources: ImmutableArray.Create(importDocument), new[] { taghelper }); | ||
return codeDocument; | ||
//return RazorWrapperFactory.WrapCodeDocument(codeDocument); | ||
} | ||
protected RazorProjectEngine CreateProjectEngine(Action<RazorProjectEngineBuilder> configure) | ||
{ | ||
return RazorProjectEngine.Create(RazorConfiguration.Default, RazorProjectFileSystem.Create("c:\\tmp"), configure); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. May need an older version of the library to parse vbhtml, or just to tweak the settings here. If it's an older version, would need to check we're allowed to redistribute it, but it would solve any brittleness issues since it won't change. I couldn't see a version on nuget that event references visualbasic though so maybe this library wouldn't work: https://www.nuget.org/packages/Microsoft.CodeAnalysis.Razor/2.0.0#dependencies-body-tab I suspect there's some similar code somewhere for VB that's callable, but not sure where |
||
} | ||
} | ||
|
||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
#nullable disable | ||
|
||
|
||
public static class TestRazorSourceDocument | ||
{ | ||
|
||
public static MemoryStream CreateStreamContent(string content = "Hello, World!", Encoding encoding = null, bool normalizeNewLines = false) | ||
{ | ||
var stream = new MemoryStream(); | ||
encoding ??= Encoding.UTF8; | ||
using (var writer = new StreamWriter(stream, encoding, bufferSize: 1024, leaveOpen: true)) { | ||
if (normalizeNewLines) { | ||
content = NormalizeNewLines(content); | ||
} | ||
|
||
writer.Write(content); | ||
} | ||
|
||
stream.Seek(0L, SeekOrigin.Begin); | ||
|
||
return stream; | ||
} | ||
|
||
public static RazorSourceDocument Create( | ||
string content = "Hello, world!", | ||
Encoding encoding = null, | ||
bool normalizeNewLines = false, | ||
string filePath = "test.cshtml", | ||
string relativePath = "test.cshtml") | ||
{ | ||
if (normalizeNewLines) { | ||
content = NormalizeNewLines(content); | ||
} | ||
|
||
var properties = new RazorSourceDocumentProperties(filePath, relativePath); | ||
return RazorSourceDocument.Create(content, encoding ?? Encoding.UTF8, properties); | ||
} | ||
|
||
public static RazorSourceDocument Create( | ||
string content, | ||
RazorSourceDocumentProperties properties, | ||
Encoding encoding = null, | ||
bool normalizeNewLines = false) | ||
{ | ||
if (normalizeNewLines) { | ||
content = NormalizeNewLines(content); | ||
} | ||
|
||
return RazorSourceDocument.Create(content, encoding ?? Encoding.UTF8, properties); | ||
} | ||
|
||
private static string NormalizeNewLines(string content) | ||
{ | ||
return Regex.Replace(content, "(?<!\r)\n", "\r\n", RegexOptions.None, TimeSpan.FromSeconds(10)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -308,7 +308,8 @@ private async IAsyncEnumerable<ConversionResult> ConvertProjectUnhandledAsync<TL | |
var projectsByPath = | ||
_visualStudioWorkspace.CurrentSolution.Projects.ToLookup(p => p.FilePath, p => p); | ||
#pragma warning disable VSTHRD010 // Invoke single-threaded types on Main thread - ToList ensures this happens within the same thread just switched to above | ||
var projects = selectedProjects.Select(p => projectsByPath[p.FullName].First()).ToList(); | ||
var projects = selectedProjects.SelectMany(p => projectsByPath[p.FullName]).ToList(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was the initial spike that allowed getting the project that's created for the open editor. I didn't pursue this since even with the faff of needing the windows open, it didn't seem to easily have access to the mapped spans to insert the code back into the original vbhtml file from the generated file |
||
|
||
#pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread | ||
await TaskScheduler.Default; | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm pretty sure everything needed is in here, but it will take a lot of brittle reflection calls to internal methods to put it together.
Ultimately, need to get a vb syntaxtree for the whole file, and be able to map each code block back to the vbhtml so we can insert the relevant cs there at the end of conversion.