зеркало из https://github.com/dotnet/razor.git
Rework PooledArrayBuilder<T> for small arrays (#9269)
This change uses a similar approach to Roslyn's `TemporaryArray<T>` to avoid retrieving an `ImmutableArray<T>.Builder` from the pool for arrays of 4 or fewer elements. The first four items added to the builder are stored on the stack. As part of this change, I've added a new `Razor.Diagnostics.Analyzers` project that should contain any analyzers that we write specifically for the Razor repo. These shouldn't be deployed; they're for internal consumption only. I've added a variant of the `TemporaryArrayAsRefAnalyzer` from the `Roslyn.Diagnostics.Analyzers` to enforce that `PooledArrayBuilder<T>.AsRef()` can only be called on local builders in a using statement.
This commit is contained in:
Коммит
cf76071cbd
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.8.34117.57
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Razor.Diagnostics.Analyzers", "src\Analyzers\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj", "{42438A8F-6284-443A-A518-9AAD5371A403}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{42438A8F-6284-443A-A518-9AAD5371A403}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{42438A8F-6284-443A-A518-9AAD5371A403}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{42438A8F-6284-443A-A518-9AAD5371A403}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{42438A8F-6284-443A-A518-9AAD5371A403}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {F62A910A-9F8F-44CD-B8D7-8D7A88FF902A}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -2,6 +2,8 @@
|
|||
"solution": {
|
||||
"path": "Razor.sln",
|
||||
"projects": [
|
||||
"src\\Analyzers\\Razor.Diagnostics.Analyzers\\Razor.Diagnostics.Analyzers.csproj",
|
||||
"src\\Analyzers\\Razor.Diagnostics.Analyzers.Test\\Razor.Diagnostics.Analyzers.Test.csproj",
|
||||
"src\\Compiler\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\\src\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.csproj",
|
||||
"src\\Compiler\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X\\test\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version1_X.Test.csproj",
|
||||
"src\\Compiler\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X\\src\\Microsoft.AspNetCore.Mvc.Razor.Extensions.Version2_X.csproj",
|
||||
|
@ -12,9 +14,9 @@
|
|||
"src\\Compiler\\Microsoft.AspNetCore.Razor.Language\\test\\Microsoft.AspNetCore.Razor.Language.Test.csproj",
|
||||
"src\\Compiler\\Microsoft.CodeAnalysis.Razor\\src\\Microsoft.CodeAnalysis.Razor.csproj",
|
||||
"src\\Compiler\\Microsoft.CodeAnalysis.Razor\\test\\Microsoft.CodeAnalysis.Razor.Test.csproj",
|
||||
"src\\Compiler\\Microsoft.Net.Compilers.Razor.Toolset\\Microsoft.Net.Compilers.Razor.Toolset.csproj",
|
||||
"src\\Compiler\\Microsoft.NET.Sdk.Razor.SourceGenerators.Transport\\Microsoft.NET.Sdk.Razor.SourceGenerators.Transport.csproj",
|
||||
"src\\Compiler\\Microsoft.NET.Sdk.Razor.SourceGenerators\\Microsoft.NET.Sdk.Razor.SourceGenerators.csproj",
|
||||
"src\\Compiler\\Microsoft.Net.Compilers.Razor.Toolset\\Microsoft.Net.Compilers.Razor.Toolset.csproj",
|
||||
"src\\Compiler\\test\\Microsoft.AspNetCore.Razor.Test.Common\\Microsoft.AspNetCore.Razor.Test.Common.Compiler.csproj",
|
||||
"src\\Compiler\\test\\Microsoft.AspNetCore.Razor.Test.ComponentShim\\Microsoft.AspNetCore.Razor.Test.ComponentShim.Compiler.csproj",
|
||||
"src\\Compiler\\test\\Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X\\Microsoft.AspNetCore.Razor.Test.MvcShim.Version1_X.Compiler.csproj",
|
||||
|
@ -44,7 +46,8 @@
|
|||
"src\\Razor\\test\\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.Test\\Microsoft.VisualStudio.LanguageServer.ContainedLanguage.Test.csproj",
|
||||
"src\\Razor\\test\\Microsoft.VisualStudio.LanguageServices.Razor.Test\\Microsoft.VisualStudio.LanguageServices.Razor.Test.csproj",
|
||||
"src\\Razor\\test\\Microsoft.VisualStudio.LiveShare.Razor.Test\\Microsoft.VisualStudio.LiveShare.Razor.Test.csproj",
|
||||
"src\\Shared\\Microsoft.AspNetCore.Razor.Utilities.Shared.Test\\Microsoft.AspNetCore.Razor.Utilities.Shared.Test.csproj",
|
||||
"src\\Shared\\Microsoft.AspNetCore.Razor.Utilities.Shared\\Microsoft.AspNetCore.Razor.Utilities.Shared.csproj"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
57
Razor.sln
57
Razor.sln
|
@ -103,8 +103,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Sdk.Razor.Sou
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{3AE210D1-C435-4693-BF79-2EF13ED554B9}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Utilities.Shared", "src\Shared\Microsoft.AspNetCore.Razor.Utilities.Shared\Microsoft.AspNetCore.Razor.Utilities.Shared.csproj", "{BEF172F0-D1C2-4043-BF45-8E520FF79321}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions", "Microsoft.AspNetCore.Mvc.Razor.Extensions", "{DE461FC6-663E-4362-9B33-C5A88C7B4DB8}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Mvc.Razor.Extensions.Test", "src\Compiler\Microsoft.AspNetCore.Mvc.Razor.Extensions\test\Microsoft.AspNetCore.Mvc.Razor.Extensions.Test.csproj", "{7BDA653C-6164-4ACB-913B-C7BB91E2390A}"
|
||||
|
@ -171,6 +169,16 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.ProjectEngineHost.Test", "src\Razor\test\Microsoft.AspNetCore.Razor.ProjectEngineHost.Test\Microsoft.AspNetCore.Razor.ProjectEngineHost.Test.csproj", "{4126E0A6-1CA9-44B1-AD22-66EDB9FEE7AD}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Utilities.Shared.Test", "src\Shared\Microsoft.AspNetCore.Razor.Utilities.Shared.Test\Microsoft.AspNetCore.Razor.Utilities.Shared.Test.csproj", "{7275F376-1B63-49D3-8078-0F7CA15CC637}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.AspNetCore.Razor.Utilities.Shared", "src\Shared\Microsoft.AspNetCore.Razor.Utilities.Shared\Microsoft.AspNetCore.Razor.Utilities.Shared.csproj", "{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Analyzers", "Analyzers", "{4AA319E0-C81E-47CC-841A-6EFCB6784A1F}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Razor.Diagnostics.Analyzers", "src\Analyzers\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj", "{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Razor.Diagnostics.Analyzers.Test", "src\Analyzers\Razor.Diagnostics.Analyzers.Test\Razor.Diagnostics.Analyzers.Test.csproj", "{167F1426-D9AE-49DF-B214-F00536DBC305}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -499,14 +507,6 @@ Global
|
|||
{A2DED0B8-1A7E-4E3D-A820-691BB4500610}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{A2DED0B8-1A7E-4E3D-A820-691BB4500610}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{A2DED0B8-1A7E-4E3D-A820-691BB4500610}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{7BDA653C-6164-4ACB-913B-C7BB91E2390A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7BDA653C-6164-4ACB-913B-C7BB91E2390A}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7BDA653C-6164-4ACB-913B-C7BB91E2390A}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
|
@ -707,6 +707,38 @@ Global
|
|||
{4126E0A6-1CA9-44B1-AD22-66EDB9FEE7AD}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4126E0A6-1CA9-44B1-AD22-66EDB9FEE7AD}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4126E0A6-1CA9-44B1-AD22-66EDB9FEE7AD}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.DebugNoVSIX|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.DebugNoVSIX|Any CPU.Build.0 = Debug|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.ReleaseNoVSIX|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305}.ReleaseNoVSIX|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -752,7 +784,6 @@ Global
|
|||
{EF6275D9-682E-4ED9-85BB-92AFF18169CE} = {9B419123-4D1D-4ADB-ABB0-C324ED5A62E3}
|
||||
{DE2A3AB5-3CE4-4CB3-BF46-1D54E537D130} = {F8C0166A-2714-44AA-87B5-3365F1FB1AE2}
|
||||
{A2DED0B8-1A7E-4E3D-A820-691BB4500610} = {AA4EE974-E765-4B97-AF35-F734BF9830F6}
|
||||
{BEF172F0-D1C2-4043-BF45-8E520FF79321} = {3AE210D1-C435-4693-BF79-2EF13ED554B9}
|
||||
{DE461FC6-663E-4362-9B33-C5A88C7B4DB8} = {5B60F564-4AD7-4B70-A887-7D91496799A2}
|
||||
{7BDA653C-6164-4ACB-913B-C7BB91E2390A} = {DE461FC6-663E-4362-9B33-C5A88C7B4DB8}
|
||||
{9B419123-4D1D-4ADB-ABB0-C324ED5A62E3} = {5B60F564-4AD7-4B70-A887-7D91496799A2}
|
||||
|
@ -785,6 +816,10 @@ Global
|
|||
{53977089-1A87-4521-8368-0D50DFDA1279} = {3C0D6505-79B3-49D0-B4C3-176F0F1836ED}
|
||||
{C0C2AD17-5F5B-4B11-956D-203D91C377FB} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{4126E0A6-1CA9-44B1-AD22-66EDB9FEE7AD} = {92463391-81BE-462B-AC3C-78C6C760741F}
|
||||
{7275F376-1B63-49D3-8078-0F7CA15CC637} = {3AE210D1-C435-4693-BF79-2EF13ED554B9}
|
||||
{BAFE178B-7AD4-41AE-A75D-9B920B9EA050} = {3AE210D1-C435-4693-BF79-2EF13ED554B9}
|
||||
{45B207E2-DDB3-44F0-87C5-DEFB5A9534A5} = {4AA319E0-C81E-47CC-841A-6EFCB6784A1F}
|
||||
{167F1426-D9AE-49DF-B214-F00536DBC305} = {4AA319E0-C81E-47CC-841A-6EFCB6784A1F}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0035341D-175A-4D05-95E6-F1C2785A1E26}
|
||||
|
|
|
@ -2,10 +2,13 @@
|
|||
|
||||
<Target Name="_PublishLanguageServerRids" AfterTargets="Pack" Condition="'$(DotNetBuildFromSource)' != 'true'">
|
||||
<PropertyGroup>
|
||||
<BuildAnalyzersSolutionPath>$(MSBuildThisFileDirectory)..\BuildAnalyzers.sln</BuildAnalyzersSolutionPath>
|
||||
<LanguageServerProject>$(MSBuildThisFileDirectory)..\src\Razor\src\rzls\rzls.csproj</LanguageServerProject>
|
||||
<RazorSolutionPath>$(MSBuildThisFileDirectory)..\Razor.sln</RazorSolutionPath>
|
||||
</PropertyGroup>
|
||||
|
||||
<MSBuild Projects="$(BuildAnalyzersSolutionPath)"
|
||||
Targets="Restore" />
|
||||
<MSBuild Projects="$(RazorSolutionPath)"
|
||||
Targets="Restore" />
|
||||
<MSBuild Projects="$(LanguageServerProject)"
|
||||
|
|
|
@ -6,6 +6,13 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Note: It is important BuildAnalyzers.sln builds first and does not allow building in parallel.
|
||||
Because projects in Razor.sln (or Razor.Slim.slnf) have a project reference to Razor.Diagnostics.Analyzers
|
||||
that is treated as an analyzer, there can be file locking issues if Razor.Diagnostics.Analyzers isn't
|
||||
built before Razor.sln. Setting "BuildInParallel" to "false" ensures that this solution will be fully
|
||||
built first. -->
|
||||
<ProjectToBuild Include="$(RepoRoot)BuildAnalyzers.sln" BuildInParallel="false" />
|
||||
|
||||
<ProjectToBuild Condition="'$(OS)'=='WINDOWS_NT' and '$(SdkTaskProjects)'==''" Include="$(MSBuildThisFileDirectory)..\Razor.sln" />
|
||||
|
||||
<!-- Exclude VSIX projects on non-Windows -->
|
||||
|
|
|
@ -110,7 +110,9 @@
|
|||
<MicrosoftNETSdkRazorPackageVersion>6.0.0-alpha.1.21072.5</MicrosoftNETSdkRazorPackageVersion>
|
||||
<!-- Packages from dotnet/roslyn -->
|
||||
<MicrosoftNetCompilersToolsetVersion>$(MicrosoftNetCompilersToolsetPackageVersion)</MicrosoftNetCompilersToolsetVersion>
|
||||
<MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>1.1.2-beta1.23323.1</MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>
|
||||
<MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>1.1.2-beta1.23431.1</MicrosoftCodeAnalysisAnalyzerTestingPackageVersion>
|
||||
<MicrosoftCodeAnalysisCSharpAnalyzerTestingXUnitPackageVersion>1.1.2-beta1.23431.1</MicrosoftCodeAnalysisCSharpAnalyzerTestingXUnitPackageVersion>
|
||||
<MicrosoftCodeAnalysisTestingVerifiersXUnitPackageVersion>1.1.2-beta1.23431.1</MicrosoftCodeAnalysisTestingVerifiersXUnitPackageVersion>
|
||||
<MicrosoftVisualStudioEditorPackageVersion>$(MicrosoftVisualStudioPackagesVersion)</MicrosoftVisualStudioEditorPackageVersion>
|
||||
<MicrosoftVisualStudioExtensibilityTestingXunitVersion>0.1.169-beta</MicrosoftVisualStudioExtensibilityTestingXunitVersion>
|
||||
<MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>$(MicrosoftVisualStudioExtensibilityTestingXunitVersion)</MicrosoftVisualStudioExtensibilityTestingSourceGeneratorVersion>
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
<Project>
|
||||
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory).., Directory.Build.props))\Directory.Build.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<PackageTags>aspnetcore;cshtml;razor</PackageTags>
|
||||
<IsPackable>true</IsPackable>
|
||||
<IsShipping>true</IsShipping>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<EnforceCodeStyleInBuild>true</EnforceCodeStyleInBuild>
|
||||
|
||||
<!-- In theory we want to have this property set, but our pipeline doesn't set the access tokens yet -->
|
||||
<PublishWindowsPdb Condition="'$(DotNetSymbolServerTokenMsdl)'!='' and '$(DotNetSymbolServerTokenSymWeb)'!=''">true</PublishWindowsPdb>
|
||||
|
||||
<RollForward Condition="'$(IsTestProject)' == 'true'">LatestMajor</RollForward>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(DotNetBuildFromSource)' != 'true'">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="$(Tooling_MicrosoftCodeAnalysisAnalyzersPackageVersion)" NoWarn="NU1608" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="$(Tooling_MicrosoftCodeAnalysisBannedApiAnalyzersPackageVersion)" />
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="$(Tooling_RoslynDiagnosticsAnalyzersPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers.Test;
|
||||
|
||||
using VerifyCS = CSharpAnalyzerVerifier<PooledArrayBuilderAsRefAnalyzer>;
|
||||
|
||||
public class PooledArrayBuilderAsRefAnalyzerTests
|
||||
{
|
||||
private const string PooledArrayBuilderSource = """
|
||||
namespace Microsoft.AspNetCore.Razor.PooledObjects
|
||||
{
|
||||
internal struct PooledArrayBuilder<T> : System.IDisposable
|
||||
{
|
||||
public void Dispose() { }
|
||||
}
|
||||
|
||||
internal static class PooledArrayBuilderExtensions
|
||||
{
|
||||
public static ref PooledArrayBuilder<T> AsRef<T>(this in PooledArrayBuilder<T> array) => throw null;
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
[Fact]
|
||||
public async Task TestUsingVariable_CSharpAsync()
|
||||
{
|
||||
var code = $$"""
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
class C
|
||||
{
|
||||
void Method()
|
||||
{
|
||||
using (var array = new PooledArrayBuilder<int>())
|
||||
{
|
||||
ref var arrayRef1 = ref array.AsRef();
|
||||
ref var arrayRef2 = ref PooledArrayBuilderExtensions.AsRef(in array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{{PooledArrayBuilderSource}}
|
||||
""";
|
||||
|
||||
await new VerifyCS.Test
|
||||
{
|
||||
TestCode = code,
|
||||
}.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TestUsingDeclarationVariable_CSharpAsync()
|
||||
{
|
||||
var code = $$"""
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
class C
|
||||
{
|
||||
void Method()
|
||||
{
|
||||
using var array = new PooledArrayBuilder<int>();
|
||||
ref var arrayRef1 = ref array.AsRef();
|
||||
ref var arrayRef2 = ref PooledArrayBuilderExtensions.AsRef(in array);
|
||||
}
|
||||
}
|
||||
|
||||
{{PooledArrayBuilderSource}}
|
||||
""";
|
||||
|
||||
await new VerifyCS.Test
|
||||
{
|
||||
TestCode = code,
|
||||
}.RunAsync();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TestNonUsingVariable_CSharpAsync()
|
||||
{
|
||||
var code = $$"""
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
class C
|
||||
{
|
||||
void Method()
|
||||
{
|
||||
var array = new PooledArrayBuilder<int>();
|
||||
ref var arrayRef1 = ref [|array.AsRef()|];
|
||||
ref var arrayRef2 = ref [|PooledArrayBuilderExtensions.AsRef(in array)|];
|
||||
}
|
||||
}
|
||||
|
||||
{{PooledArrayBuilderSource}}
|
||||
""";
|
||||
|
||||
await new VerifyCS.Test
|
||||
{
|
||||
TestCode = code,
|
||||
}.RunAsync();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(DefaultNetCoreTargetFrameworks)</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);$(DefaultNetFxTargetFramework)</TargetFrameworks>
|
||||
<IsShippingPackage>false</IsShippingPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="$(MicrosoftCodeAnalysisCSharpWorkspacesPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Analyzer.Testing.XUnit" Version="$(MicrosoftCodeAnalysisCSharpAnalyzerTestingXUnitPackageVersion)" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Testing.Verifiers.XUnit" Version="$(MicrosoftCodeAnalysisTestingVerifiersXUnitPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,28 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers.Test;
|
||||
|
||||
public static partial class CSharpAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
public class Test : CSharpAnalyzerTest<TAnalyzer, XUnitVerifier>
|
||||
{
|
||||
public Test()
|
||||
{
|
||||
SolutionTransforms.Add((solution, projectId) =>
|
||||
{
|
||||
var compilationOptions = solution.GetProject(projectId)!.CompilationOptions;
|
||||
compilationOptions = compilationOptions!.WithSpecificDiagnosticOptions(
|
||||
compilationOptions.SpecificDiagnosticOptions.SetItems(CSharpVerifierHelper.NullableWarnings));
|
||||
solution = solution.WithProjectCompilationOptions(projectId, compilationOptions);
|
||||
|
||||
return solution;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp.Testing;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Testing;
|
||||
using Microsoft.CodeAnalysis.Testing.Verifiers;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers.Test;
|
||||
|
||||
public static partial class CSharpAnalyzerVerifier<TAnalyzer>
|
||||
where TAnalyzer : DiagnosticAnalyzer, new()
|
||||
{
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic()"/>
|
||||
public static DiagnosticResult Diagnostic()
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, XUnitVerifier>.Diagnostic();
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(string)"/>
|
||||
public static DiagnosticResult Diagnostic(string diagnosticId)
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, XUnitVerifier>.Diagnostic(diagnosticId);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/>
|
||||
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor)
|
||||
=> CSharpAnalyzerVerifier<TAnalyzer, XUnitVerifier>.Diagnostic(descriptor);
|
||||
|
||||
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.VerifyAnalyzerAsync(string, DiagnosticResult[])"/>
|
||||
public static async Task VerifyAnalyzerAsync(string source, params DiagnosticResult[] expected)
|
||||
{
|
||||
var test = new Test
|
||||
{
|
||||
TestCode = source,
|
||||
};
|
||||
|
||||
test.ExpectedDiagnostics.AddRange(expected);
|
||||
await test.RunAsync(CancellationToken.None);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers.Test;
|
||||
|
||||
internal static class CSharpVerifierHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// By default, the compiler reports diagnostics for nullable reference types at
|
||||
/// <see cref="DiagnosticSeverity.Warning"/>, and the analyzer test framework defaults to only validating
|
||||
/// diagnostics at <see cref="DiagnosticSeverity.Error"/>. This map contains all compiler diagnostic IDs
|
||||
/// related to nullability mapped to <see cref="ReportDiagnostic.Error"/>, which is then used to enable all
|
||||
/// of these warnings for default validation during analyzer and code fix tests.
|
||||
/// </summary>
|
||||
internal static ImmutableDictionary<string, ReportDiagnostic> NullableWarnings { get; } = GetNullableWarningsFromCompiler();
|
||||
|
||||
private static ImmutableDictionary<string, ReportDiagnostic> GetNullableWarningsFromCompiler()
|
||||
{
|
||||
string[] args = { "/warnaserror:nullable" };
|
||||
var commandLineArguments = CSharpCommandLineParser.Default.Parse(args, baseDirectory: Environment.CurrentDirectory, sdkDirectory: Environment.CurrentDirectory);
|
||||
var nullableWarnings = commandLineArguments.CompilationOptions.SpecificDiagnosticOptions;
|
||||
|
||||
// Workaround for https://github.com/dotnet/roslyn/issues/41610
|
||||
nullableWarnings = nullableWarnings
|
||||
.SetItem("CS8632", ReportDiagnostic.Error)
|
||||
.SetItem("CS8669", ReportDiagnostic.Error);
|
||||
|
||||
return nullableWarnings;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
internal static class DiagnosticCategory
|
||||
{
|
||||
public const string Reliability = nameof(Reliability);
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
internal static class DiagnosticIds
|
||||
{
|
||||
public const string PooledArrayBuilderAsRef = "RZD001";
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
internal static class Extensions
|
||||
{
|
||||
public static Diagnostic CreateDiagnostic(this IOperation operation, DiagnosticDescriptor rule)
|
||||
{
|
||||
var location = operation.Syntax.GetLocation();
|
||||
|
||||
if (!location.IsInSource)
|
||||
{
|
||||
location = Location.None;
|
||||
}
|
||||
|
||||
return Diagnostic.Create(rule, location);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("MicrosoftCodeAnalysisReleaseTracking", "RS2008:Enable analyzer release tracking", Justification = "<Pending>", Scope = "member", Target = "~F:Razor.Diagnostics.Analyzers.PooledArrayBuilderAsRefAnalyzer.Rule")]
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Diagnostics;
|
||||
using Microsoft.CodeAnalysis.Operations;
|
||||
using static Razor.Diagnostics.Analyzers.Resources;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
[DiagnosticAnalyzer(LanguageNames.CSharp)]
|
||||
public class PooledArrayBuilderAsRefAnalyzer : DiagnosticAnalyzer
|
||||
{
|
||||
internal static readonly DiagnosticDescriptor Rule = new(
|
||||
DiagnosticIds.PooledArrayBuilderAsRef,
|
||||
CreateLocalizableResourceString(nameof(PooledArrayBuilderAsRefTitle)),
|
||||
CreateLocalizableResourceString(nameof(PooledArrayBuilderAsRefMessage)),
|
||||
DiagnosticCategory.Reliability,
|
||||
DiagnosticSeverity.Warning,
|
||||
isEnabledByDefault: true,
|
||||
description: CreateLocalizableResourceString(nameof(PooledArrayBuilderAsRefDescription)));
|
||||
|
||||
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
|
||||
|
||||
public override void Initialize(AnalysisContext context)
|
||||
{
|
||||
context.EnableConcurrentExecution();
|
||||
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
|
||||
|
||||
context.RegisterCompilationStartAction(context =>
|
||||
{
|
||||
var pooledArrayBuilderExtensions = context.Compilation.GetTypeByMetadataName(WellKnownTypeNames.PooledArrayBuilderExtensions);
|
||||
if (pooledArrayBuilderExtensions is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pooledArrayBuilderAsRef = (IMethodSymbol?)pooledArrayBuilderExtensions.GetMembers("AsRef").SingleOrDefault();
|
||||
if (pooledArrayBuilderAsRef is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
context.RegisterOperationAction(context => AnalyzeInvocation(context, pooledArrayBuilderAsRef), OperationKind.Invocation);
|
||||
});
|
||||
}
|
||||
|
||||
private static void AnalyzeInvocation(OperationAnalysisContext context, IMethodSymbol pooledArrayBuilderAsRef)
|
||||
{
|
||||
var invocation = (IInvocationOperation)context.Operation;
|
||||
var targetMethod = invocation.TargetMethod.ReducedFrom ?? invocation.TargetMethod;
|
||||
if (!SymbolEqualityComparer.Default.Equals(targetMethod.OriginalDefinition, pooledArrayBuilderAsRef))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var instance = invocation.Instance ?? invocation.Arguments.FirstOrDefault()?.Value;
|
||||
if (instance is not ILocalReferenceOperation localReference)
|
||||
{
|
||||
context.ReportDiagnostic(invocation.CreateDiagnostic(Rule));
|
||||
return;
|
||||
}
|
||||
|
||||
var declaration = invocation.SemanticModel!.GetOperation(localReference.Local.DeclaringSyntaxReferences.Single().GetSyntax(context.CancellationToken), context.CancellationToken);
|
||||
if (declaration is not { Parent: IVariableDeclarationOperation { Parent: IVariableDeclarationGroupOperation { Parent: IUsingOperation or IUsingDeclarationOperation } } })
|
||||
{
|
||||
context.ReportDiagnostic(invocation.CreateDiagnostic(Rule));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
|
||||
<ExcludeFromSourceBuild>false</ExcludeFromSourceBuild>
|
||||
<IsShippingPackage>false</IsShippingPackage>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="$(MicrosoftCodeAnalysisCSharpPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
internal partial class Resources
|
||||
{
|
||||
private static readonly Type s_resourcesType = typeof(Resources);
|
||||
|
||||
public static LocalizableResourceString CreateLocalizableResourceString(string nameOfLocalizableResource)
|
||||
=> new(nameOfLocalizableResource, ResourceManager, s_resourcesType);
|
||||
|
||||
public static LocalizableResourceString CreateLocalizableResourceString(string nameOfLocalizableResource, params string[] formatArguments)
|
||||
=> new(nameOfLocalizableResource, ResourceManager, s_resourcesType, formatArguments);
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="PooledArrayBuilderAsRefDescription" xml:space="preserve">
|
||||
<value>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</value>
|
||||
<comment>An optional longer localizable description of the diagnostic.</comment>
|
||||
</data>
|
||||
<data name="PooledArrayBuilderAsRefMessage" xml:space="preserve">
|
||||
<value>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</value>
|
||||
<comment>The format-able message the diagnostic displays.</comment>
|
||||
</data>
|
||||
<data name="PooledArrayBuilderAsRefTitle" xml:space="preserve">
|
||||
<value>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</value>
|
||||
<comment>The title of the diagnostic.</comment>
|
||||
</data>
|
||||
</root>
|
|
@ -0,0 +1,9 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
namespace Razor.Diagnostics.Analyzers;
|
||||
|
||||
internal static class WellKnownTypeNames
|
||||
{
|
||||
public const string PooledArrayBuilderExtensions = "Microsoft.AspNetCore.Razor.PooledObjects.PooledArrayBuilderExtensions";
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="cs" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="de" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="es" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="fr" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="it" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="ja" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="ko" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="pl" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="pt-BR" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="ru" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="tr" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="zh-Hans" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.2" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en" target-language="zh-Hant" original="../Resources.resx">
|
||||
<body>
|
||||
<trans-unit id="PooledArrayBuilderAsRefDescription">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable.</target>
|
||||
<note>An optional longer localizable description of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefMessage">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The format-able message the diagnostic displays.</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="PooledArrayBuilderAsRefTitle">
|
||||
<source>Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</source>
|
||||
<target state="new">Instance of PooledArrayBuilder<T>.AsRef() must be a 'using' variable</target>
|
||||
<note>The title of the diagnostic.</note>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
|
@ -40,5 +40,10 @@
|
|||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" NoWarn="NU1608" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" PrivateAssets="All" />
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" PrivateAssets="All" />
|
||||
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\Analyzers\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj"
|
||||
PrivateAssets="all"
|
||||
ReferenceOutputAssembly="false"
|
||||
OutputItemType="Analyzer" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -495,16 +495,16 @@ internal abstract partial class SyntaxNode
|
|||
|
||||
// Walk backwards until we find a non-whitespace token. We accomplish this by looking up the stack and walking nodes backwards from where we
|
||||
// were located.
|
||||
if (tryWalkBackwards(stack, out foundToken))
|
||||
if (tryWalkBackwards(ref stack.AsRef(), out foundToken))
|
||||
{
|
||||
return foundToken;
|
||||
}
|
||||
|
||||
// Encountered a newline while backtracking, so we need to walk forward instead.
|
||||
return walkForward(stack);
|
||||
return walkForward(ref stack.AsRef());
|
||||
}
|
||||
|
||||
bool tryWalkBackwards(PooledArrayBuilder<(SyntaxNode node, int nodeIndexInParent)> stack, [NotNullWhen(true)] out SyntaxToken? foundToken)
|
||||
bool tryWalkBackwards(ref PooledArrayBuilder<(SyntaxNode node, int nodeIndexInParent)> stack, [NotNullWhen(true)] out SyntaxToken? foundToken)
|
||||
{
|
||||
// Can't just pop the stack, we may need to rewalk from the start to find the next node if this fails
|
||||
for (var originalStackPosition = stack.Count - 1; originalStackPosition >= 0; originalStackPosition--)
|
||||
|
@ -528,7 +528,7 @@ internal abstract partial class SyntaxNode
|
|||
throw new ArgumentOutOfRangeException(nameof(position));
|
||||
}
|
||||
|
||||
SyntaxToken walkForward(PooledArrayBuilder<(SyntaxNode node, int nodeIndexInParent)> stack)
|
||||
SyntaxToken walkForward(ref PooledArrayBuilder<(SyntaxNode node, int nodeIndexInParent)> stack)
|
||||
{
|
||||
while (stack.TryPop(out var entry))
|
||||
{
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="$(Tooling_MicrosoftCodeAnalysisAnalyzersPackageVersion)" NoWarn="NU1608" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="$(Tooling_MicrosoftCodeAnalysisBannedApiAnalyzersPackageVersion)" />
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="$(Tooling_RoslynDiagnosticsAnalyzersPackageVersion)" />
|
||||
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\Analyzers\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj"
|
||||
PrivateAssets="all"
|
||||
ReferenceOutputAssembly="false"
|
||||
OutputItemType="Analyzer" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -299,6 +299,7 @@
|
|||
<ItemGroup>
|
||||
<BindingRedirectAssemblies Include="@(ProjectReference)" AssemblyName="%(Filename)" />
|
||||
<BindingRedirectAssemblies Remove="@(ProjectReference)" Condition="%(ProjectReference.Name) == 'Microsoft.CodeAnalysis.Remote.Razor.CoreComponents'" />
|
||||
<BindingRedirectAssemblies Remove="@(ProjectReference)" Condition="%(ProjectReference.ReferenceOutputAssembly) == 'false'" />
|
||||
<BindingRedirectAssemblies Include="$(AssemblyName)" AssemblyName="$(AssemblyName)" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Razor.Serialization.Json;
|
||||
using Microsoft.AspNetCore.Razor.Test.Common;
|
||||
using Microsoft.AspNetCore.Razor.Utilities;
|
||||
using Xunit;
|
||||
|
|
|
@ -10,12 +10,19 @@
|
|||
|
||||
<!-- In theory we want to have this property set, but our pipeline doesn't set the access tokens yet -->
|
||||
<PublishWindowsPdb Condition="'$(DotNetSymbolServerTokenMsdl)'!='' and '$(DotNetSymbolServerTokenSymWeb)'!=''">true</PublishWindowsPdb>
|
||||
|
||||
<RollForward Condition="'$(IsTestProject)' == 'true'">LatestMajor</RollForward>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition="'$(DotNetBuildFromSource)' != 'true'">
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.Analyzers" Version="$(Tooling_MicrosoftCodeAnalysisAnalyzersPackageVersion)" NoWarn="NU1608" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="$(Tooling_MicrosoftCodeAnalysisBannedApiAnalyzersPackageVersion)" />
|
||||
<PackageReference Include="Roslyn.Diagnostics.Analyzers" Version="$(Tooling_RoslynDiagnosticsAnalyzersPackageVersion)" />
|
||||
|
||||
<ProjectReference Include="$(MSBuildThisFileDirectory)..\Analyzers\Razor.Diagnostics.Analyzers\Razor.Diagnostics.Analyzers.csproj"
|
||||
PrivateAssets="all"
|
||||
ReferenceOutputAssembly="false"
|
||||
OutputItemType="Analyzer" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>$(DefaultNetCoreTargetFrameworks)</TargetFrameworks>
|
||||
<TargetFrameworks Condition="'$(OS)' == 'Windows_NT'">$(TargetFrameworks);$(DefaultNetFxTargetFramework)</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="xunit.runner.json" CopyToOutputDirectory="PreserveNewest" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Microsoft.AspNetCore.Razor.Utilities.Shared\Microsoft.AspNetCore.Razor.Utilities.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Xunit.Combinatorial" Version="$(XunitCombinatorialPackageVersion)" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Utilities.Shared.Test.PooledObjects;
|
||||
|
||||
public class PooledArrayBuilderTests
|
||||
{
|
||||
[Theory]
|
||||
[CombinatorialData]
|
||||
public void AddElements([CombinatorialRange(0, 8)] int count)
|
||||
{
|
||||
using var builder = new PooledArrayBuilder<int>();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
builder.Add(i);
|
||||
}
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
Assert.Equal(i, builder[i]);
|
||||
}
|
||||
|
||||
var result = builder.DrainToImmutable();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
Assert.Equal(i, result[i]);
|
||||
}
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> RemoveAtIndex_Data
|
||||
{
|
||||
get
|
||||
{
|
||||
for (var count = 0; count < 8; count++)
|
||||
{
|
||||
for (var removeIndex = 0; removeIndex < 8; removeIndex++)
|
||||
{
|
||||
if (removeIndex < count)
|
||||
{
|
||||
yield return new object[] { count, removeIndex };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(RemoveAtIndex_Data))]
|
||||
public void RemoveAtIndex(int count, int removeIndex)
|
||||
{
|
||||
using var builder = new PooledArrayBuilder<int>();
|
||||
|
||||
for (var i = 0; i < count; i++)
|
||||
{
|
||||
builder.Add(i);
|
||||
}
|
||||
|
||||
var newCount = count;
|
||||
var newValue = removeIndex;
|
||||
|
||||
// Now, remove each element at removeIndex.
|
||||
for (var i = removeIndex; i < builder.Count; i++)
|
||||
{
|
||||
builder.RemoveAt(removeIndex);
|
||||
newCount--;
|
||||
newValue++;
|
||||
|
||||
Assert.Equal(newCount, builder.Count);
|
||||
|
||||
// Check the values starting at removeIndex.
|
||||
for (var j = removeIndex; j < newCount; j++)
|
||||
{
|
||||
Assert.Equal(newValue + (j - removeIndex), builder[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"methodDisplay": "method",
|
||||
"shadowCopy": false,
|
||||
"parallelizeTestCollections": false
|
||||
}
|
|
@ -29,4 +29,34 @@ internal static class EnumerableExtensions
|
|||
return results.DrainToImmutable();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetCount<T>(this IEnumerable<T> sequence, out int count)
|
||||
{
|
||||
#if NET6_0_OR_GREATER
|
||||
return Linq.Enumerable.TryGetNonEnumeratedCount(sequence, out count);
|
||||
#else
|
||||
return TryGetCount<T>((IEnumerable)sequence, out count);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static bool TryGetCount<T>(this IEnumerable sequence, out int count)
|
||||
{
|
||||
switch (sequence)
|
||||
{
|
||||
case ICollection collection:
|
||||
count = collection.Count;
|
||||
return true;
|
||||
|
||||
case ICollection<T> collection:
|
||||
count = collection.Count;
|
||||
return true;
|
||||
|
||||
case IReadOnlyCollection<T> collection:
|
||||
count = collection.Count;
|
||||
return true;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ using Microsoft.Extensions.ObjectPool;
|
|||
|
||||
namespace Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
internal static partial class PooledObjectExtensions
|
||||
internal static partial class Extensions
|
||||
{
|
||||
public static PooledObject<T> GetPooledObject<T>(this ObjectPool<T> pool)
|
||||
where T : class
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
internal static class PooledArrayBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a mutable reference to a <see cref="PooledArrayBuilder{T}"/> stored in a <c>using</c> variable.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>This supporting method allows <see cref="PooledArrayBuilder{T}"/>, a non-copyable <see langword="struct"/>
|
||||
/// implementing <see cref="IDisposable"/>, to be used with <c>using</c> statements while still allowing them to
|
||||
/// be passed by reference in calls. The following two calls are equivalent:</para>
|
||||
///
|
||||
/// <code>
|
||||
/// using var array = PooledArrayBuilder<T>.Empty;
|
||||
///
|
||||
/// // Using the 'Unsafe.AsRef' method
|
||||
/// Method(ref Unsafe.AsRef(in builder));
|
||||
///
|
||||
/// // Using this helper method
|
||||
/// Method(ref builder.AsRef());
|
||||
/// </code>
|
||||
///
|
||||
/// <para>⚠ Do not move or rename this method without updating the corresponding
|
||||
/// Razor.Diagnostics.Analyzers\PooledArrayBuilderAsRefAnalyzer.cs.</para>
|
||||
/// </remarks>
|
||||
/// <typeparam name="T">The type of element stored in the pooled array builder.</typeparam>
|
||||
/// <param name="builder">A read-only reference to a pooled array builder which is part of a <c>using</c> statement.</param>
|
||||
/// <returns>A mutable reference to the pooled array builder.</returns>
|
||||
public static ref PooledArrayBuilder<T> AsRef<T>(this in PooledArrayBuilder<T> builder)
|
||||
=> ref Unsafe.AsRef(in builder);
|
||||
}
|
|
@ -1,51 +1,32 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using Microsoft.AspNetCore.Razor.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
internal ref partial struct PooledArrayBuilder<T>
|
||||
internal partial struct PooledArrayBuilder<T>
|
||||
{
|
||||
public struct Enumerator : IEnumerator<T>
|
||||
[NonCopyable]
|
||||
public struct Enumerator(in PooledArrayBuilder<T> builder)
|
||||
{
|
||||
private readonly ImmutableArray<T>.Builder? _builder;
|
||||
private int _index;
|
||||
private T? _current;
|
||||
// Enumerate a copy of the original.
|
||||
private readonly PooledArrayBuilder<T> _builder = new(builder);
|
||||
private int _index = 0;
|
||||
private T _current = default!;
|
||||
|
||||
public Enumerator(ImmutableArray<T>.Builder builder)
|
||||
{
|
||||
_builder = builder;
|
||||
_index = 0;
|
||||
_current = default;
|
||||
}
|
||||
|
||||
public T Current => _current!;
|
||||
|
||||
object? IEnumerator.Current => Current;
|
||||
|
||||
public readonly void Dispose()
|
||||
{
|
||||
}
|
||||
public readonly T Current => _current;
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (_builder is { } builder && _index < builder.Count)
|
||||
if (_index >= _builder.Count)
|
||||
{
|
||||
_current = builder[_index];
|
||||
_index++;
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
_index = 0;
|
||||
_current = default;
|
||||
_current = _builder[_index];
|
||||
_index++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.ObjectPool;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.AspNetCore.Razor.Utilities;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.PooledObjects;
|
||||
|
||||
|
@ -13,58 +15,198 @@ namespace Microsoft.AspNetCore.Razor.PooledObjects;
|
|||
/// Wraps a pooled <see cref="ImmutableArray{T}.Builder"/> but doesn't allocate it until
|
||||
/// it's needed. Note: Dispose this to ensure that the pooled array builder is returned
|
||||
/// to the pool.
|
||||
///
|
||||
/// There is significant effort to avoid retrieving the <see cref="ImmutableArray{T}.Builder"/>.
|
||||
/// For very small arrays of length 4 or less, the elements will be stored on the stack. If the array
|
||||
/// grows larger than 4 elements, a builder will be employed. Afterward, the build will
|
||||
/// continue to be used, even if the arrays shrinks and has fewer than 4 elements.
|
||||
/// </summary>
|
||||
internal ref partial struct PooledArrayBuilder<T>
|
||||
[NonCopyable]
|
||||
internal partial struct PooledArrayBuilder<T> : IDisposable
|
||||
{
|
||||
private readonly ObjectPool<ImmutableArray<T>.Builder> _pool;
|
||||
private readonly int? _capacity;
|
||||
public static PooledArrayBuilder<T> Empty => default;
|
||||
|
||||
/// <summary>
|
||||
/// The number of items that can be stored inline.
|
||||
/// </summary>
|
||||
private const int InlineCapacity = 4;
|
||||
|
||||
/// <summary>
|
||||
/// A builder to be used as storage after the first time that the number
|
||||
/// of items exceeds <see cref="InlineCapacity"/>. Once the builder is used,
|
||||
/// it is still used even if the number of items shrinks below <see cref="InlineCapacity"/>.
|
||||
/// Essentially, if this field is non-null, it will be used as storage.
|
||||
/// </summary>
|
||||
private ImmutableArray<T>.Builder? _builder;
|
||||
|
||||
public PooledArrayBuilder()
|
||||
: this(null, null)
|
||||
/// <summary>
|
||||
/// An optional initial capacity for the builder.
|
||||
/// </summary>
|
||||
private int? _capacity;
|
||||
|
||||
private T _element0;
|
||||
private T _element1;
|
||||
private T _element2;
|
||||
private T _element3;
|
||||
|
||||
/// <summary>
|
||||
/// The number of inline elements. Note that this value is only used when <see cref="_builder"/> is <see langword="null"/>.
|
||||
/// </summary>
|
||||
private int _inlineCount;
|
||||
|
||||
public PooledArrayBuilder(int? capacity = null)
|
||||
{
|
||||
_capacity = capacity is > InlineCapacity ? capacity : null;
|
||||
_element0 = default!;
|
||||
_element1 = default!;
|
||||
_element2 = default!;
|
||||
_element3 = default!;
|
||||
_inlineCount = 0;
|
||||
}
|
||||
|
||||
public PooledArrayBuilder(ObjectPool<ImmutableArray<T>.Builder>? pool = null, int? capacity = null)
|
||||
private PooledArrayBuilder(in PooledArrayBuilder<T> builder)
|
||||
{
|
||||
_pool = pool ?? ArrayBuilderPool<T>.Default;
|
||||
_capacity = capacity;
|
||||
}
|
||||
|
||||
public readonly T this[int i]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_builder is null || Count <= i)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return _builder[i];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_builder is null || Count <= i)
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
}
|
||||
|
||||
_builder[i] = value;
|
||||
}
|
||||
// This is an intentional copy used to create an Enumerator.
|
||||
#pragma warning disable RS0042
|
||||
this = builder;
|
||||
#pragma warning restore RS0042
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
ClearAndFree();
|
||||
// Return _builder to the pool if necessary. Note that we don't need to clear the inline elements here
|
||||
// because this type is intended to be allocated on the stack and the GC can reclaim objects from the
|
||||
// stack after the last use of a reference to them.
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
ArrayBuilderPool<T>.Default.Return(builder);
|
||||
_builder = null;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ClearInlineElement(int index)
|
||||
{
|
||||
Debug.Assert(_inlineCount <= InlineCapacity);
|
||||
|
||||
// Clearing out an item makes it potentially available for garbage collection.
|
||||
// Note: On .NET Core, we can be a bit more judicious and only zero-out
|
||||
// fields that contain references to heap-allocated objects.
|
||||
|
||||
#if NETCOREAPP
|
||||
if (RuntimeHelpers.IsReferenceOrContainsReferences<T>())
|
||||
#endif
|
||||
{
|
||||
SetInlineElement(index, default!);
|
||||
}
|
||||
}
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
readonly get
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
return builder[index];
|
||||
}
|
||||
|
||||
if (index >= _inlineCount)
|
||||
{
|
||||
ThrowIndexOutOfRangeException();
|
||||
}
|
||||
|
||||
return GetInlineElement(index);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
set
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
builder[index] = value;
|
||||
return;
|
||||
}
|
||||
|
||||
if (index >= _inlineCount)
|
||||
{
|
||||
ThrowIndexOutOfRangeException();
|
||||
}
|
||||
|
||||
SetInlineElement(index, value);
|
||||
}
|
||||
}
|
||||
|
||||
public T this[Index index]
|
||||
{
|
||||
readonly get => this[index.GetOffset(Count)];
|
||||
set => this[index.GetOffset(Count)] = value;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private readonly T GetInlineElement(int index)
|
||||
{
|
||||
Debug.Assert(_inlineCount <= InlineCapacity);
|
||||
|
||||
return index switch
|
||||
{
|
||||
0 => _element0,
|
||||
1 => _element1,
|
||||
2 => _element2,
|
||||
3 => _element3,
|
||||
_ => Assumed.Unreachable<T>()
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void SetInlineElement(int index, T value)
|
||||
{
|
||||
Debug.Assert(_inlineCount <= InlineCapacity);
|
||||
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
_element0 = value;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_element1 = value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_element2 = value;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_element3 = value;
|
||||
break;
|
||||
|
||||
default:
|
||||
Assumed.Unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public readonly int Count
|
||||
=> _builder?.Count ?? 0;
|
||||
=> _builder?.Count ?? _inlineCount;
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
_builder ??= GetBuilder();
|
||||
_builder.Add(item);
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
builder.Add(item);
|
||||
}
|
||||
else if (_inlineCount < InlineCapacity)
|
||||
{
|
||||
SetInlineElement(_inlineCount, item);
|
||||
_inlineCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Assert(_inlineCount == InlineCapacity);
|
||||
MoveInlineItemsToBuilder();
|
||||
_builder.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddRange(ImmutableArray<T> items)
|
||||
|
@ -74,62 +216,144 @@ internal ref partial struct PooledArrayBuilder<T>
|
|||
return;
|
||||
}
|
||||
|
||||
_builder ??= GetBuilder();
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
public void AddRange(IReadOnlyList<T> items)
|
||||
{
|
||||
if (items.Count == 0)
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
return;
|
||||
builder.AddRange(items);
|
||||
}
|
||||
else if (_inlineCount + items.Length <= InlineCapacity)
|
||||
{
|
||||
foreach (var item in items)
|
||||
{
|
||||
SetInlineElement(_inlineCount, item);
|
||||
_inlineCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveInlineItemsToBuilder();
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
_builder ??= GetBuilder();
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<T> items)
|
||||
{
|
||||
_builder ??= GetBuilder();
|
||||
_builder.AddRange(items);
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
builder.AddRange(items);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!items.TryGetCount(out var count))
|
||||
{
|
||||
// We couldn't retrieve a count, so we have to enumerate the elements.
|
||||
foreach (var item in items)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
// No items, so there's nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
if (_inlineCount + count <= InlineCapacity)
|
||||
{
|
||||
// The items can fit into our inline elements.
|
||||
foreach (var item in items)
|
||||
{
|
||||
SetInlineElement(_inlineCount, item);
|
||||
_inlineCount++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// The items can't fit into our inline elements, so we switch to a builder.
|
||||
MoveInlineItemsToBuilder();
|
||||
_builder.AddRange(items);
|
||||
}
|
||||
}
|
||||
|
||||
public readonly Enumerator GetEnumerator()
|
||||
=> _builder is { } builder
|
||||
? new Enumerator(builder)
|
||||
: default;
|
||||
|
||||
public void ClearAndFree()
|
||||
public void Clear()
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
_pool.Return(builder);
|
||||
_builder = null;
|
||||
// Keep using a real builder to avoid churn in the object pool.
|
||||
builder.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public readonly void RemoveAt(int index)
|
||||
{
|
||||
if (_builder is null || Count <= index)
|
||||
else
|
||||
{
|
||||
throw new IndexOutOfRangeException();
|
||||
var oldCapacity = _capacity;
|
||||
this = Empty;
|
||||
_capacity = oldCapacity;
|
||||
}
|
||||
|
||||
_builder.RemoveAt(index);
|
||||
}
|
||||
|
||||
private readonly ImmutableArray<T>.Builder GetBuilder()
|
||||
public readonly Enumerator GetEnumerator()
|
||||
=> new(in this);
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
var result = _pool.Get();
|
||||
if (_capacity is int capacity)
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
result.SetCapacityIfLarger(capacity);
|
||||
builder.RemoveAt(index);
|
||||
return;
|
||||
}
|
||||
|
||||
return result;
|
||||
if (index < 0 || index >= _inlineCount)
|
||||
{
|
||||
ThrowIndexOutOfRangeException();
|
||||
}
|
||||
|
||||
// Copy inline elements depending on the index to be removed.
|
||||
switch (index)
|
||||
{
|
||||
case 0:
|
||||
_element0 = _element1;
|
||||
|
||||
if (_inlineCount > 1)
|
||||
{
|
||||
_element1 = _element2;
|
||||
}
|
||||
|
||||
if (_inlineCount > 2)
|
||||
{
|
||||
_element2 = _element3;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
_element1 = _element2;
|
||||
|
||||
if (_inlineCount > 2)
|
||||
{
|
||||
_element2 = _element3;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_element2 = _element3;
|
||||
break;
|
||||
}
|
||||
|
||||
// Clear the last element if necessary.
|
||||
if (_inlineCount > 3)
|
||||
{
|
||||
ClearInlineElement(3);
|
||||
}
|
||||
|
||||
// Decrement the count.
|
||||
_inlineCount--;
|
||||
}
|
||||
|
||||
public void RemoveAt(Index index)
|
||||
=> RemoveAt(index.GetOffset(Count));
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current contents as an <see cref="ImmutableArray{T}"/> and sets
|
||||
/// the collection to a zero length array.
|
||||
|
@ -141,18 +365,66 @@ internal ref partial struct PooledArrayBuilder<T>
|
|||
/// will then be set to a zero-length array.
|
||||
/// </remarks>
|
||||
/// <returns>An immutable array.</returns>
|
||||
public readonly ImmutableArray<T> DrainToImmutable()
|
||||
=> _builder?.DrainToImmutable() ?? ImmutableArray<T>.Empty;
|
||||
public ImmutableArray<T> DrainToImmutable()
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
return builder.DrainToImmutable();
|
||||
}
|
||||
|
||||
var inlineArray = InlineItemsToImmutableArray();
|
||||
|
||||
var oldCapacity = _capacity;
|
||||
this = Empty;
|
||||
_capacity = oldCapacity;
|
||||
|
||||
return inlineArray;
|
||||
}
|
||||
|
||||
public readonly ImmutableArray<T> ToImmutable()
|
||||
=> _builder?.ToImmutable() ?? ImmutableArray<T>.Empty;
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
return InlineItemsToImmutableArray();
|
||||
}
|
||||
|
||||
private readonly ImmutableArray<T> InlineItemsToImmutableArray()
|
||||
{
|
||||
Debug.Assert(_inlineCount <= InlineCapacity);
|
||||
|
||||
return _inlineCount switch
|
||||
{
|
||||
0 => ImmutableArray<T>.Empty,
|
||||
1 => ImmutableArray.Create(_element0),
|
||||
2 => ImmutableArray.Create(_element0, _element1),
|
||||
3 => ImmutableArray.Create(_element0, _element1, _element2),
|
||||
_ => ImmutableArray.Create(_element0, _element1, _element2, _element3)
|
||||
};
|
||||
}
|
||||
|
||||
public readonly T[] ToArray()
|
||||
=> _builder?.ToArray() ?? Array.Empty<T>();
|
||||
{
|
||||
if (_builder is { } builder)
|
||||
{
|
||||
return builder.ToArray();
|
||||
}
|
||||
|
||||
return _inlineCount switch
|
||||
{
|
||||
0 => Array.Empty<T>(),
|
||||
1 => new[] { _element0 },
|
||||
2 => new[] { _element0, _element1 },
|
||||
3 => new[] { _element0, _element1, _element2 },
|
||||
_ => new[] { _element0, _element1, _element2, _element3 }
|
||||
};
|
||||
}
|
||||
|
||||
public void Push(T item)
|
||||
{
|
||||
this.Add(item);
|
||||
Add(item);
|
||||
}
|
||||
|
||||
public readonly T Peek()
|
||||
|
@ -160,14 +432,16 @@ internal ref partial struct PooledArrayBuilder<T>
|
|||
return this[^1];
|
||||
}
|
||||
|
||||
public readonly T Pop()
|
||||
public T Pop()
|
||||
{
|
||||
var item = this[^1];
|
||||
RemoveAt(Count - 1);
|
||||
var index = ^1;
|
||||
var item = this[index];
|
||||
RemoveAt(index);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
public readonly bool TryPop([MaybeNullWhen(false)] out T item)
|
||||
public bool TryPop([MaybeNullWhen(false)] out T item)
|
||||
{
|
||||
if (Count == 0)
|
||||
{
|
||||
|
@ -178,4 +452,37 @@ internal ref partial struct PooledArrayBuilder<T>
|
|||
item = Pop();
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is present to help the JIT inline methods that need to throw
|
||||
/// a <see cref="IndexOutOfRangeException"/>.
|
||||
/// </summary>
|
||||
[DoesNotReturn]
|
||||
private static void ThrowIndexOutOfRangeException()
|
||||
=> throw new IndexOutOfRangeException();
|
||||
|
||||
[MemberNotNull(nameof(_builder))]
|
||||
private void MoveInlineItemsToBuilder()
|
||||
{
|
||||
Debug.Assert(_builder is null);
|
||||
|
||||
var builder = ArrayBuilderPool<T>.Default.Get();
|
||||
|
||||
if (_capacity is int capacity)
|
||||
{
|
||||
builder.SetCapacityIfLarger(capacity);
|
||||
}
|
||||
|
||||
_builder = builder;
|
||||
|
||||
// Add the inline items and clear their field values.
|
||||
for (var i = 0; i < _inlineCount; i++)
|
||||
{
|
||||
builder.Add(GetInlineElement(i));
|
||||
ClearInlineElement(i);
|
||||
}
|
||||
|
||||
// Since _inlineCount tracks the number of inline items used, we zero it out here.
|
||||
_inlineCount = 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Razor shared utilities test assemblies
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Utilities.Shared.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
||||
// Razor compiler assemblies
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Mvc.Razor.Extensions, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Language, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the MIT license. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Utilities;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Struct)]
|
||||
internal sealed class NonCopyableAttribute : Attribute
|
||||
{
|
||||
}
|
Загрузка…
Ссылка в новой задаче