Skip to content

Commit 1212a45

Browse files
Compiler: Add Parent property to nested tag helper objects (#11953)
> [!IMPORTANT] > This affects the Razor SDK. When the compiler flows to the .NET SDK, this commit will be needed: dotnet/sdk@a9d343d. Add Parent properties to all of the nested tag helper objects: * `AllowedChildTagDescriptor.Parent` -> `TagHelperDescriptor` * `BoundAttributeDescriptor.Parent` -> `TagHelperDescriptor` * `BoundAttributeParameterDescriptor.Parent` -> `BoundAttributeDescriptor` * `TagMatchingRuleDescriptor.Parent` -> `TagHelperDescriptor` * `RequiredAttributeDescriptor.Parent` -> `TagMatchingRuleDescriptor` This removes the need for `BoundAttribute` and `BoundAttributeParameterDescriptor` to duplicate the `Kind` property from `TagHelperDescriptor`.
2 parents 6763310 + 8e28962 commit 1212a45

File tree

39 files changed

+17676
-44535
lines changed

39 files changed

+17676
-44535
lines changed

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/BoundAttributeDescriptorExtensionsTest.cs

Lines changed: 111 additions & 125 deletions
Large diffs are not rendered by default.

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/DefaultBoundAttributeDescriptorBuilderTest.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public void DisplayName_SetsDescriptorsDisplayName()
1616

1717
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
1818

19-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
19+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
2020
builder.DisplayName(expectedDisplayName);
2121

2222
// Act
@@ -33,7 +33,7 @@ public void DisplayName_DefaultsToPropertyLookingDisplayName()
3333
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
3434
tagHelperBuilder.Metadata(TypeName("TestTagHelper"));
3535

36-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
36+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
3737
builder
3838
.TypeName(typeof(int).FullName)
3939
.Metadata(PropertyName("SomeProperty"));
@@ -56,12 +56,12 @@ public void Metadata_Same()
5656

5757
var metadata = MetadataCollection.Create(PropertyName("SomeProperty"));
5858

59-
var builder1 = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind)
59+
var builder1 = new BoundAttributeDescriptorBuilder(tagHelperBuilder)
6060
{
6161
TypeName = typeof(int).FullName
6262
};
6363

64-
var builder2 = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind)
64+
var builder2 = new BoundAttributeDescriptorBuilder(tagHelperBuilder)
6565
{
6666
TypeName = typeof(int).FullName
6767
};
@@ -86,12 +86,12 @@ public void Metadata_NotSame()
8686
// Arrange
8787
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
8888

89-
var builder1 = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind)
89+
var builder1 = new BoundAttributeDescriptorBuilder(tagHelperBuilder)
9090
{
9191
TypeName = typeof(int).FullName
9292
};
9393

94-
var builder2 = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind)
94+
var builder2 = new BoundAttributeDescriptorBuilder(tagHelperBuilder)
9595
{
9696
TypeName = typeof(int).FullName
9797
};

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Extensions/PreallocatedAttributeTargetExtensionTest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ public void WriteTagHelperProperty_RendersCorrectly()
130130
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
131131
tagHelperBuilder.Metadata(TypeName("FooTagHelper"));
132132

133-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
133+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
134134
builder
135135
.Name("Foo")
136136
.TypeName("System.String")
@@ -173,7 +173,7 @@ public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_RendersCorrec
173173
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
174174
tagHelperBuilder.Metadata(TypeName("FooTagHelper"));
175175

176-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
176+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
177177
builder
178178
.Name("Foo")
179179
.TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")
@@ -223,7 +223,7 @@ public void WriteSetPreallocatedTagHelperProperty_IndexerAttribute_MultipleValue
223223
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "FooTagHelper", "Test");
224224
tagHelperBuilder.Metadata(TypeName("FooTagHelper"));
225225

226-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
226+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
227227
builder
228228
.Name("Foo")
229229
.TypeName("System.Collections.Generic.Dictionary<System.String, System.String>")

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/TagHelperMatchingConventionsTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ public void CanSatisfyBoundAttribute_IndexerAttribute_ReturnsFalseIsNotMatching(
163163
{
164164
// Arrange
165165
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
166-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
166+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
167167
builder.AsDictionary("asp-", typeof(Dictionary<string, string>).FullName);
168168

169169
var boundAttribute = builder.Build();
@@ -180,7 +180,7 @@ public void CanSatisfyBoundAttribute_IndexerAttribute_ReturnsTrueIfMatching()
180180
{
181181
// Arrange
182182
var tagHelperBuilder = new TagHelperDescriptorBuilder(TagHelperConventions.DefaultKind, "TestTagHelper", "Test");
183-
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder, TagHelperConventions.DefaultKind);
183+
var builder = new BoundAttributeDescriptorBuilder(tagHelperBuilder);
184184
builder.AsDictionary("asp-", typeof(Dictionary<string, string>).FullName);
185185

186186
var boundAttribute = builder.Build();

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/AllowedChildTagDescriptor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System.Collections.Immutable;
5+
using System.Diagnostics;
56
using Microsoft.AspNetCore.Razor.Utilities;
67

78
namespace Microsoft.AspNetCore.Razor.Language;
89

910
public sealed class AllowedChildTagDescriptor : TagHelperObject<AllowedChildTagDescriptor>
1011
{
12+
private TagHelperDescriptor? _parent;
13+
1114
public string Name { get; }
1215
public string DisplayName { get; }
1316

@@ -24,6 +27,17 @@ private protected override void BuildChecksum(in Checksum.Builder builder)
2427
builder.AppendData(DisplayName);
2528
}
2629

30+
public TagHelperDescriptor Parent
31+
=> _parent ?? ThrowHelper.ThrowInvalidOperationException<TagHelperDescriptor>(Resources.Parent_has_not_been_set);
32+
33+
internal void SetParent(TagHelperDescriptor parent)
34+
{
35+
Debug.Assert(parent != null);
36+
Debug.Assert(_parent == null);
37+
38+
_parent = parent;
39+
}
40+
2741
public override string ToString()
2842
=> DisplayName ?? base.ToString()!;
2943
}

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/BoundAttributeDescriptor.cs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System;
55
using System.Collections.Generic;
66
using System.Collections.Immutable;
7+
using System.Diagnostics;
78
using Microsoft.AspNetCore.Razor.Language.Components;
89
using Microsoft.AspNetCore.Razor.Utilities;
910

@@ -31,7 +32,8 @@ private enum BoundAttributeFlags
3132
private readonly BoundAttributeFlags _flags;
3233
private readonly DocumentationObject _documentationObject;
3334

34-
public string Kind { get; }
35+
private TagHelperDescriptor? _parent;
36+
3537
public string Name { get; }
3638
public string TypeName { get; }
3739
public string DisplayName { get; }
@@ -54,7 +56,6 @@ private enum BoundAttributeFlags
5456
public MetadataCollection Metadata { get; }
5557

5658
internal BoundAttributeDescriptor(
57-
string kind,
5859
string name,
5960
string typeName,
6061
bool isEnum,
@@ -71,7 +72,6 @@ internal BoundAttributeDescriptor(
7172
ImmutableArray<RazorDiagnostic> diagnostics)
7273
: base(diagnostics)
7374
{
74-
Kind = kind;
7575
Name = name;
7676
TypeName = typeName;
7777
IndexerNamePrefix = indexerNamePrefix;
@@ -82,6 +82,11 @@ internal BoundAttributeDescriptor(
8282
Parameters = parameters.NullToEmpty();
8383
Metadata = metadata ?? MetadataCollection.Empty;
8484

85+
foreach (var parameter in Parameters)
86+
{
87+
parameter.SetParent(this);
88+
}
89+
8590
BoundAttributeFlags flags = 0;
8691

8792
if (isEnum)
@@ -134,7 +139,6 @@ internal BoundAttributeDescriptor(
134139

135140
private protected override void BuildChecksum(in Checksum.Builder builder)
136141
{
137-
builder.AppendData(Kind);
138142
builder.AppendData(Name);
139143
builder.AppendData(TypeName);
140144
builder.AppendData(IndexerNamePrefix);
@@ -161,6 +165,17 @@ private protected override void BuildChecksum(in Checksum.Builder builder)
161165
builder.AppendData(Metadata.Checksum);
162166
}
163167

168+
public TagHelperDescriptor Parent
169+
=> _parent ?? ThrowHelper.ThrowInvalidOperationException<TagHelperDescriptor>(Resources.Parent_has_not_been_set);
170+
171+
internal void SetParent(TagHelperDescriptor parent)
172+
{
173+
Debug.Assert(parent != null);
174+
Debug.Assert(_parent == null);
175+
176+
_parent = parent;
177+
}
178+
164179
public string? Documentation => _documentationObject.GetText();
165180

166181
internal DocumentationObject DocumentationObject => _documentationObject;

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/BoundAttributeDescriptorBuilder.cs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ public sealed partial class BoundAttributeDescriptorBuilder : TagHelperObjectBui
3535

3636
[AllowNull]
3737
private TagHelperDescriptorBuilder _parent;
38-
[AllowNull]
39-
private string _kind;
4038
private DocumentationObject _documentationObject;
4139
private MetadataHolder _metadata;
4240
private bool? _caseSensitive;
@@ -45,10 +43,9 @@ private BoundAttributeDescriptorBuilder()
4543
{
4644
}
4745

48-
internal BoundAttributeDescriptorBuilder(TagHelperDescriptorBuilder parent, string kind)
46+
internal BoundAttributeDescriptorBuilder(TagHelperDescriptorBuilder parent)
4947
{
5048
_parent = parent;
51-
_kind = kind;
5249
}
5350

5451
[AllowNull]
@@ -93,7 +90,7 @@ public void BindAttributeParameter(Action<BoundAttributeParameterDescriptorBuild
9390
throw new ArgumentNullException(nameof(configure));
9491
}
9592

96-
var builder = BoundAttributeParameterDescriptorBuilder.GetInstance(this, _kind);
93+
var builder = BoundAttributeParameterDescriptorBuilder.GetInstance(this);
9794
configure(builder);
9895
Parameters.Add(builder);
9996
}
@@ -111,7 +108,6 @@ internal void SetDocumentation(DocumentationDescriptor? documentation)
111108
private protected override BoundAttributeDescriptor BuildCore(ImmutableArray<RazorDiagnostic> diagnostics)
112109
{
113110
return new BoundAttributeDescriptor(
114-
_kind,
115111
Name ?? string.Empty,
116112
TypeName ?? string.Empty,
117113
IsEnum,

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/BoundAttributeDescriptorBuilder_Pooling.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,18 @@ public partial class BoundAttributeDescriptorBuilder
1010
{
1111
internal static readonly ObjectPool<BoundAttributeDescriptorBuilder> Pool = DefaultPool.Create(Policy.Instance);
1212

13-
internal static BoundAttributeDescriptorBuilder GetInstance(TagHelperDescriptorBuilder parent, string kind)
13+
internal static BoundAttributeDescriptorBuilder GetInstance(TagHelperDescriptorBuilder parent)
1414
{
1515
var builder = Pool.Get();
1616

1717
builder._parent = parent;
18-
builder._kind = kind;
1918

2019
return builder;
2120
}
2221

2322
private protected override void Reset()
2423
{
2524
_parent = null;
26-
_kind = null;
2725
_documentationObject = default;
2826
_caseSensitive = null;
2927

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/BoundAttributeDescriptorExtensions.cs

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,33 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
#nullable disable
5-
64
using System;
75

86
namespace Microsoft.AspNetCore.Razor.Language;
97

108
public static class BoundAttributeDescriptorExtensions
119
{
12-
public static string GetPropertyName(this BoundAttributeDescriptor attribute)
10+
public static string? GetPropertyName(this BoundAttributeDescriptor attribute)
1311
{
14-
if (attribute == null)
15-
{
16-
throw new ArgumentNullException(nameof(attribute));
17-
}
12+
ArgHelper.ThrowIfNull(attribute);
1813

1914
attribute.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName);
2015
return propertyName;
2116
}
2217

23-
public static string GetGloballyQualifiedTypeName(this BoundAttributeDescriptor attribute)
18+
public static string? GetGloballyQualifiedTypeName(this BoundAttributeDescriptor attribute)
2419
{
25-
if (attribute == null)
26-
{
27-
throw new ArgumentNullException(nameof(attribute));
28-
}
20+
ArgHelper.ThrowIfNull(attribute);
2921

3022
attribute.Metadata.TryGetValue(TagHelperMetadata.Common.GloballyQualifiedTypeName, out var propertyName);
3123
return propertyName;
3224
}
3325

3426
public static bool IsDefaultKind(this BoundAttributeDescriptor attribute)
3527
{
36-
if (attribute == null)
37-
{
38-
throw new ArgumentNullException(nameof(attribute));
39-
}
28+
ArgHelper.ThrowIfNull(attribute);
4029

41-
return attribute.Kind == TagHelperConventions.DefaultKind;
30+
return attribute.Parent.Kind == TagHelperConventions.DefaultKind;
4231
}
4332

4433
internal static bool ExpectsStringValue(this BoundAttributeDescriptor attribute, string name)
@@ -65,20 +54,14 @@ internal static bool ExpectsBooleanValue(this BoundAttributeDescriptor attribute
6554

6655
public static bool IsDefaultKind(this BoundAttributeParameterDescriptor parameter)
6756
{
68-
if (parameter == null)
69-
{
70-
throw new ArgumentNullException(nameof(parameter));
71-
}
57+
ArgHelper.ThrowIfNull(parameter);
7258

73-
return parameter.Kind == TagHelperConventions.DefaultKind;
59+
return parameter.Parent.Parent.Kind == TagHelperConventions.DefaultKind;
7460
}
7561

76-
public static string GetPropertyName(this BoundAttributeParameterDescriptor parameter)
62+
public static string? GetPropertyName(this BoundAttributeParameterDescriptor parameter)
7763
{
78-
if (parameter == null)
79-
{
80-
throw new ArgumentNullException(nameof(parameter));
81-
}
64+
ArgHelper.ThrowIfNull(parameter);
8265

8366
parameter.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName);
8467
return propertyName;

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/Language/BoundAttributeParameterDescriptor.cs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
using System;
55
using System.Collections.Immutable;
6+
using System.Diagnostics;
67
using Microsoft.AspNetCore.Razor.Utilities;
78

89
namespace Microsoft.AspNetCore.Razor.Language;
@@ -21,7 +22,8 @@ private enum BoundAttributeParameterFlags
2122
private readonly BoundAttributeParameterFlags _flags;
2223
private readonly DocumentationObject _documentationObject;
2324

24-
public string Kind { get; }
25+
private BoundAttributeDescriptor? _parent;
26+
2527
public string Name { get; }
2628
public string TypeName { get; }
2729
public string DisplayName { get; }
@@ -34,7 +36,6 @@ private enum BoundAttributeParameterFlags
3436
public MetadataCollection Metadata { get; }
3537

3638
internal BoundAttributeParameterDescriptor(
37-
string kind,
3839
string name,
3940
string typeName,
4041
bool isEnum,
@@ -45,7 +46,6 @@ internal BoundAttributeParameterDescriptor(
4546
ImmutableArray<RazorDiagnostic> diagnostics)
4647
: base(diagnostics)
4748
{
48-
Kind = kind;
4949
Name = name;
5050
TypeName = typeName;
5151
_documentationObject = documentationObject;
@@ -79,7 +79,6 @@ internal BoundAttributeParameterDescriptor(
7979

8080
private protected override void BuildChecksum(in Checksum.Builder builder)
8181
{
82-
builder.AppendData(Kind);
8382
builder.AppendData(Name);
8483
builder.AppendData(TypeName);
8584
builder.AppendData(DisplayName);
@@ -93,6 +92,17 @@ private protected override void BuildChecksum(in Checksum.Builder builder)
9392
builder.AppendData(Metadata.Checksum);
9493
}
9594

95+
public BoundAttributeDescriptor Parent
96+
=> _parent ?? ThrowHelper.ThrowInvalidOperationException<BoundAttributeDescriptor>(Resources.Parent_has_not_been_set);
97+
98+
internal void SetParent(BoundAttributeDescriptor parent)
99+
{
100+
Debug.Assert(parent != null);
101+
Debug.Assert(_parent == null);
102+
103+
_parent = parent;
104+
}
105+
96106
public string? Documentation => _documentationObject.GetText();
97107

98108
internal DocumentationObject DocumentationObject => _documentationObject;

0 commit comments

Comments
 (0)