зеркало из https://github.com/dotnet/razor.git
Emit host outputs (#8242)
* Consolidate roslyn versions We had multiple sets of roslyn references, differing between the compiler and the tooling. This consolidates those versions and updates the compiler references to be inline with the tooling. * Filter out compiler-generated types such as RefSafetyRulesAttribute and EmbeddedAttribute. * Update Roslyn to 4.5.0-2.23107.1 * Add reference to `ExternalAccess.RazorCompiler` * Emit design-time outputs from the source generator * Emit host outputs from the source generator * Test host outputs * Generate both design-time and runtime outputs * Switch to implementation output * Remove `general-testing` feed * Update Roslyn to 4.6.0-2.23110.2 * Update Roslyn to 4.6.0-2.23113.3 * Remove blank line * Re-do changes of this PR onto main * Update Roslyn to 4.7.0-2.23227.6 * Skip host outputs unless opted-in * Update Roslyn to 4.7.0-2.23253.2 --------- Co-authored-by: Fredric Silberberg <frsilb@microsoft.com>
This commit is contained in:
Родитель
b6e673c517
Коммит
a0d029c1ef
|
@ -41,9 +41,6 @@
|
|||
-->
|
||||
<packageSourceMapping>
|
||||
<clear />
|
||||
<packageSource key="general-testing">
|
||||
<package pattern="microsoft.commonlanguageserverProtocol.*" />
|
||||
</packageSource>
|
||||
<packageSource key="dotnet-core-internal-tooling">
|
||||
<package pattern="microsoft.*" />
|
||||
</packageSource>
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>f6725f6f04ce03574fcf89faa4b20b72ef83e4dd</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.RazorCompiler" Version="4.7.0-2.23301.2">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>f6725f6f04ce03574fcf89faa4b20b72ef83e4dd</Sha>
|
||||
</Dependency>
|
||||
<Dependency Name="Microsoft.CodeAnalysis.ExternalAccess.OmniSharp.CSharp" Version="4.7.0-2.23301.2">
|
||||
<Uri>https://github.com/dotnet/roslyn</Uri>
|
||||
<Sha>f6725f6f04ce03574fcf89faa4b20b72ef83e4dd</Sha>
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
<MicrosoftNetCompilersToolsetPackageVersion>4.7.0-2.23301.2</MicrosoftNetCompilersToolsetPackageVersion>
|
||||
<MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>4.7.0-2.23301.2</MicrosoftCommonLanguageServerProtocolFrameworkPackageVersion>
|
||||
<MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>4.7.0-2.23301.2</MicrosoftCodeAnalysisExternalAccessRazorPackageVersion>
|
||||
<MicrosoftCodeAnalysisExternalAccessRazorCompilerPackageVersion>4.7.0-2.23301.2</MicrosoftCodeAnalysisExternalAccessRazorCompilerPackageVersion>
|
||||
<MicrosoftCodeAnalysisExternalAccessOmniSharpCSharpPackageVersion>4.7.0-2.23301.2</MicrosoftCodeAnalysisExternalAccessOmniSharpCSharpPackageVersion>
|
||||
<MicrosoftCodeAnalysisCommonPackageVersion>4.7.0-2.23301.2</MicrosoftCodeAnalysisCommonPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpPackageVersion>4.7.0-2.23301.2</MicrosoftCodeAnalysisCSharpPackageVersion>
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="$(MicrosoftCodeAnalysisCommonPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.ExternalAccess.RazorCompiler" Version="$(MicrosoftCodeAnalysisExternalAccessRazorCompilerPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.CodeAnalysis.Workspaces.MSBuild" Version="$(MicrosoftCodeAnalysisWorkspacesMSBuildPackageVersion)" />
|
||||
<PackageVersion Include="Microsoft.CSharp" Version="$(MicrosoftCSharpVersion)" />
|
||||
<PackageVersion Include="Microsoft.Css.Parser" Version="$(MicrosoftCssParserVersion)" />
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.ExternalAccess.RazorCompiler" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
public LanguageVersion CSharpLanguageVersion { get; set; } = LanguageVersion.CSharp10;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a flag that determines if localized component names should be supported.</c>.
|
||||
/// Gets a flag that determines if localized component names should be supported.
|
||||
/// </summary>
|
||||
public bool SupportLocalizedComponentNames { get; set; } = false;
|
||||
|
||||
|
|
|
@ -28,6 +28,12 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
&& suppressRazorSourceGenerator == "true";
|
||||
}
|
||||
|
||||
private static bool GetHostOutputsEnabledStatus(AnalyzerConfigOptionsProvider optionsProvider, CancellationToken _)
|
||||
{
|
||||
return optionsProvider.GlobalOptions.TryGetValue("build_property.EnableRazorHostOutputs", out var enableRazorHostOutputs)
|
||||
&& enableRazorHostOutputs == "true";
|
||||
}
|
||||
|
||||
private static (RazorSourceGenerationOptions?, Diagnostic?) ComputeRazorSourceGeneratorOptions((AnalyzerConfigOptionsProvider, ParseOptions) pair, CancellationToken ct)
|
||||
{
|
||||
Log.ComputeRazorSourceGeneratorOptions();
|
||||
|
|
|
@ -9,6 +9,7 @@ using System.Linq;
|
|||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.RazorCompiler;
|
||||
|
||||
namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
||||
{
|
||||
|
@ -24,11 +25,11 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
var compilation = context.CompilationProvider;
|
||||
|
||||
// determine if we should suppress this run and filter out all the additional files if so
|
||||
var isGeneratorSuppressed = context.AnalyzerConfigOptionsProvider.Select(GetSuppressionStatus);
|
||||
var isGeneratorSuppressed = analyzerConfigOptions.Select(GetSuppressionStatus);
|
||||
var additionalTexts = context.AdditionalTextsProvider
|
||||
.Combine(isGeneratorSuppressed)
|
||||
.Where(pair => !pair.Right)
|
||||
.Select((pair, _) => pair.Left);
|
||||
.Combine(isGeneratorSuppressed)
|
||||
.Where(pair => !pair.Right)
|
||||
.Select((pair, _) => pair.Left);
|
||||
|
||||
var razorSourceGeneratorOptions = analyzerConfigOptions
|
||||
.Combine(parseOptions)
|
||||
|
@ -68,7 +69,6 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
.Combine(razorSourceGeneratorOptions)
|
||||
.Select(static (pair, _) =>
|
||||
{
|
||||
|
||||
var ((sourceItem, importFiles), razorSourceGeneratorOptions) = pair;
|
||||
RazorSourceGeneratorEventSource.Log.GenerateDeclarationCodeStart(sourceItem.FilePath);
|
||||
|
||||
|
@ -204,26 +204,39 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
return allTagHelpers;
|
||||
});
|
||||
|
||||
var generatedOutput = sourceItems
|
||||
var withOptions = sourceItems
|
||||
.Combine(importFiles.Collect())
|
||||
.Combine(allTagHelpers)
|
||||
.Combine(razorSourceGeneratorOptions)
|
||||
.Select(static (pair, _) =>
|
||||
.Combine(razorSourceGeneratorOptions);
|
||||
|
||||
var withOptionsDesignTime = withOptions
|
||||
.Combine(analyzerConfigOptions.Select(GetHostOutputsEnabledStatus))
|
||||
.Where(pair => pair.Right)
|
||||
.Select((pair, _) => pair.Left);
|
||||
|
||||
IncrementalValuesProvider<(string, RazorCodeDocument)> processed(bool designTime) => (designTime ? withOptionsDesignTime : withOptions)
|
||||
.Select((pair, _) =>
|
||||
{
|
||||
var (((sourceItem, imports), allTagHelpers), razorSourceGeneratorOptions) = pair;
|
||||
|
||||
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStart(sourceItem.FilePath);
|
||||
|
||||
// Add a generated suffix so tools, such as coverlet, consider the file to be generated
|
||||
var hintName = GetIdentifierFromPath(sourceItem.RelativePhysicalPath) + ".g.cs";
|
||||
var kind = designTime ? "DesignTime" : "Runtime";
|
||||
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStart(sourceItem.FilePath, kind);
|
||||
|
||||
var projectEngine = GetGenerationProjectEngine(allTagHelpers, sourceItem, imports, razorSourceGeneratorOptions);
|
||||
|
||||
var codeDocument = projectEngine.Process(sourceItem);
|
||||
var csharpDocument = codeDocument.GetCSharpDocument();
|
||||
var codeDocument = designTime
|
||||
? projectEngine.ProcessDesignTime(sourceItem)
|
||||
: projectEngine.Process(sourceItem);
|
||||
|
||||
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStop(sourceItem.FilePath);
|
||||
return (hintName, csharpDocument);
|
||||
RazorSourceGeneratorEventSource.Log.RazorCodeGenerateStop(sourceItem.FilePath, kind);
|
||||
return (filePath: sourceItem.RelativePhysicalPath, codeDocument);
|
||||
});
|
||||
|
||||
var csharpDocuments = processed(designTime: false)
|
||||
.Select(static (pair, _) =>
|
||||
{
|
||||
var (filePath, document) = pair;
|
||||
return (filePath, csharpDocument: document.GetCSharpDocument());
|
||||
})
|
||||
.WithLambdaComparer(static (a, b) =>
|
||||
{
|
||||
|
@ -236,9 +249,13 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
return string.Equals(a.csharpDocument.GeneratedCode, b.csharpDocument.GeneratedCode, StringComparison.Ordinal);
|
||||
}, static a => StringComparer.Ordinal.GetHashCode(a.csharpDocument));
|
||||
|
||||
context.RegisterSourceOutput(generatedOutput, static (context, pair) =>
|
||||
context.RegisterImplementationSourceOutput(csharpDocuments, static (context, pair) =>
|
||||
{
|
||||
var (hintName, csharpDocument) = pair;
|
||||
var (filePath, csharpDocument) = pair;
|
||||
|
||||
// Add a generated suffix so tools, such as coverlet, consider the file to be generated
|
||||
var hintName = GetIdentifierFromPath(filePath) + ".g.cs";
|
||||
|
||||
RazorSourceGeneratorEventSource.Log.AddSyntaxTrees(hintName);
|
||||
for (var i = 0; i < csharpDocument.Diagnostics.Count; i++)
|
||||
{
|
||||
|
@ -249,6 +266,14 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
|
||||
context.AddSource(hintName, csharpDocument.GeneratedCode);
|
||||
});
|
||||
|
||||
context.RegisterHostOutput(processed(designTime: true), static (context, pair, _) =>
|
||||
{
|
||||
var (filePath, document) = pair;
|
||||
var hintName = GetIdentifierFromPath(filePath);
|
||||
context.AddOutput(hintName + ".rsg.cs", document.GetCSharpDocument().GeneratedCode);
|
||||
context.AddOutput(hintName + ".rsg.html", document.GetHtmlDocument().GeneratedCode);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,11 +42,11 @@ namespace Microsoft.NET.Sdk.Razor.SourceGenerators
|
|||
|
||||
private const int RazorCodeGenerateStartId = 10;
|
||||
[Event(RazorCodeGenerateStartId, Level = EventLevel.Informational)]
|
||||
public void RazorCodeGenerateStart(string file) => WriteEvent(RazorCodeGenerateStartId, file);
|
||||
public void RazorCodeGenerateStart(string file, string kind) => WriteEvent(RazorCodeGenerateStartId, file, kind);
|
||||
|
||||
private const int RazorCodeGenerateStopId = 11;
|
||||
[Event(RazorCodeGenerateStopId, Level = EventLevel.Informational)]
|
||||
public void RazorCodeGenerateStop(string file) => WriteEvent(RazorCodeGenerateStopId, file);
|
||||
public void RazorCodeGenerateStop(string file, string kind) => WriteEvent(RazorCodeGenerateStopId, file, kind);
|
||||
|
||||
private const int AddSyntaxTreesId = 12;
|
||||
[Event(AddSyntaxTreesId, Level = EventLevel.Informational)]
|
||||
|
|
|
@ -97,6 +97,99 @@ namespace MyApp.Pages
|
|||
Assert.Equal(2, result.GeneratedSources.Length);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SourceGenerator_RazorFiles_DesignTime()
|
||||
{
|
||||
// Arrange
|
||||
var project = CreateTestProject(new()
|
||||
{
|
||||
["Pages/Index.razor"] = "<h1>Hello world</h1>",
|
||||
});
|
||||
|
||||
var compilation = await project.GetCompilationAsync();
|
||||
var (driver, additionalTexts, optionsProvider) = await GetDriverWithAdditionalTextAndProviderAsync(project, hostOutputs: true);
|
||||
|
||||
// Enable design-time.
|
||||
var options = optionsProvider.Clone();
|
||||
options.TestGlobalOptions["build_property.RazorDesignTime"] = "true";
|
||||
options.TestGlobalOptions["build_property.EnableRazorHostOutputs"] = "true";
|
||||
var driver2 = driver.WithUpdatedAnalyzerConfigOptions(options);
|
||||
|
||||
var result = RunGenerator(compilation!, ref driver2);
|
||||
|
||||
var pageOutput =
|
||||
@"#pragma checksum ""Pages/Index.razor"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""6b5db227a6aa2228c777b0771108b184b1fc5df3""
|
||||
// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace MyApp.Pages
|
||||
{
|
||||
#line hidden
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::System.Linq;
|
||||
using global::System.Threading.Tasks;
|
||||
using global::Microsoft.AspNetCore.Components;
|
||||
public partial class Index : global::Microsoft.AspNetCore.Components.ComponentBase
|
||||
{
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
|
||||
{
|
||||
__builder.AddMarkupContent(0, ""<h1>Hello world</h1>"");
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
";
|
||||
result.VerifyPageOutput(pageOutput);
|
||||
|
||||
result.VerifyHostOutput(
|
||||
(@"Pages_Index_razor.rsg.cs", @"// <auto-generated/>
|
||||
#pragma warning disable 1591
|
||||
namespace MyApp.Pages
|
||||
{
|
||||
#line hidden
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::System.Linq;
|
||||
using global::System.Threading.Tasks;
|
||||
using global::Microsoft.AspNetCore.Components;
|
||||
public partial class Index : global::Microsoft.AspNetCore.Components.ComponentBase
|
||||
{
|
||||
#pragma warning disable 219
|
||||
private void __RazorDirectiveTokenHelpers__() {
|
||||
}
|
||||
#pragma warning restore 219
|
||||
#pragma warning disable 0414
|
||||
private static object __o = null;
|
||||
#pragma warning restore 0414
|
||||
#pragma warning disable 1998
|
||||
protected override void BuildRenderTree(global::Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder __builder)
|
||||
{
|
||||
}
|
||||
#pragma warning restore 1998
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
"),
|
||||
(@"Pages_Index_razor.rsg.html", @"<h1>Hello world</h1>"));
|
||||
|
||||
Assert.Empty(result.Diagnostics);
|
||||
Assert.Single(result.GeneratedSources);
|
||||
|
||||
// Enable design-time without host outputs.
|
||||
options = optionsProvider.Clone();
|
||||
options.TestGlobalOptions["build_property.RazorDesignTime"] = "true";
|
||||
driver2 = driver.WithUpdatedAnalyzerConfigOptions(options);
|
||||
|
||||
result = RunGenerator(compilation!, ref driver2);
|
||||
result.VerifyPageOutput(pageOutput);
|
||||
result.VerifyHostOutput();
|
||||
|
||||
Assert.Empty(result.Diagnostics);
|
||||
Assert.Single(result.GeneratedSources);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SourceGeneratorEvents_RazorFiles_Works()
|
||||
{
|
||||
|
@ -164,70 +257,21 @@ namespace MyApp.Pages
|
|||
|
||||
Assert.Collection(eventListener.Events,
|
||||
e => Assert.Equal("ComputeRazorSourceGeneratorOptions", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStart", "/Pages/Index.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStop", "/Pages/Index.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStart", "/Pages/Counter.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStop", "/Pages/Counter.razor"),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Index_razor.g.cs", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Counter_razor.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Index_razor.g.cs"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Counter_razor.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -413,36 +457,12 @@ namespace MyApp.Pages
|
|||
Assert.Equal(2, result.GeneratedSources.Length);
|
||||
|
||||
Assert.Collection(eventListener.Events,
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Counter_razor.g.cs", file);
|
||||
});
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStart", "/Pages/Counter.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStop", "/Pages/Counter.razor"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Counter_razor.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -787,38 +807,14 @@ __builder.AddContent(3, count);
|
|||
Assert.Equal(2, result.GeneratedSources.Length);
|
||||
|
||||
Assert.Collection(eventListener.Events,
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStart", "/Pages/Counter.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStop", "/Pages/Counter.razor"),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Counter_razor.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Counter_razor.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -967,50 +963,16 @@ __builder.AddContent(3, count);
|
|||
Assert.Equal(2, result.GeneratedSources.Length);
|
||||
|
||||
Assert.Collection(eventListener.Events,
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("GenerateDeclarationCodeStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStart", "/Pages/Counter.razor"),
|
||||
e => e.AssertSingleItem("GenerateDeclarationCodeStop", "/Pages/Counter.razor"),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Counter_razor.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Counter_razor.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1145,36 +1107,12 @@ using SurveyPromptRootNamspace;
|
|||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Counter.razor", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Index_razor.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Index.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Counter.razor", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Index_razor.g.cs")
|
||||
);
|
||||
|
||||
// Verify caching
|
||||
eventListener.Events.Clear();
|
||||
|
@ -1330,42 +1268,13 @@ namespace AspNetCoreGeneratedDocument
|
|||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromReferencesStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Index_cshtml.g.cs", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Views_Shared__Layout_cshtml.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Index.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Index.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Index_cshtml.g.cs"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Views_Shared__Layout_cshtml.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact, WorkItem("https://github.com/dotnet/razor/issues/7049")]
|
||||
|
@ -1693,24 +1602,10 @@ namespace AspNetCoreGeneratedDocument
|
|||
Assert.Equal(2, result.GeneratedSources.Length);
|
||||
|
||||
Assert.Collection(eventListener.Events,
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Views_Shared__Layout_cshtml.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Views_Shared__Layout_cshtml.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -2028,36 +1923,12 @@ public class HeaderTagHelper : TagHelper
|
|||
Assert.Collection(eventListener.Events,
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStart", e.EventName),
|
||||
e => Assert.Equal("DiscoverTagHelpersFromCompilationStop", e.EventName),
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Pages/Index.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStart", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("RazorCodeGenerateStop", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("/Views/Shared/_Layout.cshtml", file);
|
||||
},
|
||||
e =>
|
||||
{
|
||||
Assert.Equal("AddSyntaxTrees", e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal("Pages_Index_cshtml.g.cs", file);
|
||||
});
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Pages/Index.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Pages/Index.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStart", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertPair("RazorCodeGenerateStop", "/Views/Shared/_Layout.cshtml", "Runtime"),
|
||||
e => e.AssertSingleItem("AddSyntaxTrees", "Pages_Index_cshtml.g.cs")
|
||||
);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
|
@ -30,6 +30,7 @@ using Microsoft.AspNetCore.Razor.Language;
|
|||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.ExternalAccess.RazorCompiler;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyModel;
|
||||
using Microsoft.Extensions.DependencyModel.Resolution;
|
||||
|
@ -56,10 +57,11 @@ public abstract class RazorSourceGeneratorTestsBase
|
|||
return (result.Item1, result.Item2);
|
||||
}
|
||||
|
||||
protected static async ValueTask<(GeneratorDriver, ImmutableArray<AdditionalText>, TestAnalyzerConfigOptionsProvider)> GetDriverWithAdditionalTextAndProviderAsync(Project project, Action<TestAnalyzerConfigOptionsProvider>? configureGlobalOptions = null)
|
||||
protected static async ValueTask<(GeneratorDriver, ImmutableArray<AdditionalText>, TestAnalyzerConfigOptionsProvider)> GetDriverWithAdditionalTextAndProviderAsync(Project project, Action<TestAnalyzerConfigOptionsProvider>? configureGlobalOptions = null, bool hostOutputs = false)
|
||||
{
|
||||
var razorSourceGenerator = new RazorSourceGenerator().AsSourceGenerator();
|
||||
var driver = (GeneratorDriver)CSharpGeneratorDriver.Create(new[] { razorSourceGenerator }, parseOptions: (CSharpParseOptions)project.ParseOptions!, driverOptions: new GeneratorDriverOptions(IncrementalGeneratorOutputKind.None, true));
|
||||
var disabledOutputs = hostOutputs ? IncrementalGeneratorOutputKind.None : (IncrementalGeneratorOutputKind)0b100000;
|
||||
var driver = (GeneratorDriver)CSharpGeneratorDriver.Create(new[] { razorSourceGenerator }, parseOptions: (CSharpParseOptions)project.ParseOptions!, driverOptions: new GeneratorDriverOptions(disabledOutputs, true));
|
||||
|
||||
var optionsProvider = new TestAnalyzerConfigOptionsProvider();
|
||||
optionsProvider.TestGlobalOptions["build_property.RazorConfiguration"] = "Default";
|
||||
|
@ -409,7 +411,7 @@ internal static class Extensions
|
|||
{
|
||||
if (expectedOutput.Length == 1 && string.IsNullOrWhiteSpace(expectedOutput[0]))
|
||||
{
|
||||
Assert.True(false, GenerateExpectedOutput(result));
|
||||
Assert.True(false, GenerateExpectedPageOutput(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -424,6 +426,29 @@ internal static class Extensions
|
|||
return result;
|
||||
}
|
||||
|
||||
public static GeneratorRunResult VerifyHostOutput(this GeneratorRunResult result, params (string hintName, string text)[] expectedOutputs)
|
||||
{
|
||||
if (expectedOutputs.Length == 1 && string.IsNullOrWhiteSpace(expectedOutputs[0].text))
|
||||
{
|
||||
Assert.True(false, GenerateExpectedHostOutput(result));
|
||||
}
|
||||
else
|
||||
{
|
||||
var hostOutputs = result.GetHostOutputs();
|
||||
Assert.Equal(expectedOutputs.Length, hostOutputs.Length);
|
||||
for (int i = 0; i < hostOutputs.Length; i++)
|
||||
{
|
||||
var expectedOutput = expectedOutputs[i];
|
||||
var actualOutput = hostOutputs[i];
|
||||
|
||||
Assert.Equal(expectedOutput.hintName, actualOutput.Key);
|
||||
Assert.Equal(expectedOutput.text, actualOutput.Value, ignoreWhiteSpaceDifferences: true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string CreateBaselineDirectory(string testPath, string testName)
|
||||
{
|
||||
var baselineDirectory = Path.Join(
|
||||
|
@ -490,9 +515,9 @@ internal static class Extensions
|
|||
}
|
||||
}
|
||||
|
||||
private static string GenerateExpectedOutput(GeneratorRunResult result)
|
||||
private static string GenerateExpectedPageOutput(GeneratorRunResult result)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("Generated Output:").AppendLine().AppendLine();
|
||||
StringBuilder sb = new StringBuilder("Generated Page Output:").AppendLine().AppendLine();
|
||||
for (int i = 0; i < result.GeneratedSources.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
|
@ -504,6 +529,22 @@ internal static class Extensions
|
|||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static string GenerateExpectedHostOutput(GeneratorRunResult result)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder("Generated Host Output:").AppendLine().AppendLine();
|
||||
var hostOutputs = result.GetHostOutputs();
|
||||
for (int i = 0; i < hostOutputs.Length; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
sb.AppendLine(",");
|
||||
}
|
||||
sb.Append("(@\"").Append(hostOutputs[i].Key.Replace("\"", "\"\"")).Append("\", ");
|
||||
sb.Append("@\"").Append(hostOutputs[i].Value.Replace("\"", "\"\"")).Append("\")");
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static GeneratorRunResult VerifyOutputsMatch(this GeneratorRunResult actual, GeneratorRunResult expected, params (int index, string replacement)[] diffs)
|
||||
{
|
||||
Assert.Equal(actual.GeneratedSources.Length, expected.GeneratedSources.Length);
|
||||
|
@ -532,4 +573,19 @@ internal static class Extensions
|
|||
Assert.StartsWith("#pragma", trimmed);
|
||||
return trimmed.Substring(trimmed.IndexOf('\n') + 1);
|
||||
}
|
||||
|
||||
public static void AssertSingleItem(this RazorEventListener.RazorEvent e, string expectedEventName, string expectedFileName)
|
||||
{
|
||||
Assert.Equal(expectedEventName, e.EventName);
|
||||
var file = Assert.Single(e.Payload);
|
||||
Assert.Equal(expectedFileName, file);
|
||||
}
|
||||
|
||||
public static void AssertPair(this RazorEventListener.RazorEvent e, string expectedEventName, string payload1, string payload2)
|
||||
{
|
||||
Assert.Equal(expectedEventName, e.EventName);
|
||||
Assert.Equal(2, e.Payload.Length);
|
||||
Assert.Equal(payload1, e.Payload[0]);
|
||||
Assert.Equal(payload2, e.Payload[1]);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче