Skip to content
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

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CodeConverter/CodeConverter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="4.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.1.0" />
<PackageReference Include="Microsoft.CodeAnalysis.Razor" Version="6.0.31" />
<PackageReference Include="Microsoft.CodeAnalysis.VisualBasic.Workspaces" Version="4.1.0" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0">
Expand Down
1 change: 1 addition & 0 deletions ResetRoslynInstance.bat
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
2 changes: 1 addition & 1 deletion Tests/CSharp/SelfVerifyingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ICSharpCode.CodeConverter.Tests.CSharp;
/// </summary>
public class SelfVerifyingTests
{
[Theory, MemberData(nameof(GetVisualBasicToCSharpTestData))]
//[Theory, MemberData(nameof(GetVisualBasicToCSharpTestData))]
public async Task VisualBasicToCSharpAsync(NamedTest verifyConvertedTestPasses)
{
await verifyConvertedTestPasses.Execute();
Expand Down
145 changes: 145 additions & 0 deletions Tests/CSharp/SpikeTests.cs
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);
Copy link
Member Author

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.



}

[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);
Copy link
Member Author

@GrahamTheCoder GrahamTheCoder Jul 6, 2024

Choose a reason for hiding this comment

The 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));
}
}
3 changes: 1 addition & 2 deletions Tests/LanguageAgnostic/ProjectFileTextEditorTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Web.UI.WebControls;
using System.Xml.Linq;
using System.Xml.Linq;
using System;
using ICSharpCode.CodeConverter.Common;
using Xunit;
Expand Down
4 changes: 2 additions & 2 deletions Tests/TestConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ public static class TestConstants
public static string GetTestDataDirectory()
{
var assembly = Assembly.GetExecutingAssembly();
var solutionDir = new FileInfo(new Uri(assembly.CodeBase).LocalPath).Directory?.Parent?.Parent ??
throw new InvalidOperationException(assembly.CodeBase);
var solutionDir = new FileInfo(new Uri(assembly.Location).LocalPath).Directory?.Parent?.Parent ??
throw new InvalidOperationException(assembly.Location);
return Path.Combine(solutionDir.FullName, "TestData");
}
}
2 changes: 1 addition & 1 deletion Tests/TestRunners/TestFileRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ private static Dictionary<string, string> 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;
}
Expand Down
3 changes: 2 additions & 1 deletion Tests/Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net472</TargetFramework>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
<AssemblyName>ICSharpCode.CodeConverter.Tests</AssemblyName>
<RootNamespace>ICSharpCode.CodeConverter.Tests</RootNamespace>
<DisableMSBuildAssemblyCopyCheck>true</DisableMSBuildAssemblyCopyCheck>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Moq" Version="4.18.3" />
Expand Down
2 changes: 1 addition & 1 deletion Tests/VB/SelfVerifyingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace ICSharpCode.CodeConverter.Tests.VB;
/// </summary>
public class SelfVerifyingTests
{
[Theory, MemberData(nameof(GetCSharpToVisualBasicTestData))]
//[Theory, MemberData(nameof(GetCSharpToVisualBasicTestData))]
public async Task VisualBasicToCSharpAsync(NamedTest verifyConvertedTestPasses)
{
await verifyConvertedTestPasses.Execute();
Expand Down
1 change: 0 additions & 1 deletion Tests/VB/StandaloneStatementTests.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Threading.Tasks;
using System.Windows.Forms;
using ICSharpCode.CodeConverter.Tests.TestRunners;
using Xunit;

Expand Down
3 changes: 2 additions & 1 deletion Vsix/CodeConversion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Copy link
Member Author

Choose a reason for hiding this comment

The 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;

Expand Down
Loading