Skip to content

Commit a3edec0

Browse files
committed
Move GetSyntaxTree to document snapshot
1 parent 53fec86 commit a3edec0

File tree

9 files changed

+35
-51
lines changed

9 files changed

+35
-51
lines changed
Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,9 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4-
using System;
5-
using System.Collections.Generic;
6-
using System.Linq;
7-
using System.Text;
8-
using System.Threading;
9-
using System.Threading.Tasks;
10-
using Microsoft.AspNetCore.Razor.Language;
11-
using Microsoft.CodeAnalysis;
12-
using Microsoft.CodeAnalysis.CSharp;
134
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
145
using Microsoft.CodeAnalysis.Razor.GoToDefinition;
156
using Microsoft.CodeAnalysis.Razor.Logging;
16-
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
177
using Microsoft.CodeAnalysis.Razor.Workspaces;
188

199
namespace Microsoft.AspNetCore.Razor.LanguageServer.Definition;
@@ -24,10 +14,4 @@ internal sealed class RazorComponentDefinitionService(
2414
ILoggerFactory loggerFactory)
2515
: AbstractRazorComponentDefinitionService(componentSearchEngine, documentMappingService, loggerFactory.GetOrCreateLogger<RazorComponentDefinitionService>())
2616
{
27-
protected override async ValueTask<SyntaxTree> GetCSharpSyntaxTreeAsync(IDocumentSnapshot documentSnapshot, CancellationToken cancellationToken)
28-
{
29-
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync().ConfigureAwait(false);
30-
var csharpText = codeDocument.GetCSharpSourceText();
31-
return CSharpSyntaxTree.ParseText(csharpText, cancellationToken: cancellationToken);
32-
}
3317
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/AbstractRazorComponentDefinitionService.cs

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,8 @@ private async Task<LspRange> GetNavigateRangeAsync(IDocumentSnapshot documentSna
6969
{
7070
_logger.LogInformation($"Attempting to get definition from an attribute directly.");
7171

72-
var originCodeDocument = await documentSnapshot.GetGeneratedOutputAsync().ConfigureAwait(false);
73-
var syntaxTree = await GetCSharpSyntaxTreeAsync(documentSnapshot, cancellationToken).ConfigureAwait(false);
74-
7572
var range = await RazorComponentDefinitionHelpers
76-
.TryGetPropertyRangeAsync(originCodeDocument, syntaxTree, attributeDescriptor.GetPropertyName(), _documentMappingService, _logger, cancellationToken)
73+
.TryGetPropertyRangeAsync(documentSnapshot, attributeDescriptor.GetPropertyName(), _documentMappingService, _logger, cancellationToken)
7774
.ConfigureAwait(false);
7875

7976
if (range is not null)
@@ -88,6 +85,4 @@ private async Task<LspRange> GetNavigateRangeAsync(IDocumentSnapshot documentSna
8885
// at least then press F7 to go there.
8986
return VsLspFactory.DefaultRange;
9087
}
91-
92-
protected abstract ValueTask<SyntaxTree> GetCSharpSyntaxTreeAsync(IDocumentSnapshot documentSnapshot, CancellationToken cancellationToken);
9388
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/GoToDefinition/RazorComponentDefinitionHelpers.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using Microsoft.CodeAnalysis.CSharp.Syntax;
1212
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
1313
using Microsoft.CodeAnalysis.Razor.Logging;
14+
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
1415
using Microsoft.CodeAnalysis.Razor.Workspaces;
1516
using Microsoft.VisualStudio.LanguageServer.Protocol;
1617
using LspRange = Microsoft.VisualStudio.LanguageServer.Protocol.Range;
@@ -129,8 +130,7 @@ static bool TryGetTagName(RazorSyntaxNode node, [NotNullWhen(true)] out RazorSyn
129130
}
130131

131132
public static async Task<LspRange?> TryGetPropertyRangeAsync(
132-
RazorCodeDocument codeDocument,
133-
SyntaxTree csharpSyntaxTree,
133+
IDocumentSnapshot documentSnapshot,
134134
string propertyName,
135135
IDocumentMappingService documentMappingService,
136136
ILogger logger,
@@ -148,7 +148,9 @@ static bool TryGetTagName(RazorSyntaxNode node, [NotNullWhen(true)] out RazorSyn
148148
// will error, but allowing them to Go To Def on that property regardless, actually helps
149149
// them fix the error.
150150

151+
var csharpSyntaxTree = await documentSnapshot.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
151152
var root = await csharpSyntaxTree.GetRootAsync(cancellationToken).ConfigureAwait(false);
153+
var codeDocument = await documentSnapshot.GetGeneratedOutputAsync().ConfigureAwait(false);
152154

153155
// Since we know how the compiler generates the C# source we can be a little specific here, and avoid
154156
// long tree walks. If the compiler ever changes how they generate their code, the tests for this will break

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/DocumentSnapshot.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33

44
using System;
55
using System.Diagnostics.CodeAnalysis;
6+
using System.Threading;
67
using System.Threading.Tasks;
78
using Microsoft.AspNetCore.Razor.Language;
9+
using Microsoft.CodeAnalysis.CSharp;
810
using Microsoft.CodeAnalysis.Text;
911

1012
namespace Microsoft.CodeAnalysis.Razor.ProjectSystem;
@@ -62,4 +64,11 @@ public IDocumentSnapshot WithText(SourceText text)
6264
{
6365
return new DocumentSnapshot(ProjectInternal, State.WithText(text, VersionStamp.Create()));
6466
}
67+
68+
public async Task<SyntaxTree> GetCSharpSyntaxTreeAsync(CancellationToken cancellationToken)
69+
{
70+
var codeDocument = await GetGeneratedOutputAsync().ConfigureAwait(false);
71+
var csharpText = codeDocument.GetCSharpSourceText();
72+
return CSharpSyntaxTree.ParseText(csharpText, cancellationToken: cancellationToken);
73+
}
6574
}

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/IDocumentSnapshot.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

44
using System.Diagnostics.CodeAnalysis;
5+
using System.Threading;
56
using System.Threading.Tasks;
67
using Microsoft.AspNetCore.Razor.Language;
78
using Microsoft.CodeAnalysis.Text;
@@ -20,6 +21,12 @@ internal interface IDocumentSnapshot
2021
Task<VersionStamp> GetTextVersionAsync();
2122
Task<RazorCodeDocument> GetGeneratedOutputAsync();
2223

24+
/// <summary>
25+
/// Gets the Roslyn syntax tree for the generated C# for this Razor document
26+
/// </summary>
27+
/// <remarks>Using this from the LSP server side of things is not ideal. Use sparingly :)</remarks>
28+
Task<SyntaxTree> GetCSharpSyntaxTreeAsync(CancellationToken cancellationToken);
29+
2330
bool TryGetText([NotNullWhen(true)] out SourceText? result);
2431
bool TryGetTextVersion(out VersionStamp result);
2532
bool TryGetGeneratedOutput([NotNullWhen(true)] out RazorCodeDocument? result);

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/ProjectSystem/ImportDocumentSnapshot.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Diagnostics.CodeAnalysis;
66
using System.IO;
7+
using System.Threading;
78
using System.Threading.Tasks;
89
using Microsoft.AspNetCore.Razor.Language;
910
using Microsoft.CodeAnalysis.Text;
@@ -75,4 +76,7 @@ public bool TryGetGeneratedOutput([NotNullWhen(true)] out RazorCodeDocument? res
7576

7677
public IDocumentSnapshot WithText(SourceText text)
7778
=> throw new NotSupportedException();
79+
80+
public Task<SyntaxTree> GetCSharpSyntaxTreeAsync(CancellationToken cancellationToken)
81+
=> throw new NotSupportedException();
7882
}

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/GoToDefinition/RazorComponentDefinitionService.cs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,10 @@
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

44
using System.Composition;
5-
using System.Diagnostics;
6-
using System.Threading;
7-
using System.Threading.Tasks;
8-
using Microsoft.AspNetCore.Razor;
95
using Microsoft.CodeAnalysis.Razor.DocumentMapping;
106
using Microsoft.CodeAnalysis.Razor.GoToDefinition;
117
using Microsoft.CodeAnalysis.Razor.Logging;
12-
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
138
using Microsoft.CodeAnalysis.Razor.Workspaces;
14-
using Microsoft.CodeAnalysis.Remote.Razor.ProjectSystem;
159

1610
namespace Microsoft.CodeAnalysis.Remote.Razor.GoToDefinition;
1711

@@ -23,19 +17,4 @@ internal sealed class RazorComponentDefinitionService(
2317
ILoggerFactory loggerFactory)
2418
: AbstractRazorComponentDefinitionService(componentSearchEngine, documentMappingService, loggerFactory.GetOrCreateLogger<RazorComponentDefinitionService>())
2519
{
26-
protected override async ValueTask<SyntaxTree> GetCSharpSyntaxTreeAsync(IDocumentSnapshot documentSnapshot, CancellationToken cancellationToken)
27-
{
28-
Debug.Assert(documentSnapshot is RemoteDocumentSnapshot, "This method only works on document snapshots created in the OOP process");
29-
30-
var remoteSnapshot = (RemoteDocumentSnapshot)documentSnapshot;
31-
var document = await remoteSnapshot.GetGeneratedDocumentAsync().ConfigureAwait(false);
32-
33-
if (document.TryGetSyntaxTree(out var syntaxTree))
34-
{
35-
return syntaxTree;
36-
}
37-
38-
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
39-
return tree.AssumeNotNull();
40-
}
4120
}

src/Razor/src/Microsoft.CodeAnalysis.Remote.Razor/ProjectSystem/RemoteDocumentSnapshot.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,4 +117,11 @@ private async Task<Document> HACK_GenerateDocumentAsync()
117117
// HACK: We're not in the same solution fork as the LSP server that provides content for this document
118118
return generatedDocument.WithText(csharpSourceText);
119119
}
120+
121+
public async Task<SyntaxTree> GetCSharpSyntaxTreeAsync(CancellationToken cancellationToken)
122+
{
123+
var document = await GetGeneratedDocumentAsync().ConfigureAwait(false);
124+
var tree = await document.GetSyntaxTreeAsync(cancellationToken).ConfigureAwait(false);
125+
return tree.AssumeNotNull();
126+
}
120127
}

src/Razor/test/Microsoft.AspNetCore.Razor.LanguageServer.Test/Definition/RazorComponentDefinitionHelpersTest.cs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4-
using System.Threading;
54
using System.Threading.Tasks;
65
using Microsoft.AspNetCore.Razor.Language;
76
using Microsoft.AspNetCore.Razor.LanguageServer.Completion;
87
using Microsoft.AspNetCore.Razor.Test.Common;
98
using Microsoft.AspNetCore.Razor.Test.Common.LanguageServer;
10-
using Microsoft.CodeAnalysis.CSharp;
9+
using Microsoft.AspNetCore.Razor.Test.Common.ProjectSystem;
1110
using Microsoft.CodeAnalysis.Razor.GoToDefinition;
1211
using Microsoft.CodeAnalysis.Testing;
1312
using Microsoft.VisualStudio.LanguageServer.Protocol;
@@ -391,13 +390,11 @@ private async Task VerifyTryGetPropertyRangeAsync(string content, string propert
391390

392391
var codeDocument = CreateCodeDocument(content);
393392
var expectedRange = codeDocument.Source.Text.GetRange(selection);
393+
var snapshot = TestDocumentSnapshot.Create("test.razor", content).With(codeDocument);
394394

395395
var documentMappingService = new LspDocumentMappingService(FilePathService, new TestDocumentContextFactory(), LoggerFactory);
396396

397-
var csharpText = codeDocument.GetCSharpSourceText();
398-
var syntaxTree = CSharpSyntaxTree.ParseText(csharpText);
399-
400-
var range = await RazorComponentDefinitionHelpers.TryGetPropertyRangeAsync(codeDocument, syntaxTree, propertyName, documentMappingService, Logger, DisposalToken);
397+
var range = await RazorComponentDefinitionHelpers.TryGetPropertyRangeAsync(snapshot, propertyName, documentMappingService, Logger, DisposalToken);
401398
Assert.NotNull(range);
402399
Assert.Equal(expectedRange, range);
403400
}

0 commit comments

Comments
 (0)