Skip to content

Commit 843db34

Browse files
Merge pull request #8758 from DustinCampbell/formalize-top-level-converters
Clean up serialization layer and ProjectEngineHost
2 parents 8175b43 + 855b86c commit 843db34

File tree

199 files changed

+871
-855
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

199 files changed

+871
-855
lines changed

src/Compiler/Microsoft.AspNetCore.Razor.Language/src/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.Editor.Razor.Test.Common, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
3636
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServices.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
3737
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LanguageServerClient.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
38+
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.LiveShare.Razor.Test, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
3839
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
3940
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Microbenchmarks.Compiler, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]
4041
[assembly: InternalsVisibleTo("Microsoft.AspNetCore.Razor.Microbenchmarks, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f33a29044fa9d740c9b3213a93e57c84b472c84e0b8a0e1ae48e67a9f8f6de9d5f7f3d52ac23e48ac51801f1dc950abe901da34d2a9e3baadb141a17c77ef3c565dd5ee5054b91cf63bb3c6ab83f72ab3aafe93d0fc3c2348b764fafb0b1c0733de51459aeab46580384bf9d74c4e28164b7cde247f891ba07891c9d872ad2bb")]

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/CommonResources.cs

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

4-
using System.Collections.Generic;
4+
using System.Collections.Immutable;
55
using System.IO;
66
using Microsoft.AspNetCore.Razor.Language;
7-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
7+
using Microsoft.AspNetCore.Razor.ProjectSystem;
8+
using Microsoft.AspNetCore.Razor.Serialization;
89

910
namespace Microsoft.AspNetCore.Razor.Microbenchmarks;
1011

1112
internal static class CommonResources
1213
{
1314
public static readonly byte[] LegacyTagHelperBytes = Resources.GetResourceBytes("taghelpers.json");
14-
public static readonly IReadOnlyList<TagHelperDescriptor> LegacyTagHelpers = LoadTagHelpers(LegacyTagHelperBytes);
15+
public static readonly ImmutableArray<TagHelperDescriptor> LegacyTagHelpers = LoadTagHelpers(LegacyTagHelperBytes);
1516

1617
public static readonly byte[] LegacyProjectRazorJsonBytes = Resources.GetResourceBytes("project.razor.json");
1718
public static readonly ProjectRazorJson LegacyProjectRazorJson = LoadProjectRazorJson(LegacyProjectRazorJsonBytes);
1819

1920
public static readonly byte[] TelerikTagHelperBytes = Resources.GetResourceBytes("Kendo.Mvc.Examples.taghelpers.json", folder: "Telerik");
20-
public static readonly IReadOnlyList<TagHelperDescriptor> TelerikTagHelpers = LoadTagHelpers(TelerikTagHelperBytes);
21+
public static readonly ImmutableArray<TagHelperDescriptor> TelerikTagHelpers = LoadTagHelpers(TelerikTagHelperBytes);
2122

2223
public static readonly byte[] TelerikProjectRazorJsonBytes = Resources.GetResourceBytes("Kendo.Mvc.Examples.project.razor.json", folder: "Telerik");
2324
public static readonly ProjectRazorJson TelerikProjectRazorJson = LoadProjectRazorJson(TelerikProjectRazorJsonBytes);
2425

25-
private static IReadOnlyList<TagHelperDescriptor> LoadTagHelpers(byte[] bytes)
26+
private static ImmutableArray<TagHelperDescriptor> LoadTagHelpers(byte[] bytes)
2627
{
2728
using var stream = new MemoryStream(bytes);
2829
using var reader = new StreamReader(stream);
2930

3031
return JsonDataConvert.DeserializeData(reader,
31-
static r => r.ReadArrayOrEmpty(
32-
static r => ObjectReaders.ReadTagHelper(r, useCache: false)));
32+
static r => r.ReadImmutableArray(
33+
static r => ObjectReaders.ReadTagHelper(r, useCache: false))).NullToEmpty();
3334
}
3435

3536
private static ProjectRazorJson LoadProjectRazorJson(byte[] bytes)

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/LanguageServer/RazorLanguageServerBenchmarkBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
using System.Threading.Tasks;
1010
using Microsoft.AspNetCore.Razor.Language;
1111
using Microsoft.AspNetCore.Razor.LanguageServer;
12-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
12+
using Microsoft.AspNetCore.Razor.ProjectSystem;
1313
using Microsoft.AspNetCore.Razor.Telemetry;
1414
using Microsoft.CodeAnalysis;
1515
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
@@ -59,7 +59,7 @@ internal IDocumentSnapshot GetDocumentSnapshot(string projectFilePath, string fi
5959

6060
var projectSnapshotManager = CreateProjectSnapshotManager();
6161
projectSnapshotManager.ProjectAdded(hostProject);
62-
var tagHelpers = GetTagHelperDescriptors();
62+
var tagHelpers = CommonResources.LegacyTagHelpers;
6363
var projectWorkspaceState = new ProjectWorkspaceState(tagHelpers, CodeAnalysis.CSharp.LanguageVersion.CSharp11);
6464
projectSnapshotManager.ProjectWorkspaceStateChanged(projectFilePath, projectWorkspaceState);
6565
projectSnapshotManager.DocumentAdded(hostProject, hostDocument, textLoader);
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
// Copyright (c) .NET Foundation. All rights reserved.
22
// Licensed under the MIT license. See License.txt in the project root for license information.
33

4-
using System;
5-
using System.Collections.Generic;
4+
using System.Collections.Immutable;
65
using System.Threading;
76
using System.Threading.Tasks;
87
using Microsoft.AspNetCore.Razor.Language;
9-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
8+
using Microsoft.AspNetCore.Razor.Serialization;
109
using Microsoft.AspNetCore.Razor.Telemetry;
1110
using Microsoft.CodeAnalysis;
1211
using Microsoft.CodeAnalysis.Razor;
@@ -18,9 +17,9 @@ public abstract partial class ProjectSnapshotManagerBenchmarkBase
1817
{
1918
private class StaticTagHelperResolver : TagHelperResolver
2019
{
21-
private readonly IReadOnlyList<TagHelperDescriptor> _tagHelpers;
20+
private readonly ImmutableArray<TagHelperDescriptor> _tagHelpers;
2221

23-
public StaticTagHelperResolver(IReadOnlyList<TagHelperDescriptor> tagHelpers, ITelemetryReporter telemetryReporter)
22+
public StaticTagHelperResolver(ImmutableArray<TagHelperDescriptor> tagHelpers, ITelemetryReporter telemetryReporter)
2423
: base(telemetryReporter)
2524
{
2625
_tagHelpers = tagHelpers;
@@ -30,6 +29,6 @@ public override Task<TagHelperResolutionResult> GetTagHelpersAsync(
3029
Project project,
3130
IProjectSnapshot projectSnapshot,
3231
CancellationToken cancellationToken = default)
33-
=> Task.FromResult(new TagHelperResolutionResult(_tagHelpers, Array.Empty<RazorDiagnostic>()));
32+
=> Task.FromResult(new TagHelperResolutionResult(_tagHelpers));
3433
}
3534
}

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/ProjectSystem/ProjectSnapshotManagerBenchmarkBase.cs

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

44
using System;
5-
using System.Collections.Generic;
65
using System.Collections.Immutable;
76
using System.IO;
87
using Microsoft.AspNetCore.Razor.Language;
98
using Microsoft.AspNetCore.Razor.PooledObjects;
10-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
119
using Microsoft.AspNetCore.Razor.Telemetry;
1210
using Microsoft.CodeAnalysis;
1311
using Microsoft.CodeAnalysis.Host;
1412
using Microsoft.CodeAnalysis.Razor;
1513
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
1614
using Microsoft.CodeAnalysis.Text;
17-
using Newtonsoft.Json;
1815

1916
namespace Microsoft.AspNetCore.Razor.Microbenchmarks;
2017

@@ -63,19 +60,8 @@ protected ProjectSnapshotManagerBenchmarkBase()
6360

6461
Documents = documents.ToImmutable();
6562

66-
TagHelperResolver = new StaticTagHelperResolver(GetTagHelperDescriptors(), NoOpTelemetryReporter.Instance);
67-
}
68-
69-
internal IReadOnlyList<TagHelperDescriptor> GetTagHelperDescriptors()
70-
{
71-
var tagHelperBuffer = Resources.GetResourceBytes("taghelpers.json");
72-
73-
var serializer = new JsonSerializer();
74-
serializer.Converters.Add(TagHelperDescriptorJsonConverter.Instance);
75-
using var stream = new MemoryStream(tagHelperBuffer);
76-
using var reader = new JsonTextReader(new StreamReader(stream));
77-
78-
return serializer.Deserialize<IReadOnlyList<TagHelperDescriptor>>(reader) ?? Array.Empty<TagHelperDescriptor>();
63+
var tagHelpers = CommonResources.LegacyTagHelpers;
64+
TagHelperResolver = new StaticTagHelperResolver(tagHelpers, NoOpTelemetryReporter.Instance);
7965
}
8066

8167
internal DefaultProjectSnapshotManager CreateProjectSnapshotManager()

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/ProjectSystem/ProjectSnapshotSerializationBenchmark.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
using System.IO;
88
using System.Text;
99
using BenchmarkDotNet.Attributes;
10-
using Microsoft.CodeAnalysis.Razor;
10+
using Microsoft.AspNetCore.Razor.Serialization;
11+
using Microsoft.AspNetCore.Razor.Serialization.Converters;
1112
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
1213
using Newtonsoft.Json;
1314

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Remote/RemoteTagHelperDeltaProviderBenchmark.cs

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

4-
using System;
5-
using System.Collections.Generic;
4+
using System.Collections.Immutable;
65
using System.Diagnostics.CodeAnalysis;
76
using System.Linq;
87
using BenchmarkDotNet.Attributes;
@@ -15,34 +14,37 @@ public class RemoteTagHelperDeltaProviderBenchmark
1514
{
1615
public RemoteTagHelperDeltaProviderBenchmark()
1716
{
18-
DefaultTagHelperSet = CommonResources.LegacyTagHelpers.ToHashSet();
17+
DefaultTagHelperSet = CommonResources.LegacyTagHelpers.ToHashSet().ToImmutableArray();
1918

2019
Added50PercentMoreDefaultTagHelpers = DefaultTagHelperSet
21-
.Take(DefaultTagHelperSet.Count / 2)
20+
.Take(DefaultTagHelperSet.Length / 2)
2221
.Select(th => new RenamedTagHelperDescriptor(th.Name + "Added", th))
2322
.Concat(DefaultTagHelperSet)
24-
.ToHashSet();
23+
.ToHashSet()
24+
.ToImmutableArray();
2525

2626
RemovedHalfOfDefaultTagHelpers = DefaultTagHelperSet
27-
.Take(CommonResources.LegacyTagHelpers.Count / 2)
28-
.ToHashSet();
27+
.Take(CommonResources.LegacyTagHelpers.Length / 2)
28+
.ToHashSet()
29+
.ToImmutableArray();
2930

3031
var tagHelpersToMutate = DefaultTagHelperSet
3132
.Take(2)
3233
.Select(th => new RenamedTagHelperDescriptor(th.Name + "Mutated", th));
3334
MutatedTwoDefaultTagHelpers = DefaultTagHelperSet
3435
.Skip(2)
3536
.Concat(tagHelpersToMutate)
36-
.ToHashSet();
37+
.ToHashSet()
38+
.ToImmutableArray();
3739
}
3840

39-
private IReadOnlyCollection<TagHelperDescriptor> DefaultTagHelperSet { get; }
41+
private ImmutableArray<TagHelperDescriptor> DefaultTagHelperSet { get; }
4042

41-
private IReadOnlyCollection<TagHelperDescriptor> Added50PercentMoreDefaultTagHelpers { get; }
43+
private ImmutableArray<TagHelperDescriptor> Added50PercentMoreDefaultTagHelpers { get; }
4244

43-
private IReadOnlyCollection<TagHelperDescriptor> RemovedHalfOfDefaultTagHelpers { get; }
45+
private ImmutableArray<TagHelperDescriptor> RemovedHalfOfDefaultTagHelpers { get; }
4446

45-
private IReadOnlyCollection<TagHelperDescriptor> MutatedTwoDefaultTagHelpers { get; }
47+
private ImmutableArray<TagHelperDescriptor> MutatedTwoDefaultTagHelpers { get; }
4648

4749
private string ProjectFilePath { get; } = "C:/path/to/project.csproj";
4850

@@ -68,7 +70,7 @@ public void TagHelper_GetTagHelpersDelta_NewProject()
6870
[Benchmark(Description = "Calculate Delta - Remove project")]
6971
public void TagHelper_GetTagHelpersDelta_RemoveProject()
7072
{
71-
_ = Provider.GetTagHelpersDelta(ProjectFilePath, LastResultId, Array.Empty<TagHelperDescriptor>());
73+
_ = Provider.GetTagHelpersDelta(ProjectFilePath, LastResultId, ImmutableArray<TagHelperDescriptor>.Empty);
7274
}
7375

7476
[Benchmark(Description = "Calculate Delta - Add lots of TagHelpers")]

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Serialization/MemoryCacheBenchmark.cs

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

44
using System.Collections.Generic;
5-
using System.IO;
65
using System.Linq;
76
using BenchmarkDotNet.Attributes;
87
using Microsoft.AspNetCore.Razor.Language;
9-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
10-
using Newtonsoft.Json;
8+
using Microsoft.AspNetCore.Razor.Utilities;
119

1210
namespace Microsoft.AspNetCore.Razor.Microbenchmarks.Serialization;
1311

@@ -24,16 +22,8 @@ public class MemoryCacheBenchmark
2422
[GlobalSetup]
2523
public void Setup()
2624
{
27-
var tagHelperBuffer = Resources.GetResourceBytes("taghelpers.json");
28-
29-
// Deserialize from json file.
30-
var serializer = new JsonSerializer();
31-
serializer.Converters.Add(TagHelperDescriptorJsonConverter.Instance);
32-
using var stream = new MemoryStream(tagHelperBuffer);
33-
using var reader = new JsonTextReader(new StreamReader(stream));
34-
35-
_tagHelpers = serializer.Deserialize<IReadOnlyList<TagHelperDescriptor>>(reader).AssumeNotNull();
36-
_tagHelperHashes = TagHelpers.Select(th => th.GetHashCode()).ToList();
25+
_tagHelpers = CommonResources.LegacyTagHelpers;
26+
_tagHelperHashes = TagHelpers.Select(th => th.GetHashCode()).ToArray();
3727

3828
// Set cache size to 400 so anything more then that will force compacts
3929
_cache = new MemoryCache<int, TagHelperDescriptor>(400);

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Serialization/ProjectRazorJsonSerializationBenchmark.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
using System.IO;
55
using System.Text;
66
using BenchmarkDotNet.Attributes;
7-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
7+
using Microsoft.AspNetCore.Razor.ProjectSystem;
8+
using Microsoft.AspNetCore.Razor.Serialization;
89

910
namespace Microsoft.AspNetCore.Razor.Microbenchmarks.Serialization;
1011

@@ -56,7 +57,7 @@ public void Deserialize()
5657
var projectRazorJson = DeserializeProjectRazorJson(reader);
5758

5859
if (projectRazorJson.ProjectWorkspaceState is null ||
59-
projectRazorJson.ProjectWorkspaceState.TagHelpers.Count != ProjectRazorJson.ProjectWorkspaceState?.TagHelpers.Count)
60+
projectRazorJson.ProjectWorkspaceState.TagHelpers.Length != ProjectRazorJson.ProjectWorkspaceState?.TagHelpers.Length)
6061
{
6162
throw new InvalidDataException();
6263
}
@@ -78,7 +79,7 @@ public void RoundTrip()
7879
var projectRazorJson = DeserializeProjectRazorJson(reader);
7980

8081
if (projectRazorJson.ProjectWorkspaceState is null ||
81-
projectRazorJson.ProjectWorkspaceState.TagHelpers.Count != ProjectRazorJson.ProjectWorkspaceState?.TagHelpers.Count)
82+
projectRazorJson.ProjectWorkspaceState.TagHelpers.Length != ProjectRazorJson.ProjectWorkspaceState?.TagHelpers.Length)
8283
{
8384
throw new InvalidDataException();
8485
}

src/Razor/benchmarks/Microsoft.AspNetCore.Razor.Microbenchmarks/Serialization/TagHelperResolutionResultSerializationBenchmark.cs

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

4-
using System;
5-
using System.Collections.Generic;
4+
using System.Collections.Immutable;
65
using System.IO;
76
using System.Text;
87
using BenchmarkDotNet.Attributes;
98
using Microsoft.AspNetCore.Razor.Language;
10-
using Microsoft.AspNetCore.Razor.ProjectEngineHost.Serialization;
9+
using Microsoft.AspNetCore.Razor.Serialization;
10+
using Microsoft.AspNetCore.Razor.Serialization.Converters;
1111
using Newtonsoft.Json;
1212

1313
namespace Microsoft.AspNetCore.Razor.Microbenchmarks.Serialization;
@@ -17,7 +17,7 @@ public class TagHelperResolutionResultSerializationBenchmark
1717
[ParamsAllValues]
1818
public ResourceSet ResourceSet { get; set; }
1919

20-
private IReadOnlyList<TagHelperDescriptor> TagHelpers
20+
private ImmutableArray<TagHelperDescriptor> TagHelpers
2121
=> ResourceSet switch
2222
{
2323
ResourceSet.Telerik => CommonResources.TelerikTagHelpers,
@@ -40,7 +40,7 @@ public void GlobalSetup()
4040
[IterationSetup]
4141
public void IterationSetup()
4242
{
43-
_tagHelperResolutionResult = new TagHelperResolutionResult(TagHelpers, Array.Empty<RazorDiagnostic>());
43+
_tagHelperResolutionResult = new TagHelperResolutionResult(TagHelpers);
4444
}
4545

4646
[Benchmark(Description = "RoundTrip TagHelperDescriptorResult")]
@@ -60,7 +60,7 @@ public void RoundTrip()
6060
var result = Serializer.Deserialize<TagHelperResolutionResult>(jsonReader);
6161

6262
if (result is null ||
63-
result.Descriptors.Count != TagHelpers.Count)
63+
result.Descriptors.Length != TagHelpers.Length)
6464
{
6565
throw new InvalidDataException();
6666
}

0 commit comments

Comments
 (0)