add razor file syntax highlighting
This commit is contained in:
@@ -16,6 +16,8 @@ csharp_space_after_cast = true
|
||||
csharp_space_before_colon_in_inheritance_clause = true
|
||||
csharp_space_after_colon_in_inheritance_clause = true
|
||||
csharp_place_attribute_on_same_line = false
|
||||
dotnet_analyzer_diagnostic.category-ApiDesign.severity = none
|
||||
dotnet_analyzer_diagnostic.category-RoslynDiagnosticsMaintainability.severity = suggestion
|
||||
|
||||
[*.csproj]
|
||||
indent_style = space
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
<PropertyGroup>
|
||||
<!-- <TreatWarningsAsErrors Condition="'$(Configuration)' != 'Debug'">true</TreatWarningsAsErrors>-->
|
||||
<UseArtifactsOutput>true</UseArtifactsOutput>
|
||||
<Features>$(Features);use-roslyn-tokenizer=true</Features> <!-- idk if this does anything lol -->
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
|
||||
47
Directory.Packages.props
Normal file
47
Directory.Packages.props
Normal file
@@ -0,0 +1,47 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
|
||||
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="Ardalis.GuardClauses" Version="5.0.0" />
|
||||
<PackageVersion Include="AsyncReadProcess" Version="1.0.0-preview15" />
|
||||
<PackageVersion Include="BenchmarkDotNet" Version="0.15.2" />
|
||||
<PackageVersion Include="BlazorMonaco" Version="3.3.0" />
|
||||
<PackageVersion Include="CliWrap" Version="3.9.0" />
|
||||
<PackageVersion Include="ClrDebug" Version="0.3.4" />
|
||||
<PackageVersion Include="Krafs.Publicizer" Version="2.3.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components" Version="10.0.0-rc.1.25451.107" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Components.WebView" Version="10.0.0-rc.1.25451.107" />
|
||||
<PackageVersion Include="Microsoft.Build" Version="17.15.0-preview-25462-116" />
|
||||
<PackageVersion Include="Microsoft.Build.Framework" Version="17.15.0-preview-25462-116" />
|
||||
<PackageVersion Include="Microsoft.Build.Locator" Version="1.9.1" />
|
||||
<PackageVersion Include="Microsoft.Build.Tasks.Core" Version="17.15.0-preview-25462-116" />
|
||||
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.15.0-preview-25462-116" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Features" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.AspNetCore.Razor.Utilities.Shared" Version="10.0.0-preview.25429.2" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Features" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Razor.Compiler" Version="10.0.0-preview.25429.2" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Razor.Workspaces" Version="10.0.0-preview.25429.2" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="5.0.0-2.25462.116" />
|
||||
<PackageVersion Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.645901" />
|
||||
<PackageVersion Include="Microsoft.DotNet.Arcade.Sdk" Version="9.0.0-beta.24372.7" />
|
||||
<PackageVersion Include="Microsoft.Net.Compilers.Razor.Toolset" Version="10.0.0-preview.25429.2" />
|
||||
<PackageVersion Include="Microsoft.VisualStudio.Shared.VSCodeDebugProtocol" Version="18.0.10427.1" />
|
||||
<PackageVersion Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.52" />
|
||||
<PackageVersion Include="MudBlazor" Version="8.12.0" />
|
||||
<PackageVersion Include="NuGet.Protocol" Version="7.0.0-preview.1.46008" />
|
||||
<PackageVersion Include="ObservableCollections" Version="3.3.4" />
|
||||
<PackageVersion Include="ObservableCollections.R3" Version="3.3.4" />
|
||||
<PackageVersion Include="Photino.Blazor" Version="4.0.13" />
|
||||
<PackageVersion Include="R3" Version="1.3.0" />
|
||||
<PackageVersion Include="XtermBlazor" Version="2.1.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Pinned Transitive Dependencies">
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.ExternalAccess.Razor.Features" Version="5.0.0-2.25462.116" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -22,31 +22,74 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{B6835010
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Roslyn.Benchmarks", "tests\Roslyn.Benchmarks\Roslyn.Benchmarks.csproj", "{252CE098-2F9A-4DA3-A172-EE1167B335BF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpIDE.RazorAccess", "src\SharpIDE.RazorAccess\SharpIDE.RazorAccess.csproj", "{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4}.Release|x86.Build.0 = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|x64.Build.0 = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF}.Release|x86.Build.0 = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|x64.Build.0 = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{E35167E1-0FF4-4194-97A8-CC95EDA224CD} = {F4ED837F-888A-4D01-BCED-C360B9CE0865}
|
||||
{D7D5D39E-DA3A-4B10-8F40-B07B769347F4} = {F4ED837F-888A-4D01-BCED-C360B9CE0865}
|
||||
{252CE098-2F9A-4DA3-A172-EE1167B335BF} = {B6835010-35FA-4C74-AB48-009FB923185D}
|
||||
{0DE5B721-4C17-4A93-A94B-5DEA9CAAAE99} = {F4ED837F-888A-4D01-BCED-C360B9CE0865}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -6,5 +6,7 @@
|
||||
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
|
||||
<add key="localnugettest" value="C:\Users\Matthew\AppData\Roaming\LocalNuget" />
|
||||
<add key="roslyn-compiler" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
|
||||
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
|
||||
<add key="ide-services" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json" />
|
||||
</packageSources>
|
||||
</configuration>
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using Ardalis.GuardClauses;
|
||||
using Microsoft.CodeAnalysis;
|
||||
@@ -12,9 +11,9 @@ using Microsoft.CodeAnalysis.Host.Mef;
|
||||
using Microsoft.CodeAnalysis.MSBuild;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using NuGet.Packaging;
|
||||
using ObservableCollections;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
using SharpIDE.RazorAccess;
|
||||
|
||||
namespace SharpIDE.Application.Features.Analysis;
|
||||
|
||||
@@ -137,7 +136,8 @@ public static class RoslynAnalysis
|
||||
await _solutionLoadedTcs.Task;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath);
|
||||
var document = project.Documents.Single(s => s.FilePath == fileModel.Path);
|
||||
var document = project.Documents.SingleOrDefault(s => s.FilePath == fileModel.Path);
|
||||
if (document is null) return [];
|
||||
//var document = _workspace!.CurrentSolution.GetDocument(fileModel.Path);
|
||||
Guard.Against.Null(document, nameof(document));
|
||||
|
||||
@@ -150,11 +150,80 @@ public static class RoslynAnalysis
|
||||
return result;
|
||||
}
|
||||
|
||||
public record SharpIdeRazorMappedClassifiedSpan(SharpIdeRazorSourceSpan SourceSpanInRazor, string CsharpClassificationType);
|
||||
public static async Task<IEnumerable<SharpIdeRazorClassifiedSpan>> GetRazorDocumentSyntaxHighlighting(SharpIdeFile fileModel)
|
||||
{
|
||||
await _solutionLoadedTcs.Task;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var sharpIdeProjectModel = ((IChildSharpIdeNode) fileModel).GetNearestProjectNode()!;
|
||||
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == sharpIdeProjectModel!.FilePath);
|
||||
if (!fileModel.Name.EndsWith(".razor", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return [];
|
||||
//throw new InvalidOperationException("File is not a .razor file");
|
||||
}
|
||||
|
||||
var importsFile = sharpIdeProjectModel.Files.Single(s => s.Name.Equals("_Imports.razor", StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
var razorDocument = project.AdditionalDocuments.Single(s => s.FilePath == fileModel.Path);
|
||||
var importsDocument = project.AdditionalDocuments.Single(s => s.FilePath == importsFile.Path);
|
||||
|
||||
var razorText = await razorDocument.GetTextAsync(cancellationToken);
|
||||
var importsText = await importsDocument.GetTextAsync(cancellationToken);
|
||||
var (razorSpans, razorGeneratedSourceText, sourceMappings) = RazorAccessors.GetClassifiedSpans(razorText, importsText, razorDocument.FilePath!, Path.GetDirectoryName(project.FilePath!)!);
|
||||
|
||||
var razorGeneratedDocument = project.AddDocument(fileModel.Name + ".g.cs", razorGeneratedSourceText);
|
||||
var razorSyntaxTree = await razorGeneratedDocument.GetSyntaxTreeAsync(cancellationToken);
|
||||
var razorSyntaxRoot = await razorSyntaxTree!.GetRootAsync(cancellationToken);
|
||||
var classifiedSpans = await Classifier.GetClassifiedSpansAsync(razorGeneratedDocument, razorSyntaxRoot.FullSpan, cancellationToken);
|
||||
var roslynMappedSpans = classifiedSpans.Select(s =>
|
||||
{
|
||||
var genSpan = s.TextSpan;
|
||||
var mapping = sourceMappings.SingleOrDefault(m => m.GeneratedSpan.AsTextSpan().IntersectsWith(genSpan));
|
||||
if (mapping != null)
|
||||
{
|
||||
// Translate generated span back to Razor span
|
||||
var offset = genSpan.Start - mapping.GeneratedSpan.AbsoluteIndex;
|
||||
var mappedStart = mapping.OriginalSpan.AbsoluteIndex + offset;
|
||||
var mappedSpan = new TextSpan(mappedStart, genSpan.Length);
|
||||
var sharpIdeSpan = new SharpIdeRazorSourceSpan(
|
||||
mapping.OriginalSpan.FilePath,
|
||||
mappedSpan.Start,
|
||||
razorText.Lines.GetLineFromPosition(mappedSpan.Start).LineNumber,
|
||||
mappedSpan.Start - razorText.Lines.GetLineFromPosition(mappedSpan.Start).Start,
|
||||
mappedSpan.Length,
|
||||
1,
|
||||
mappedSpan.Start - razorText.Lines.GetLineFromPosition(mappedSpan.Start).Start + mappedSpan.Length
|
||||
);
|
||||
|
||||
return new SharpIdeRazorMappedClassifiedSpan(
|
||||
sharpIdeSpan,
|
||||
s.ClassificationType
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}).Where(s => s is not null).ToList();
|
||||
|
||||
razorSpans = [..razorSpans.Where(s => s.Kind is not SharpIdeRazorSpanKind.Code), ..roslynMappedSpans
|
||||
.Select(s => new SharpIdeRazorClassifiedSpan(s!.SourceSpanInRazor, SharpIdeRazorSpanKind.Code, s.CsharpClassificationType))
|
||||
];
|
||||
razorSpans = razorSpans.OrderBy(s => s.Span.AbsoluteIndex).ToImmutableArray();
|
||||
|
||||
return razorSpans;
|
||||
}
|
||||
|
||||
public static async Task<IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)>> GetDocumentSyntaxHighlighting(SharpIdeFile fileModel)
|
||||
{
|
||||
await _solutionLoadedTcs.Task;
|
||||
var cancellationToken = CancellationToken.None;
|
||||
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath);
|
||||
if (fileModel.Name.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) is false)
|
||||
{
|
||||
//throw new InvalidOperationException("File is not a .cs");
|
||||
return [];
|
||||
}
|
||||
|
||||
var document = project.Documents.Single(s => s.FilePath == fileModel.Path);
|
||||
Guard.Against.Null(document, nameof(document));
|
||||
|
||||
@@ -300,11 +369,18 @@ public static class RoslynAnalysis
|
||||
Guard.Against.NullOrEmpty(newContent, nameof(newContent));
|
||||
|
||||
var project = _workspace!.CurrentSolution.Projects.Single(s => s.FilePath == ((IChildSharpIdeNode)fileModel).GetNearestProjectNode()!.FilePath);
|
||||
var document = project.Documents.Single(s => s.FilePath == fileModel.Path);
|
||||
Guard.Against.Null(document, nameof(document));
|
||||
|
||||
//var updatedDocument = document.WithText(SourceText.From(newContent));
|
||||
var newSolution = _workspace.CurrentSolution.WithDocumentText(document.Id, SourceText.From(newContent));
|
||||
_workspace.TryApplyChanges(newSolution);
|
||||
if (fileModel.IsRazorFile)
|
||||
{
|
||||
var razorDocument = project.AdditionalDocuments.Single(s => s.FilePath == fileModel.Path);
|
||||
var newSolution = _workspace.CurrentSolution.WithAdditionalDocumentText(razorDocument.Id, SourceText.From(newContent));
|
||||
_workspace.TryApplyChanges(newSolution);
|
||||
}
|
||||
else
|
||||
{
|
||||
var document = project.Documents.Single(s => s.FilePath == fileModel.Path);
|
||||
Guard.Against.Null(document, nameof(document));
|
||||
var newSolution = _workspace.CurrentSolution.WithDocumentText(document.Id, SourceText.From(newContent));
|
||||
_workspace.TryApplyChanges(newSolution);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ public class SharpIdeFile : ISharpIdeNode, IChildSharpIdeNode
|
||||
public required IExpandableSharpIdeNode Parent { get; set; }
|
||||
public required string Path { get; set; }
|
||||
public required string Name { get; set; }
|
||||
public bool IsRazorFile => Path.EndsWith(".razor", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
[SetsRequiredMembers]
|
||||
internal SharpIdeFile(string fullPath, string name, IExpandableSharpIdeNode parent, ConcurrentBag<SharpIdeFile> allFiles)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
@@ -8,22 +8,26 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" Version="0.2.645901" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shared.VSCodeDebugProtocol" Version="18.0.10427.1" />
|
||||
<PackageReference Include="Microsoft.Diagnostics.NETCore.Client" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Shared.VSCodeDebugProtocol" />
|
||||
<!-- If any Microsoft.Build.*.dll (Excluding Locator) ends up in the output, it will be prioritised for loading by MSBuild Nodes -->
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="5.0.0" />
|
||||
<PackageReference Include="AsyncReadProcess" Version="1.0.0-preview15" />
|
||||
<PackageReference Include="Microsoft.Build" Version="17.15.0-preview-25459-108" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" Version="17.15.0-preview-25459-108" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Locator" Version="1.9.1" />
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" Version="17.15.0-preview-25459-108" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" Version="17.15.0-preview-25459-108" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" Version="5.0.0-2.25459.108" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="5.0.0-2.25459.108" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Features" Version="5.0.0-2.25459.108" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="5.0.0-2.25459.108" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.SolutionPersistence" Version="1.0.52" />
|
||||
<PackageReference Include="NuGet.Protocol" Version="7.0.0-preview.1.46008" />
|
||||
<PackageReference Include="ObservableCollections" Version="3.3.4" />
|
||||
<PackageReference Include="Ardalis.GuardClauses" />
|
||||
<PackageReference Include="AsyncReadProcess" />
|
||||
<PackageReference Include="Microsoft.Build" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Framework" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Locator" />
|
||||
<PackageReference Include="Microsoft.Build.Tasks.Core" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.Build.Utilities.Core" ExcludeAssets="runtime" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Features" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Features" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" PrivateAssets="all" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.SolutionPersistence" />
|
||||
<PackageReference Include="NuGet.Protocol" />
|
||||
<PackageReference Include="ObservableCollections" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharpIDE.RazorAccess\SharpIDE.RazorAccess.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -2,20 +2,85 @@
|
||||
using Godot.Collections;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Classification;
|
||||
using SharpIDE.RazorAccess;
|
||||
|
||||
namespace SharpIDE.Godot;
|
||||
|
||||
public partial class CustomHighlighter : SyntaxHighlighter
|
||||
{
|
||||
public IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> ClassifiedSpans = [];
|
||||
private readonly Dictionary _emptyDict = new();
|
||||
public HashSet<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> ClassifiedSpans = [];
|
||||
public HashSet<SharpIdeRazorClassifiedSpan> RazorClassifiedSpans = [];
|
||||
public override Dictionary _GetLineSyntaxHighlighting(int line)
|
||||
{
|
||||
var highlights = MapClassifiedSpansToHighlights(line);
|
||||
var highlights = (ClassifiedSpans, RazorClassifiedSpans) switch
|
||||
{
|
||||
({ Count: 0 }, { Count: 0 }) => _emptyDict,
|
||||
({ Count: > 0 }, _) => MapClassifiedSpansToHighlights(line),
|
||||
(_, { Count: > 0 }) => MapRazorClassifiedSpansToHighlights(line),
|
||||
_ => throw new NotImplementedException("Both ClassifiedSpans and RazorClassifiedSpans are set. This is not supported yet.")
|
||||
};
|
||||
|
||||
return highlights;
|
||||
}
|
||||
|
||||
private static readonly StringName ColorStringName = "color";
|
||||
private Dictionary MapRazorClassifiedSpansToHighlights(int line)
|
||||
{
|
||||
var highlights = new Dictionary();
|
||||
|
||||
// Filter spans on the given line, ignore empty spans
|
||||
var spansForLine = RazorClassifiedSpans
|
||||
.Where(s => s.Span.LineIndex == line && s.Span.Length is not 0)
|
||||
.GroupBy(s => s.Span)
|
||||
.ToList();
|
||||
|
||||
foreach (var razorSpanGrouping in spansForLine)
|
||||
{
|
||||
var spans = razorSpanGrouping.ToList();
|
||||
if (spans.Count > 2) throw new NotImplementedException("More than 2 classified spans is not supported yet.");
|
||||
if (spans.Count is not 1)
|
||||
{
|
||||
if (spans.Any(s => s.Kind is SharpIdeRazorSpanKind.Code))
|
||||
{
|
||||
spans = spans.Where(s => s.Kind is SharpIdeRazorSpanKind.Code).ToList();
|
||||
}
|
||||
if (spans.Count is not 1)
|
||||
{
|
||||
SharpIdeRazorClassifiedSpan? staticClassifiedSpan = spans.FirstOrDefault(s => s.CodeClassificationType == ClassificationTypeNames.StaticSymbol);
|
||||
if (staticClassifiedSpan is not null) spans.Remove(staticClassifiedSpan.Value);
|
||||
}
|
||||
}
|
||||
var razorSpan = spans.Single();
|
||||
|
||||
int columnIndex = razorSpan.Span.CharacterIndex;
|
||||
|
||||
var highlightInfo = new Dictionary
|
||||
{
|
||||
{ ColorStringName, GetColorForRazorSpanKind(razorSpan.Kind, razorSpan.CodeClassificationType) }
|
||||
};
|
||||
|
||||
highlights[columnIndex] = highlightInfo;
|
||||
}
|
||||
|
||||
return highlights;
|
||||
}
|
||||
|
||||
private static Color GetColorForRazorSpanKind(SharpIdeRazorSpanKind kind, string? codeClassificationType)
|
||||
{
|
||||
return kind switch
|
||||
{
|
||||
SharpIdeRazorSpanKind.Code => GetColorForClassification(codeClassificationType!),
|
||||
SharpIdeRazorSpanKind.Comment => new Color("57a64a"), // green
|
||||
SharpIdeRazorSpanKind.MetaCode => new Color("a699e6"), // purple
|
||||
SharpIdeRazorSpanKind.Markup => new Color("0b7f7f"), // dark green
|
||||
SharpIdeRazorSpanKind.Transition => new Color("a699e6"), // purple
|
||||
SharpIdeRazorSpanKind.None => new Color("dcdcdc"),
|
||||
_ => new Color("dcdcdc")
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
private Dictionary MapClassifiedSpansToHighlights(int line)
|
||||
{
|
||||
var highlights = new Dictionary();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<ManagePackageVersionsCentrally>false</ManagePackageVersionsCentrally>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharpIDE.Application\SharpIDE.Application.csproj" />
|
||||
|
||||
@@ -6,6 +6,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpIDE.Application", "..\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpIDE.Photino", "..\SharpIDE.Photino\SharpIDE.Photino.csproj", "{DFF170D9-D92E-4DB7-83B5-19640EAF79D2}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{E33CF95D-DEAB-4CAC-9931-FC3ADCBA54C0}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\..\.editorconfig = ..\..\.editorconfig
|
||||
..\..\.gitattributes = ..\..\.gitattributes
|
||||
..\..\.gitignore = ..\..\.gitignore
|
||||
..\..\Directory.Build.props = ..\..\Directory.Build.props
|
||||
..\..\global.json = ..\..\global.json
|
||||
..\..\nuget.config = ..\..\nuget.config
|
||||
..\..\README.md = ..\..\README.md
|
||||
..\..\Directory.Packages.props = ..\..\Directory.Packages.props
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpIDE.RazorAccess", "..\SharpIDE.RazorAccess\SharpIDE.RazorAccess.csproj", "{614547C3-6620-4F37-B0A9-AA78A4293EB4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -31,5 +45,11 @@ Global
|
||||
{DFF170D9-D92E-4DB7-83B5-19640EAF79D2}.ExportDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{DFF170D9-D92E-4DB7-83B5-19640EAF79D2}.ExportRelease|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{DFF170D9-D92E-4DB7-83B5-19640EAF79D2}.ExportRelease|Any CPU.Build.0 = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.ExportDebug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.ExportDebug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.ExportRelease|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{614547C3-6620-4F37-B0A9-AA78A4293EB4}.ExportRelease|Any CPU.Build.0 = Debug|Any CPU
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
@@ -10,6 +10,7 @@ using SharpIDE.Application.Features.Debugging;
|
||||
using SharpIDE.Application.Features.Events;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery;
|
||||
using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence;
|
||||
using SharpIDE.RazorAccess;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
||||
namespace SharpIDE.Godot;
|
||||
@@ -120,12 +121,13 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
||||
_ = Task.GodotRun(async () =>
|
||||
{
|
||||
var syntaxHighlighting = RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
|
||||
var razorSyntaxHighlighting = RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
|
||||
var diagnostics = RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
|
||||
var slnDiagnostics = RoslynAnalysis.UpdateSolutionDiagnostics();
|
||||
await Task.WhenAll(syntaxHighlighting, diagnostics);
|
||||
await Task.WhenAll(syntaxHighlighting, razorSyntaxHighlighting, diagnostics);
|
||||
Callable.From(() =>
|
||||
{
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting.Result);
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting.Result, razorSyntaxHighlighting.Result);
|
||||
SetDiagnosticsModel(diagnostics.Result);
|
||||
}).CallDeferred();
|
||||
await slnDiagnostics;
|
||||
@@ -144,12 +146,13 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
||||
await RoslynAnalysis.ApplyCodeActionAsync(codeAction);
|
||||
var fileContents = await File.ReadAllTextAsync(_currentFile.Path);
|
||||
var syntaxHighlighting = await RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
|
||||
var razorSyntaxHighlighting = await RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
|
||||
var diagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
|
||||
Callable.From(() =>
|
||||
{
|
||||
BeginComplexOperation();
|
||||
SetText(fileContents);
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting);
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting, razorSyntaxHighlighting);
|
||||
SetDiagnosticsModel(diagnostics);
|
||||
SetCaretLine(currentCaretPosition.line);
|
||||
SetCaretColumn(currentCaretPosition.col);
|
||||
@@ -167,7 +170,8 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
||||
SetText(fileContents);
|
||||
_fileChangingSuppressBreakpointToggleEvent = false;
|
||||
var syntaxHighlighting = await RoslynAnalysis.GetDocumentSyntaxHighlighting(_currentFile);
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting);
|
||||
var razorSyntaxHighlighting = await RoslynAnalysis.GetRazorDocumentSyntaxHighlighting(_currentFile);
|
||||
SetSyntaxHighlightingModel(syntaxHighlighting, razorSyntaxHighlighting);
|
||||
var diagnostics = await RoslynAnalysis.GetDocumentDiagnostics(_currentFile);
|
||||
SetDiagnosticsModel(diagnostics);
|
||||
}
|
||||
@@ -273,9 +277,10 @@ public partial class SharpIdeCodeEdit : CodeEdit
|
||||
_diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
private void SetSyntaxHighlightingModel(IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> classifiedSpans)
|
||||
private void SetSyntaxHighlightingModel(IEnumerable<(FileLinePositionSpan fileSpan, ClassifiedSpan classifiedSpan)> classifiedSpans, IEnumerable<SharpIdeRazorClassifiedSpan> razorClassifiedSpans)
|
||||
{
|
||||
_syntaxHighlighter.ClassifiedSpans = classifiedSpans;
|
||||
_syntaxHighlighter.ClassifiedSpans = classifiedSpans.ToHashSet();
|
||||
_syntaxHighlighter.RazorClassifiedSpans = razorClassifiedSpans.ToHashSet();
|
||||
Callable.From(() =>
|
||||
{
|
||||
_syntaxHighlighter.ClearHighlightingCache();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType> <!-- Doesn't actually mean Windows Exe, 'Exe' = console entrypoint, 'WinExe' = application entry point -->
|
||||
@@ -18,13 +18,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ardalis.GuardClauses" Version="5.0.0" />
|
||||
<PackageReference Include="BlazorMonaco" Version="3.3.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" Version="10.0.0-rc.1.25451.107" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView" Version="10.0.0-rc.1.25451.107" />
|
||||
<PackageReference Include="MudBlazor" Version="8.12.0" />
|
||||
<PackageReference Include="Photino.Blazor" Version="4.0.13" />
|
||||
<PackageReference Include="XtermBlazor" Version="2.1.2" />
|
||||
<PackageReference Include="Ardalis.GuardClauses" />
|
||||
<PackageReference Include="BlazorMonaco" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Components.WebView" />
|
||||
<PackageReference Include="MudBlazor" />
|
||||
<PackageReference Include="Photino.Blazor" />
|
||||
<PackageReference Include="XtermBlazor" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
72
src/SharpIDE.RazorAccess/RazorAccessors.cs
Normal file
72
src/SharpIDE.RazorAccess/RazorAccessors.cs
Normal file
@@ -0,0 +1,72 @@
|
||||
extern alias WorkspaceAlias;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using RazorCodeDocumentExtensions = WorkspaceAlias::Microsoft.AspNetCore.Razor.Language.RazorCodeDocumentExtensions;
|
||||
|
||||
namespace SharpIDE.RazorAccess;
|
||||
|
||||
public static class RazorAccessors
|
||||
{
|
||||
public static (ImmutableArray<SharpIdeRazorClassifiedSpan>, SourceText Text, List<SharpIdeRazorSourceMapping>) GetClassifiedSpans(SourceText sourceText, SourceText importsSourceText, string razorDocumentFilePath, string projectDirectory)
|
||||
{
|
||||
|
||||
var razorSourceDocument = RazorSourceDocument.Create(sourceText.ToString(), razorDocumentFilePath);
|
||||
var importsRazorSourceDocument = RazorSourceDocument.Create(importsSourceText.ToString(), "_Imports.razor");
|
||||
|
||||
var projectEngine = RazorProjectEngine.Create(RazorConfiguration.Default, RazorProjectFileSystem.Create(projectDirectory),
|
||||
builder => { /* configure features if needed */ });
|
||||
|
||||
//var razorCodeDocument = projectEngine.Process(razorSourceDocument, RazorFileKind.Component, [], []);
|
||||
var razorCodeDocument = projectEngine.ProcessDesignTime(razorSourceDocument, RazorFileKind.Component, [importsRazorSourceDocument], []);
|
||||
var razorCSharpDocument = razorCodeDocument.GetRequiredCSharpDocument();
|
||||
//var generatedSourceText = razorCSharpDocument.Text;
|
||||
|
||||
//var filePath = razorCodeDocument.Source.FilePath.AssumeNotNull();
|
||||
//var razorSourceText = razorCodeDocument.Source.Text;
|
||||
var razorSpans = RazorCodeDocumentExtensions.GetClassifiedSpans(razorCodeDocument);
|
||||
|
||||
//var sharpIdeSpans = MemoryMarshal.Cast<RazorCodeDocumentExtensions.ClassifiedSpan, SharpIdeRazorClassifiedSpan>(razorSpans);
|
||||
var sharpIdeSpans = razorSpans.Select(s => new SharpIdeRazorClassifiedSpan(s.Span.ToSharpIdeSourceSpan(), s.Kind.ToSharpIdeSpanKind())).ToList();
|
||||
|
||||
return (sharpIdeSpans.ToImmutableArray(), razorCSharpDocument.Text, razorCSharpDocument.SourceMappings.Select(s => s.ToSharpIdeSourceMapping()).ToList());
|
||||
}
|
||||
|
||||
// public static bool TryGetMappedSpans(
|
||||
// TextSpan span,
|
||||
// SourceText source,
|
||||
// RazorCSharpDocument output,
|
||||
// out LinePositionSpan linePositionSpan,
|
||||
// out TextSpan mappedSpan)
|
||||
// {
|
||||
// foreach (SourceMapping sourceMapping in output.SourceMappings)
|
||||
// {
|
||||
// TextSpan textSpan1 = sourceMapping.OriginalSpan.AsTextSpan();
|
||||
// TextSpan textSpan2 = sourceMapping.GeneratedSpan.AsTextSpan();
|
||||
// if (textSpan2.Contains(span))
|
||||
// {
|
||||
// int num1 = span.Start - textSpan2.Start;
|
||||
// int num2 = span.End - textSpan2.End;
|
||||
// if (num1 >= 0 && num2 <= 0)
|
||||
// {
|
||||
// mappedSpan = new TextSpan(textSpan1.Start + num1, textSpan1.End + num2 - (textSpan1.Start + num1));
|
||||
// linePositionSpan = source.Lines.GetLinePositionSpan(mappedSpan);
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// mappedSpan = new TextSpan();
|
||||
// linePositionSpan = new LinePositionSpan();
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// /// <summary>
|
||||
// /// Wrapper to avoid <see cref="MissingMethodException"/>s in the caller during JITing
|
||||
// /// even though the method is not actually called.
|
||||
// /// </summary>
|
||||
// [MethodImpl(MethodImplOptions.NoInlining)]
|
||||
// private static object GetFileKindFromPath(string filePath)
|
||||
// {
|
||||
// return FileKinds.GetFileKindFromPath(filePath);
|
||||
// }
|
||||
}
|
||||
40
src/SharpIDE.RazorAccess/SharpIDE.RazorAccess.csproj
Normal file
40
src/SharpIDE.RazorAccess/SharpIDE.RazorAccess.csproj
Normal file
@@ -0,0 +1,40 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<AssemblyName>Microsoft.CodeAnalysis.Razor.Test</AssemblyName>
|
||||
<KeyOriginatorFile>$(PkgMicrosoft_DotNet_Arcade_Sdk)\tools\snk\AspNetCore.snk</KeyOriginatorFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Common" />
|
||||
<PackageReference Include="Microsoft.DotNet.Arcade.Sdk" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Net.Compilers.Razor.Toolset" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Razor.Utilities.Shared" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.Extensions.ObjectPool" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Razor.Compiler" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Razor.Workspaces" PrivateAssets="all" IncludeAssets="none" GeneratePathProperty="true" />
|
||||
<PackageReference Include="Krafs.Publicizer">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- <Reference Include="$(PkgMicrosoft_Net_Compilers_Razor_Toolset)\source-generators\Microsoft.CodeAnalysis.Razor.Compiler.dll" />-->
|
||||
<Reference Aliases="WorkspaceAlias" Include="$(PkgMicrosoft_CodeAnalysis_Razor_Workspaces)\lib\net9.0\Microsoft.CodeAnalysis.Razor.Workspaces.dll" />
|
||||
<Reference Include="$(PkgMicrosoft_CodeAnalysis_Razor_Compiler)\lib\net9.0\Microsoft.CodeAnalysis.Razor.Compiler.dll" />
|
||||
<Reference Include="$(PkgMicrosoft_AspNetCore_Razor_Utilities_Shared)\lib\net9.0\Microsoft.AspNetCore.Razor.Utilities.Shared.dll" />
|
||||
<Reference Include="$(PkgMicrosoft_Extensions_ObjectPool)\lib\net8.0\Microsoft.Extensions.ObjectPool.dll" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Publicize Include="Microsoft.CodeAnalysis.Razor.Workspaces" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
30
src/SharpIDE.RazorAccess/SharpIdeRazorClassifiedSpan.cs
Normal file
30
src/SharpIDE.RazorAccess/SharpIdeRazorClassifiedSpan.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
extern alias WorkspaceAlias;
|
||||
using RazorCodeDocumentExtensions = WorkspaceAlias::Microsoft.AspNetCore.Razor.Language.RazorCodeDocumentExtensions;
|
||||
|
||||
namespace SharpIDE.RazorAccess;
|
||||
|
||||
public record struct SharpIdeRazorClassifiedSpan(SharpIdeRazorSourceSpan Span, SharpIdeRazorSpanKind Kind, string? CodeClassificationType = null);
|
||||
|
||||
public enum SharpIdeRazorSpanKind
|
||||
{
|
||||
Transition,
|
||||
MetaCode,
|
||||
Comment,
|
||||
Code,
|
||||
Markup,
|
||||
None,
|
||||
}
|
||||
|
||||
public static class SharpIdeRazorClassifiedSpanExtensions
|
||||
{
|
||||
public static SharpIdeRazorSpanKind ToSharpIdeSpanKind(this RazorCodeDocumentExtensions.SpanKind kind) => kind switch
|
||||
{
|
||||
RazorCodeDocumentExtensions.SpanKind.Transition => SharpIdeRazorSpanKind.Transition,
|
||||
RazorCodeDocumentExtensions.SpanKind.MetaCode => SharpIdeRazorSpanKind.MetaCode,
|
||||
RazorCodeDocumentExtensions.SpanKind.Comment => SharpIdeRazorSpanKind.Comment,
|
||||
RazorCodeDocumentExtensions.SpanKind.Code => SharpIdeRazorSpanKind.Code,
|
||||
RazorCodeDocumentExtensions.SpanKind.Markup => SharpIdeRazorSpanKind.Markup,
|
||||
RazorCodeDocumentExtensions.SpanKind.None => SharpIdeRazorSpanKind.None,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(kind), kind, null)
|
||||
};
|
||||
}
|
||||
49
src/SharpIDE.RazorAccess/SharpIdeRazorSourceMapping.cs
Normal file
49
src/SharpIDE.RazorAccess/SharpIdeRazorSourceMapping.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace SharpIDE.RazorAccess;
|
||||
|
||||
public sealed class SharpIdeRazorSourceMapping(
|
||||
SharpIdeRazorSourceSpan originalSpan,
|
||||
SharpIdeRazorSourceSpan generatedSpan)
|
||||
: IEquatable<SharpIdeRazorSourceMapping>
|
||||
{
|
||||
public SharpIdeRazorSourceSpan OriginalSpan { get; } = originalSpan;
|
||||
|
||||
public SharpIdeRazorSourceSpan GeneratedSpan { get; } = generatedSpan;
|
||||
|
||||
public override bool Equals(object? obj) => Equals(obj as SourceMapping);
|
||||
|
||||
public bool Equals(SharpIdeRazorSourceMapping? other)
|
||||
{
|
||||
if (other == null)
|
||||
return false;
|
||||
var sourceSpan = OriginalSpan;
|
||||
if (!sourceSpan.Equals(other.OriginalSpan))
|
||||
return false;
|
||||
sourceSpan = GeneratedSpan;
|
||||
return sourceSpan.Equals(other.GeneratedSpan);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
HashCodeCombiner hashCode = HashCodeCombiner.Start();
|
||||
hashCode.Add(OriginalSpan);
|
||||
hashCode.Add(GeneratedSpan);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(CultureInfo.CurrentCulture, "{0} -> {1}", OriginalSpan, GeneratedSpan);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SharpIdeRazorSourceMappingExtensions
|
||||
{
|
||||
public static SharpIdeRazorSourceMapping ToSharpIdeSourceMapping(this SourceMapping mapping)
|
||||
{
|
||||
return new SharpIdeRazorSourceMapping(mapping.OriginalSpan.ToSharpIdeSourceSpan(), mapping.GeneratedSpan.ToSharpIdeSourceSpan());
|
||||
}
|
||||
}
|
||||
83
src/SharpIDE.RazorAccess/SharpIdeRazorSourceSpan.cs
Normal file
83
src/SharpIDE.RazorAccess/SharpIdeRazorSourceSpan.cs
Normal file
@@ -0,0 +1,83 @@
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.Extensions.Internal;
|
||||
|
||||
namespace SharpIDE.RazorAccess;
|
||||
|
||||
public readonly struct SharpIdeRazorSourceSpan(
|
||||
string filePath,
|
||||
int absoluteIndex,
|
||||
int lineIndex,
|
||||
int characterIndex,
|
||||
int length,
|
||||
int lineCount,
|
||||
int endCharacterIndex)
|
||||
: IEquatable<SharpIdeRazorSourceSpan>
|
||||
{
|
||||
public int Length { get; } = length;
|
||||
public int AbsoluteIndex { get; } = absoluteIndex;
|
||||
public int LineIndex { get; } = lineIndex;
|
||||
public int CharacterIndex { get; } = characterIndex;
|
||||
public int LineCount { get; } = lineCount;
|
||||
public int EndCharacterIndex { get; } = endCharacterIndex;
|
||||
|
||||
public string FilePath { get; } = filePath;
|
||||
|
||||
public bool Equals(SharpIdeRazorSourceSpan other)
|
||||
{
|
||||
return string.Equals(FilePath, other.FilePath, StringComparison.Ordinal) && this.AbsoluteIndex == other.AbsoluteIndex && this.LineIndex == other.LineIndex && this.CharacterIndex == other.CharacterIndex && this.Length == other.Length;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) => obj is SharpIdeRazorSourceSpan other && Equals(other);
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
var hashCode = HashCodeCombiner.Start();
|
||||
hashCode.Add(FilePath, StringComparer.Ordinal);
|
||||
hashCode.Add(AbsoluteIndex);
|
||||
hashCode.Add(LineIndex);
|
||||
hashCode.Add(CharacterIndex);
|
||||
hashCode.Add(Length);
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format(
|
||||
CultureInfo.CurrentCulture,
|
||||
"({0}:{1},{2} [{3}] {4})",
|
||||
this.AbsoluteIndex,
|
||||
this.LineIndex,
|
||||
this.CharacterIndex,
|
||||
this.Length,
|
||||
this.FilePath
|
||||
);
|
||||
}
|
||||
public static bool operator ==(SharpIdeRazorSourceSpan left, SharpIdeRazorSourceSpan right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(SharpIdeRazorSourceSpan left, SharpIdeRazorSourceSpan right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SharpIdeRazorSourceSpanExtensions
|
||||
{
|
||||
public static TextSpan AsTextSpan(this SharpIdeRazorSourceSpan sourceSpan)
|
||||
{
|
||||
return new TextSpan(sourceSpan.AbsoluteIndex, sourceSpan.Length);
|
||||
}
|
||||
public static SharpIdeRazorSourceSpan ToSharpIdeSourceSpan(this SourceSpan span)
|
||||
=> new SharpIdeRazorSourceSpan(
|
||||
span.FilePath,
|
||||
span.AbsoluteIndex,
|
||||
span.LineIndex,
|
||||
span.CharacterIndex,
|
||||
span.Length,
|
||||
span.LineCount,
|
||||
span.EndCharacterIndex);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
@@ -8,9 +8,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.15.2" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.14.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="4.14.0" />
|
||||
<PackageReference Include="BenchmarkDotNet" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user