Skip to content

Commit 00adc9e

Browse files
Rework bound attribute parameters (#11954)
> [!IMPORTANT] > This affects the Razor SDK. When the compiler flows to the .NET VMR, this commit will be needed: dotnet/dotnet@cb7d5b4. This change makes a few updates `BoundAttributeParameterDescriptor`: - Remove the `Metadata` property. There were only two bits of metadata stored in the `Metadata` property and both have become properties on `BoundAttributeParameterDescriptor` itself. - Introduce `TypeNameObject` that is similar to `DocumentationObject`. This helps reduce the amount of data that needs to be serialized and deserialized. - Don't serialize the `DisplayName` property. This always has exactly the same format for `BoundAttributeParameterDescriptors`.
2 parents b9e53af + a8f0eac commit 00adc9e

File tree

34 files changed

+7684
-10442
lines changed

34 files changed

+7684
-10442
lines changed

src/Compiler/Microsoft.AspNetCore.Razor.Language/legacyTest/Legacy/TagHelperBlockRewriterTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,8 +2242,8 @@ public void Rewrites_ComponentDirectiveAttributes()
22422242
.BindAttributeParameter(p =>
22432243
{
22442244
p.Name = "event";
2245+
p.PropertyName = "Event";
22452246
p.TypeName = typeof(string).FullName;
2246-
p.SetMetadata(PropertyName("Event"));
22472247
}))
22482248
.Build(),
22492249
];
@@ -2288,8 +2288,8 @@ public void Rewrites_MinimizedComponentDirectiveAttributes()
22882288
.BindAttributeParameter(p =>
22892289
{
22902290
p.Name = "param";
2291+
p.PropertyName = "Param";
22912292
p.TypeName = typeof(string).FullName;
2292-
p.SetMetadata(PropertyName("Param"));
22932293
}))
22942294
.Build(),
22952295
];

src/Compiler/Microsoft.AspNetCore.Razor.Language/test/Legacy/TagHelperBlockRewriterTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2465,8 +2465,8 @@ public void Rewrites_ComponentDirectiveAttributes()
24652465
.BindAttributeParameter(p =>
24662466
{
24672467
p.Name = "event";
2468+
p.PropertyName = "Event";
24682469
p.TypeName = typeof(string).FullName;
2469-
p.SetMetadata(PropertyName("Event"));
24702470
}))
24712471
.Build(),
24722472
];
@@ -2511,8 +2511,8 @@ public void Rewrites_MinimizedComponentDirectiveAttributes()
25112511
.BindAttributeParameter(p =>
25122512
{
25132513
p.Name = "param";
2514+
p.PropertyName = "Param";
25142515
p.TypeName = typeof(string).FullName;
2515-
p.SetMetadata(PropertyName("Param"));
25162516
}))
25172517
.Build(),
25182518
];

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/BindTagHelperDescriptorProvider.cs

Lines changed: 18 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -164,57 +164,52 @@ private static TagHelperDescriptor CreateFallbackBindTagHelper()
164164
attribute.BindAttributeParameter(parameter =>
165165
{
166166
parameter.Name = "format";
167+
parameter.PropertyName = "Format";
167168
parameter.TypeName = typeof(string).FullName;
168169
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Fallback_Format);
169-
170-
parameter.SetMetadata(Parameters.Format);
171170
});
172171

173172
attribute.BindAttributeParameter(parameter =>
174173
{
175174
parameter.Name = "event";
175+
parameter.PropertyName = "Event";
176176
parameter.TypeName = typeof(string).FullName;
177177
parameter.SetDocumentation(
178178
DocumentationDescriptor.From(
179179
DocumentationId.BindTagHelper_Fallback_Event, attributeName));
180-
181-
parameter.SetMetadata(Parameters.Event);
182180
});
183181

184182
attribute.BindAttributeParameter(parameter =>
185183
{
186184
parameter.Name = "culture";
185+
parameter.PropertyName = "Culture";
187186
parameter.TypeName = typeof(CultureInfo).FullName;
188187
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture);
189-
190-
parameter.SetMetadata(Parameters.Culture);
191188
});
192189

193190
attribute.BindAttributeParameter(parameter =>
194191
{
195192
parameter.Name = "get";
193+
parameter.PropertyName = "Get";
196194
parameter.TypeName = typeof(object).FullName;
197195
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get);
198-
199-
parameter.SetMetadata(Parameters.Get);
196+
parameter.BindAttributeGetSet = true;
200197
});
201198

202199
attribute.BindAttributeParameter(parameter =>
203200
{
204201
parameter.Name = "set";
202+
parameter.PropertyName = "Set";
205203
parameter.TypeName = typeof(Delegate).FullName;
206204
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set);
207-
208-
parameter.SetMetadata(Parameters.Set);
209205
});
210206

211207
attribute.BindAttributeParameter(parameter =>
212208
{
213209
parameter.Name = "after";
210+
parameter.PropertyName = "After";
214211
parameter.TypeName = typeof(Delegate).FullName;
215212
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After);
216-
217-
parameter.SetMetadata(Parameters.After);
218213
});
219214
});
220215

@@ -470,61 +465,56 @@ private static TagHelperDescriptor CreateElementBindTagHelper(
470465
a.BindAttributeParameter(parameter =>
471466
{
472467
parameter.Name = "format";
468+
parameter.PropertyName = formatName;
473469
parameter.TypeName = typeof(string).FullName;
474470
parameter.SetDocumentation(
475471
DocumentationDescriptor.From(
476472
DocumentationId.BindTagHelper_Element_Format,
477473
attributeName));
478-
479-
parameter.SetMetadata(PropertyName(formatName));
480474
});
481475

482476
a.BindAttributeParameter(parameter =>
483477
{
484478
parameter.Name = "event";
479+
parameter.PropertyName = eventName;
485480
parameter.TypeName = typeof(string).FullName;
486481
parameter.SetDocumentation(
487482
DocumentationDescriptor.From(
488483
DocumentationId.BindTagHelper_Element_Event,
489484
attributeName));
490-
491-
parameter.SetMetadata(PropertyName(eventName));
492485
});
493486

494487
a.BindAttributeParameter(parameter =>
495488
{
496489
parameter.Name = "culture";
490+
parameter.PropertyName = "Culture";
497491
parameter.TypeName = typeof(CultureInfo).FullName;
498492
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Culture);
499-
500-
parameter.SetMetadata(Parameters.Culture);
501493
});
502494

503495
a.BindAttributeParameter(parameter =>
504496
{
505497
parameter.Name = "get";
498+
parameter.PropertyName = "Get";
506499
parameter.TypeName = typeof(object).FullName;
507500
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get);
508-
509-
parameter.SetMetadata(Parameters.Get);
501+
parameter.BindAttributeGetSet = true;
510502
});
511503

512504
a.BindAttributeParameter(parameter =>
513505
{
514506
parameter.Name = "set";
507+
parameter.PropertyName = "Set";
515508
parameter.TypeName = typeof(Delegate).FullName;
516509
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set);
517-
518-
parameter.SetMetadata(Parameters.Set);
519510
});
520511

521512
a.BindAttributeParameter(parameter =>
522513
{
523514
parameter.Name = "after";
515+
parameter.PropertyName = "After";
524516
parameter.TypeName = typeof(Delegate).FullName;
525517
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After);
526-
527-
parameter.SetMetadata(Parameters.After);
528518
});
529519
});
530520

@@ -676,28 +666,26 @@ private static void AddComponentBindTagHelpers(TagHelperDescriptor tagHelper, re
676666
attribute.BindAttributeParameter(parameter =>
677667
{
678668
parameter.Name = "get";
669+
parameter.PropertyName = "Get";
679670
parameter.TypeName = typeof(object).FullName;
680671
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Get);
681-
682-
parameter.SetMetadata(Parameters.Get);
672+
parameter.BindAttributeGetSet = true;
683673
});
684674

685675
attribute.BindAttributeParameter(parameter =>
686676
{
687677
parameter.Name = "set";
678+
parameter.PropertyName = "Set";
688679
parameter.TypeName = typeof(Delegate).FullName;
689680
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_Set);
690-
691-
parameter.SetMetadata(Parameters.Set);
692681
});
693682

694683
attribute.BindAttributeParameter(parameter =>
695684
{
696685
parameter.Name = "after";
686+
parameter.PropertyName = "After";
697687
parameter.TypeName = typeof(Delegate).FullName;
698688
parameter.SetDocumentation(DocumentationDescriptor.BindTagHelper_Element_After);
699-
700-
parameter.SetMetadata(Parameters.After);
701689
});
702690
});
703691

src/Compiler/Microsoft.CodeAnalysis.Razor.Compiler/src/CSharp/EventHandlerTagHelperDescriptorProvider.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,13 +240,12 @@ private static TagHelperDescriptor CreateTagHelper(
240240
a.BindAttributeParameter(parameter =>
241241
{
242242
parameter.Name = "preventDefault";
243+
parameter.PropertyName = "PreventDefault";
243244
parameter.TypeName = typeof(bool).FullName;
244245
parameter.SetDocumentation(
245246
DocumentationDescriptor.From(
246247
DocumentationId.EventHandlerTagHelper_PreventDefault,
247248
attributeName));
248-
249-
parameter.SetMetadata(Parameters.PreventDefault);
250249
});
251250
}
252251

@@ -255,13 +254,12 @@ private static TagHelperDescriptor CreateTagHelper(
255254
a.BindAttributeParameter(parameter =>
256255
{
257256
parameter.Name = "stopPropagation";
257+
parameter.PropertyName = "StopPropagation";
258258
parameter.TypeName = typeof(bool).FullName;
259259
parameter.SetDocumentation(
260260
DocumentationDescriptor.From(
261261
DocumentationId.EventHandlerTagHelper_StopPropagation,
262262
attributeName));
263-
264-
parameter.SetMetadata(Parameters.StopPropagation);
265263
});
266264
}
267265
});

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

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
using System;
77
using System.Collections.Generic;
8-
using Microsoft.AspNetCore.Razor.Language.Components;
98

109
namespace Microsoft.AspNetCore.Razor.Language;
1110

@@ -49,9 +48,4 @@ public static void AsDictionary(
4948
builder.IndexerAttributeNamePrefix = attributeNamePrefix;
5049
builder.IndexerValueTypeName = valueTypeName;
5150
}
52-
53-
internal static void SetMetadata(this BoundAttributeParameterDescriptorBuilder builder, KeyValuePair<string, string> pair)
54-
{
55-
builder.SetMetadata(MetadataCollection.Create(pair));
56-
}
5751
}

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

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,4 @@ public static bool IsDefaultKind(this BoundAttributeParameterDescriptor paramete
5858

5959
return parameter.Parent.Parent.Kind == TagHelperConventions.DefaultKind;
6060
}
61-
62-
public static string? GetPropertyName(this BoundAttributeParameterDescriptor parameter)
63-
{
64-
ArgHelper.ThrowIfNull(parameter);
65-
66-
parameter.Metadata.TryGetValue(TagHelperMetadata.Common.PropertyName, out var propertyName);
67-
return propertyName;
68-
}
6961
}
Lines changed: 26 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
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-
using System;
54
using System.Collections.Immutable;
65
using System.Diagnostics;
76
using Microsoft.AspNetCore.Razor.Utilities;
@@ -10,86 +9,52 @@ namespace Microsoft.AspNetCore.Razor.Language;
109

1110
public sealed class BoundAttributeParameterDescriptor : TagHelperObject<BoundAttributeParameterDescriptor>
1211
{
13-
[Flags]
14-
private enum BoundAttributeParameterFlags
15-
{
16-
CaseSensitive = 1 << 0,
17-
IsEnum = 1 << 1,
18-
IsStringProperty = 1 << 2,
19-
IsBooleanProperty = 1 << 3
20-
}
21-
2212
private readonly BoundAttributeParameterFlags _flags;
23-
private readonly DocumentationObject _documentationObject;
24-
2513
private BoundAttributeDescriptor? _parent;
14+
private string? _displayName;
2615

16+
public BoundAttributeParameterFlags Flags => _flags;
2717
public string Name { get; }
28-
public string TypeName { get; }
29-
public string DisplayName { get; }
18+
public string PropertyName { get; }
19+
public string TypeName => TypeNameObject.GetTypeName().AssumeNotNull();
20+
public string DisplayName => _displayName ??= ":" + Name;
21+
22+
public string? Documentation => DocumentationObject.GetText();
3023

31-
public bool CaseSensitive => (_flags & BoundAttributeParameterFlags.CaseSensitive) != 0;
32-
public bool IsEnum => (_flags & BoundAttributeParameterFlags.IsEnum) != 0;
33-
public bool IsStringProperty => (_flags & BoundAttributeParameterFlags.IsStringProperty) != 0;
34-
public bool IsBooleanProperty => (_flags & BoundAttributeParameterFlags.IsBooleanProperty) != 0;
24+
internal TypeNameObject TypeNameObject { get; }
25+
internal DocumentationObject DocumentationObject { get; }
3526

36-
public MetadataCollection Metadata { get; }
27+
public bool CaseSensitive => _flags.IsFlagSet(BoundAttributeParameterFlags.CaseSensitive);
28+
public bool IsEnum => _flags.IsFlagSet(BoundAttributeParameterFlags.IsEnum);
29+
public bool IsStringProperty => TypeNameObject.IsString;
30+
public bool IsBooleanProperty => TypeNameObject.IsBoolean;
31+
public bool BindAttributeGetSet => _flags.IsFlagSet(BoundAttributeParameterFlags.BindAttributeGetSet);
3732

3833
internal BoundAttributeParameterDescriptor(
34+
BoundAttributeParameterFlags flags,
3935
string name,
40-
string typeName,
41-
bool isEnum,
36+
string propertyName,
37+
TypeNameObject typeNameObject,
4238
DocumentationObject documentationObject,
43-
string displayName,
44-
bool caseSensitive,
45-
MetadataCollection metadata,
4639
ImmutableArray<RazorDiagnostic> diagnostics)
4740
: base(diagnostics)
4841
{
49-
Name = name;
50-
TypeName = typeName;
51-
_documentationObject = documentationObject;
52-
DisplayName = displayName;
53-
Metadata = metadata ?? MetadataCollection.Empty;
54-
55-
BoundAttributeParameterFlags flags = 0;
56-
57-
if (isEnum)
58-
{
59-
flags |= BoundAttributeParameterFlags.IsEnum;
60-
}
61-
62-
if (caseSensitive)
63-
{
64-
flags |= BoundAttributeParameterFlags.CaseSensitive;
65-
}
66-
67-
if (typeName == typeof(string).FullName || typeName == "string")
68-
{
69-
flags |= BoundAttributeParameterFlags.IsStringProperty;
70-
}
71-
72-
if (typeName == typeof(bool).FullName || typeName == "bool")
73-
{
74-
flags |= BoundAttributeParameterFlags.IsBooleanProperty;
75-
}
76-
7742
_flags = flags;
43+
44+
Name = name;
45+
PropertyName = propertyName;
46+
TypeNameObject = typeNameObject;
47+
DocumentationObject = documentationObject;
7848
}
7949

8050
private protected override void BuildChecksum(in Checksum.Builder builder)
8151
{
52+
builder.AppendData((byte)_flags);
8253
builder.AppendData(Name);
83-
builder.AppendData(TypeName);
84-
builder.AppendData(DisplayName);
54+
builder.AppendData(PropertyName);
8555

56+
TypeNameObject.AppendToChecksum(in builder);
8657
DocumentationObject.AppendToChecksum(in builder);
87-
88-
builder.AppendData(CaseSensitive);
89-
builder.AppendData(IsEnum);
90-
builder.AppendData(IsBooleanProperty);
91-
builder.AppendData(IsStringProperty);
92-
builder.AppendData(Metadata.Checksum);
9358
}
9459

9560
public BoundAttributeDescriptor Parent
@@ -103,10 +68,6 @@ internal void SetParent(BoundAttributeDescriptor parent)
10368
_parent = parent;
10469
}
10570

106-
public string? Documentation => _documentationObject.GetText();
107-
108-
internal DocumentationObject DocumentationObject => _documentationObject;
109-
11071
public override string ToString()
111-
=> DisplayName ?? base.ToString()!;
72+
=> DisplayName;
11273
}

0 commit comments

Comments
 (0)