@@ -67,7 +67,7 @@ protected override void ExecuteCore(RazorCodeDocument codeDocument, DocumentInte
67
67
}
68
68
}
69
69
70
- private ComponentIntermediateNode RewriteAsComponent ( TagHelperIntermediateNode node , TagHelperDescriptor tagHelper )
70
+ private static ComponentIntermediateNode RewriteAsComponent ( TagHelperIntermediateNode node , TagHelperDescriptor tagHelper )
71
71
{
72
72
var component = new ComponentIntermediateNode ( )
73
73
{
@@ -89,13 +89,54 @@ private ComponentIntermediateNode RewriteAsComponent(TagHelperIntermediateNode n
89
89
// because we see the nodes in the wrong order.
90
90
foreach ( var childContent in component . ChildContents )
91
91
{
92
- childContent . ParameterName = childContent . ParameterName ?? component . ChildContentParameterName ?? ComponentMetadata . ChildContent . DefaultParameterName ;
92
+ childContent . ParameterName ??= component . ChildContentParameterName ?? ComponentMetadata . ChildContent . DefaultParameterName ;
93
93
}
94
94
95
+ ValidateRequiredAttributes ( node , tagHelper , component ) ;
96
+
95
97
return component ;
96
98
}
97
99
98
- private MarkupElementIntermediateNode RewriteAsElement ( TagHelperIntermediateNode node )
100
+ private static void ValidateRequiredAttributes ( TagHelperIntermediateNode node , TagHelperDescriptor tagHelper , ComponentIntermediateNode intermediateNode )
101
+ {
102
+ if ( intermediateNode . Children . Any ( c => c is TagHelperDirectiveAttributeIntermediateNode node && ( node . TagHelper ? . IsSplatTagHelper ( ) ?? false ) ) )
103
+ {
104
+ // If there are any splat attributes, assume the user may have provided all values.
105
+ // This pass runs earlier than ComponentSplatLoweringPass, so we cannot rely on the presence of SplatIntermediateNode to make this check.
106
+ return ;
107
+ }
108
+
109
+ foreach ( var requiredAttribute in tagHelper . EditorRequiredAttributes )
110
+ {
111
+ if ( ! IsPresentAsAttribute ( requiredAttribute . Name , intermediateNode ) )
112
+ {
113
+ intermediateNode . Diagnostics . Add (
114
+ RazorDiagnosticFactory . CreateComponent_EditorRequiredParameterNotSpecified (
115
+ node . Source ?? SourceSpan . Undefined ,
116
+ intermediateNode . TagName ,
117
+ requiredAttribute . Name ) ) ;
118
+ }
119
+ }
120
+
121
+ static bool IsPresentAsAttribute ( string attributeName , ComponentIntermediateNode intermediateNode )
122
+ {
123
+ foreach ( var child in intermediateNode . Children )
124
+ {
125
+ if ( child is ComponentAttributeIntermediateNode attributeNode && attributeName == attributeNode . AttributeName )
126
+ {
127
+ return true ;
128
+ }
129
+ else if ( child is ComponentChildContentIntermediateNode childContent && attributeName == childContent . AttributeName )
130
+ {
131
+ return true ;
132
+ }
133
+ }
134
+
135
+ return false ;
136
+ }
137
+ }
138
+
139
+ private static MarkupElementIntermediateNode RewriteAsElement ( TagHelperIntermediateNode node )
99
140
{
100
141
var result = new MarkupElementIntermediateNode ( )
101
142
{
0 commit comments