From 18e15bf2b1cdc47165a4ee50ad97bf5a44e7cf8b Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Fri, 14 Jun 2024 23:29:48 +0100 Subject: [PATCH 1/3] Batch to restore broken instance --- ResetRoslynInstance.bat | 1 + 1 file changed, 1 insertion(+) create mode 100644 ResetRoslynInstance.bat diff --git a/ResetRoslynInstance.bat b/ResetRoslynInstance.bat new file mode 100644 index 00000000..bdf4a1fa --- /dev/null +++ b/ResetRoslynInstance.bat @@ -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 \ No newline at end of file From 5dfc31cdd3585b8ef659aa77d38dffb137bb76b1 Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Jun 2024 00:53:27 +0100 Subject: [PATCH 2/3] Temp: Pass through all - this may overwrite and repeat other boilerplate files --- Vsix/CodeConversion.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Vsix/CodeConversion.cs b/Vsix/CodeConversion.cs index b7ac11d7..80af6686 100644 --- a/Vsix/CodeConversion.cs +++ b/Vsix/CodeConversion.cs @@ -308,7 +308,8 @@ private async IAsyncEnumerable ConvertProjectUnhandledAsync 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(); + #pragma warning restore VSTHRD010 // Invoke single-threaded types on Main thread await TaskScheduler.Default; From 3dfab6f06d7e29ec242bf0fadeb939f103870a4f Mon Sep 17 00:00:00 2001 From: GrahamTheCoder Date: Sat, 15 Jun 2024 19:11:27 +0100 Subject: [PATCH 3/3] Spike - get access to RazorSyntaxNode which contains spans for html and vb/cs --- CodeConverter/CodeConverter.csproj | 1 + Tests/CSharp/SelfVerifyingTests.cs | 2 +- Tests/CSharp/SpikeTests.cs | 145 ++++++++++++++++++ .../ProjectFileTextEditorTests.cs | 3 +- Tests/TestConstants.cs | 4 +- Tests/TestRunners/TestFileRewriter.cs | 2 +- Tests/Tests.csproj | 3 +- Tests/VB/SelfVerifyingTests.cs | 2 +- Tests/VB/StandaloneStatementTests.cs | 1 - 9 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 Tests/CSharp/SpikeTests.cs diff --git a/CodeConverter/CodeConverter.csproj b/CodeConverter/CodeConverter.csproj index 80642c84..415d399d 100644 --- a/CodeConverter/CodeConverter.csproj +++ b/CodeConverter/CodeConverter.csproj @@ -38,6 +38,7 @@ + diff --git a/Tests/CSharp/SelfVerifyingTests.cs b/Tests/CSharp/SelfVerifyingTests.cs index 6e182f56..edcf2458 100644 --- a/Tests/CSharp/SelfVerifyingTests.cs +++ b/Tests/CSharp/SelfVerifyingTests.cs @@ -15,7 +15,7 @@ namespace ICSharpCode.CodeConverter.Tests.CSharp; /// public class SelfVerifyingTests { - [Theory, MemberData(nameof(GetVisualBasicToCSharpTestData))] + //[Theory, MemberData(nameof(GetVisualBasicToCSharpTestData))] public async Task VisualBasicToCSharpAsync(NamedTest verifyConvertedTestPasses) { await verifyConvertedTestPasses.Execute(); diff --git a/Tests/CSharp/SpikeTests.cs b/Tests/CSharp/SpikeTests.cs new file mode 100644 index 00000000..16ce1510 --- /dev/null +++ b/Tests/CSharp/SpikeTests.cs @@ -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 + +
+

@ViewData("Title").

@ViewData("Title2").

+

@ViewData("Message")

+ +

Use this area to provide additional information.

+
@Code + ViewData("Title") = "About" & CStr(1) + End Code + +
+

@ViewData("Title").

@ViewData("Title2").

+

@ViewData("Message")

+ +

Use this area to provide additional information.

+
+ + """, "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 configure) + { + return RazorProjectEngine.Create(RazorConfiguration.Default, RazorProjectFileSystem.Create("c:\\tmp"), configure); + } +} + +// 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, "(? GetTestFileContents() private static string GetTestSourceDirectoryPath() { - string assemblyDir = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().CodeBase).AbsolutePath); + string assemblyDir = Path.GetDirectoryName(new Uri(Assembly.GetExecutingAssembly().Location).AbsolutePath); string testSourceDirectoryPath = Path.Combine(assemblyDir, @"..\..\"); return testSourceDirectoryPath; } diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 01aef701..2628cf2e 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,12 +1,13 @@  - net472 + net8.0 Library ICSharpCode.CodeConverter.Tests ICSharpCode.CodeConverter.Tests true true true + latest diff --git a/Tests/VB/SelfVerifyingTests.cs b/Tests/VB/SelfVerifyingTests.cs index a8dd93ad..e9bed486 100644 --- a/Tests/VB/SelfVerifyingTests.cs +++ b/Tests/VB/SelfVerifyingTests.cs @@ -15,7 +15,7 @@ namespace ICSharpCode.CodeConverter.Tests.VB; /// public class SelfVerifyingTests { - [Theory, MemberData(nameof(GetCSharpToVisualBasicTestData))] + //[Theory, MemberData(nameof(GetCSharpToVisualBasicTestData))] public async Task VisualBasicToCSharpAsync(NamedTest verifyConvertedTestPasses) { await verifyConvertedTestPasses.Execute(); diff --git a/Tests/VB/StandaloneStatementTests.cs b/Tests/VB/StandaloneStatementTests.cs index 9baf185c..76064a77 100644 --- a/Tests/VB/StandaloneStatementTests.cs +++ b/Tests/VB/StandaloneStatementTests.cs @@ -1,5 +1,4 @@ using System.Threading.Tasks; -using System.Windows.Forms; using ICSharpCode.CodeConverter.Tests.TestRunners; using Xunit;