Skip to content

Commit 6de884a

Browse files
committed
Use the full file path as the target path when it's missing
1 parent 71676b1 commit 6de884a

File tree

3 files changed

+137
-4
lines changed

3 files changed

+137
-4
lines changed

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/SourceGenerators/RazorSourceGenerator.RazorProviders.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,9 @@ private static (SourceGeneratorProjectItem?, Diagnostic?) ComputeProjectItems((A
9494
}
9595
else
9696
{
97-
// If the TargetPath is not provided, we effectively assume its in the root of the project.
98-
relativePath = Path.GetFileName(additionalText.Path);
97+
// If the TargetPath is not provided, it could be a Misc Files situation, or just a project that isn't using the
98+
// Web or Razor SDK. In this case, we just use the physical path.
99+
relativePath = additionalText.Path;
99100
}
100101

101102
options.TryGetValue("build_metadata.AdditionalFiles.CssScope", out var cssScope);

src/Razor/src/Microsoft.CodeAnalysis.Razor.Workspaces/Extensions/TextDocumentExtensions.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ public static bool TryComputeHintNameFromRazorDocument(this TextDocument razorDo
2828
var filePath = razorDocument.FilePath.AsSpanOrDefault();
2929
if (string.IsNullOrEmpty(razorDocument.Project.FilePath))
3030
{
31-
var fileName = filePath[filePath.LastIndexOfAny(['/', '\\'])..].TrimStart(['/', '\\']);
32-
hintName = RazorSourceGenerator.GetIdentifierFromPath(fileName);
31+
hintName = RazorSourceGenerator.GetIdentifierFromPath(filePath);
3332
return hintName is not null;
3433
}
3534

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Razor;
7+
using Microsoft.CodeAnalysis;
8+
using Microsoft.CodeAnalysis.Text;
9+
using Microsoft.VisualStudio.Razor.LanguageClient.Cohost;
10+
using Xunit;
11+
using Xunit.Abstractions;
12+
13+
namespace Microsoft.VisualStudioCode.RazorExtension.Test.Endpoints.Shared;
14+
15+
public class ComputedTargetPathTest(ITestOutputHelper testOutputHelper) : CohostEndpointTestBase(testOutputHelper)
16+
{
17+
[Fact]
18+
public async Task GetHintName()
19+
{
20+
// Creating a misc files project will mean that there is no globalconfig created, so no target paths will be set
21+
var document = CreateProjectAndRazorDocument("");
22+
23+
_ = await document.Project.GetCompilationAsync(DisposalToken);
24+
25+
Assert.True(document.TryComputeHintNameFromRazorDocument(out var hintName));
26+
var generatedDocument = await document.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, DisposalToken);
27+
Assert.NotNull(generatedDocument);
28+
}
29+
30+
[Fact]
31+
public async Task NoGlobalConfig_WithProjectFilePath()
32+
{
33+
var doc1Path = FilePath(@"Pages\Index.razor");
34+
35+
var document = CreateProjectAndRazorDocument("");
36+
37+
var doc1 = document.Project.AddAdditionalDocument(
38+
doc1Path,
39+
SourceText.From("""
40+
<div>This is a page</div>
41+
"""),
42+
filePath: doc1Path);
43+
44+
var project = doc1.Project.RemoveAnalyzerConfigDocument(doc1.Project.AnalyzerConfigDocuments.First().Id);
45+
46+
_ = await project.GetCompilationAsync(DisposalToken);
47+
48+
doc1 = project.GetAdditionalDocument(doc1.Id).AssumeNotNull();
49+
50+
Assert.True(doc1.TryComputeHintNameFromRazorDocument(out var hintName));
51+
var generatedDocument = await doc1.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, DisposalToken);
52+
Assert.NotNull(generatedDocument);
53+
}
54+
55+
[Fact]
56+
public async Task NoGlobalConfig_NoProjectFilePath()
57+
{
58+
var doc1Path = FilePath(@"Pages\Index.razor");
59+
60+
// Creating a misc files project will mean that there is no globalconfig created, so no target paths will be set
61+
var document = CreateProjectAndRazorDocument("", miscellaneousFile: true);
62+
63+
var doc1 = document.Project.AddAdditionalDocument(
64+
doc1Path,
65+
SourceText.From("""
66+
<div>This is a page</div>
67+
"""),
68+
filePath: doc1Path);
69+
70+
_ = await doc1.Project.GetCompilationAsync(DisposalToken);
71+
72+
Assert.True(doc1.TryComputeHintNameFromRazorDocument(out var hintName));
73+
var generatedDocument = await doc1.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, DisposalToken);
74+
Assert.NotNull(generatedDocument);
75+
}
76+
77+
[Fact]
78+
public async Task NoGlobalConfig_MultipleFilesWithTheSameName()
79+
{
80+
var doc1Path = FilePath(@"Pages\Index.razor");
81+
var doc2Path = FilePath(@"Components\Index.razor");
82+
83+
// Creating a misc files project will mean that there is no globalconfig created, so no target paths will be set
84+
var document = CreateProjectAndRazorDocument("", miscellaneousFile: true);
85+
86+
var doc1 = document.Project.AddAdditionalDocument(
87+
doc1Path,
88+
SourceText.From("""
89+
<div>This is a page</div>
90+
"""),
91+
filePath: doc1Path);
92+
var doc2 = doc1.Project.AddAdditionalDocument(
93+
doc2Path,
94+
SourceText.From("""
95+
<div>This is a component</div>
96+
"""),
97+
filePath: doc2Path);
98+
99+
// Make sure we have a doc1 from the final project
100+
doc1 = doc2.Project.GetAdditionalDocument(doc1.Id).AssumeNotNull();
101+
102+
Assert.True(doc1.TryComputeHintNameFromRazorDocument(out var hintName1));
103+
var generatedDocument = await doc1.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName1, DisposalToken);
104+
Assert.NotNull(generatedDocument);
105+
106+
Assert.True(doc2.TryComputeHintNameFromRazorDocument(out var hintName2));
107+
generatedDocument = await doc2.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName2, DisposalToken);
108+
Assert.NotNull(generatedDocument);
109+
}
110+
111+
[Fact]
112+
public async Task NotAllFilesHaveTargetPaths()
113+
{
114+
var doc1Path = FilePath(@"Pages\Index.razor");
115+
116+
// This will create a project with a globalconfig, and target paths for a single razor file
117+
var document = CreateProjectAndRazorDocument("""
118+
<div>This is a normal file with a target path
119+
""");
120+
121+
// Now add a file without updating the globalconfig
122+
var doc1 = document.Project.AddAdditionalDocument(
123+
doc1Path,
124+
SourceText.From("""
125+
<div>This is an extra document</div>
126+
"""),
127+
filePath: doc1Path);
128+
129+
Assert.True(doc1.TryComputeHintNameFromRazorDocument(out var hintName));
130+
var generatedDocument = await doc1.Project.TryGetSourceGeneratedDocumentFromHintNameAsync(hintName, DisposalToken);
131+
Assert.NotNull(generatedDocument);
132+
}
133+
}

0 commit comments

Comments
 (0)