Fix bug in bind lowering logic

\n\nCommit migrated from 5bcd008779
This commit is contained in:
Ajay Bhargav Baaskaran 2019-05-22 12:35:05 -07:00 committed by Doug Bunting
parent 95bb698c5a
commit db66452bbd
8 changed files with 92 additions and 15 deletions

View File

@ -48,13 +48,17 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
} }
// First, collect all the non-parameterized bind or bind-* attributes. // First, collect all the non-parameterized bind or bind-* attributes.
var bindEntries = new Dictionary<string, BindEntry>(); // The dict key is a tuple of (parent, attributeName) to differentiate attributes with the same name in two different elements.
// We don't have to worry about duplicate bound attributes in the same element
// like, <Foo bind="bar" bind="bar" />, because IR lowering takes care of that.
var bindEntries = new Dictionary<(IntermediateNode, string), BindEntry>();
for (var i = 0; i < references.Count; i++) for (var i = 0; i < references.Count; i++)
{ {
var reference = references[i]; var reference = references[i];
var parent = reference.Parent;
var node = (TagHelperPropertyIntermediateNode)reference.Node; var node = (TagHelperPropertyIntermediateNode)reference.Node;
if (!reference.Parent.Children.Contains(node)) if (!parent.Children.Contains(node))
{ {
// This node was removed as a duplicate, skip it. // This node was removed as a duplicate, skip it.
continue; continue;
@ -62,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
if (node.TagHelper.IsBindTagHelper() && node.AttributeName.StartsWith("bind")) if (node.TagHelper.IsBindTagHelper() && node.AttributeName.StartsWith("bind"))
{ {
bindEntries[node.AttributeName] = new BindEntry(reference); bindEntries[(parent, node.AttributeName)] = new BindEntry(reference);
} }
} }
@ -70,9 +74,10 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
for (var i = 0; i < parameterReferences.Count; i++) for (var i = 0; i < parameterReferences.Count; i++)
{ {
var parameterReference = parameterReferences[i]; var parameterReference = parameterReferences[i];
var parent = parameterReference.Parent;
var node = (TagHelperAttributeParameterIntermediateNode)parameterReference.Node; var node = (TagHelperAttributeParameterIntermediateNode)parameterReference.Node;
if (!parameterReference.Parent.Children.Contains(node)) if (!parent.Children.Contains(node))
{ {
// This node was removed as a duplicate, skip it. // This node was removed as a duplicate, skip it.
continue; continue;
@ -80,7 +85,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
if (node.TagHelper.IsBindTagHelper() && node.AttributeName.StartsWith("bind")) if (node.TagHelper.IsBindTagHelper() && node.AttributeName.StartsWith("bind"))
{ {
if (!bindEntries.TryGetValue(node.AttributeNameWithoutParameter, out var entry)) // Check if this tag contains a corresponding non-parameterized bind node.
if (!bindEntries.TryGetValue((parent, node.AttributeNameWithoutParameter), out var entry))
{ {
// There is no corresponding bind node. Add a diagnostic and move on. // There is no corresponding bind node. Add a diagnostic and move on.
parameterReference.Parent.Diagnostics.Add(ComponentDiagnosticFactory.CreateBindAttributeParameter_MissingBind( parameterReference.Parent.Diagnostics.Add(ComponentDiagnosticFactory.CreateBindAttributeParameter_MissingBind(

View File

@ -2573,6 +2573,7 @@ namespace Test
// Act // Act
var generated = CompileToCSharp(@" var generated = CompileToCSharp(@"
<MyComponent bind-Item=Value/> <MyComponent bind-Item=Value/>
<MyComponent bind-Item=Value/>
@code { @code {
string Value; string Value;
}"); }");

View File

@ -34,13 +34,30 @@ namespace Test
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml" #line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = typeof(MyComponent<>); __o = typeof(MyComponent<>);
#line default
#line hidden
#nullable disable
__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_1(builder, -1, -1, Microsoft.AspNetCore.Components.BindMethods.GetValue(
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
Value
#line default
#line hidden
#nullable disable
), -1,
__value => Value = __value);
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
__o = typeof(MyComponent<>);
#line default #line default
#line hidden #line hidden
#nullable disable #nullable disable
} }
#pragma warning restore 1998 #pragma warning restore 1998
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
string Value; string Value;
@ -61,6 +78,13 @@ namespace __Blazor.Test.TestComponent
builder.AddAttribute(__seq1, "ItemChanged", __arg1); builder.AddAttribute(__seq1, "ItemChanged", __arg1);
builder.CloseComponent(); builder.CloseComponent();
} }
public static void CreateMyComponent_1<TItem>(global::Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int seq, int __seq0, TItem __arg0, int __seq1, global::System.Action<TItem> __arg1)
{
builder.OpenComponent<global::Test.MyComponent<TItem>>(seq);
builder.AddAttribute(__seq0, "Item", __arg0);
builder.AddAttribute(__seq1, "ItemChanged", __arg1);
builder.CloseComponent();
}
} }
} }
#pragma warning restore 1591 #pragma warning restore 1591

View File

@ -25,8 +25,20 @@ Document -
IntermediateToken - - CSharp - __value => Value = __value IntermediateToken - - CSharp - __value => Value = __value
HtmlContent - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) HtmlContent - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n IntermediateToken - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) Component - (32:1,0 [30] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent
IntermediateToken - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\n ComponentAttribute - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Item - AttributeStructure.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindMethods.GetValue(
IntermediateToken - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Value
IntermediateToken - - CSharp - )
ComponentAttribute - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - ItemChanged - AttributeStructure.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - __value => Value = __value
HtmlContent - (62:1,30 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (62:1,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\n
NamespaceDeclaration - - __Blazor.Test.TestComponent NamespaceDeclaration - - __Blazor.Test.TestComponent
ClassDeclaration - - internal static - TypeInference - - ClassDeclaration - - internal static - TypeInference - -
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_0 ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_0
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_1

View File

@ -3,11 +3,16 @@ Source Location: (23:0,23 [5] x:\dir\subdir\Test\TestComponent.cshtml)
Generated Location: (1012:25,23 [5] ) Generated Location: (1012:25,23 [5] )
|Value| |Value|
Source Location: (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml)
|Value|
Generated Location: (1521:42,23 [5] )
|Value|
Source Location: (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
| |
string Value; string Value;
| |
Generated Location: (1408:43,7 [21] ) Generated Location: (1917:60,7 [21] )
| |
string Value; string Value;
| |

View File

@ -22,10 +22,20 @@ namespace Test
#line hidden #line hidden
#nullable disable #nullable disable
), 2, __value => Value = __value); ), 2, __value => Value = __value);
builder.AddMarkupContent(3, "\r\n");
__Blazor.Test.TestComponent.TypeInference.CreateMyComponent_1(builder, 4, 5, Microsoft.AspNetCore.Components.BindMethods.GetValue(
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
Value
#line default
#line hidden
#nullable disable
), 6, __value => Value = __value);
} }
#pragma warning restore 1998 #pragma warning restore 1998
#nullable restore #nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml" #line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
string Value; string Value;
@ -46,6 +56,13 @@ namespace __Blazor.Test.TestComponent
builder.AddAttribute(__seq1, "ItemChanged", __arg1); builder.AddAttribute(__seq1, "ItemChanged", __arg1);
builder.CloseComponent(); builder.CloseComponent();
} }
public static void CreateMyComponent_1<TItem>(global::Microsoft.AspNetCore.Components.RenderTree.RenderTreeBuilder builder, int seq, int __seq0, TItem __arg0, int __seq1, global::System.Action<TItem> __arg1)
{
builder.OpenComponent<global::Test.MyComponent<TItem>>(seq);
builder.AddAttribute(__seq0, "Item", __arg0);
builder.AddAttribute(__seq1, "ItemChanged", __arg1);
builder.CloseComponent();
}
} }
} }
#pragma warning restore 1591 #pragma warning restore 1591

View File

@ -16,8 +16,20 @@ Document -
ComponentAttribute - (23:0,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - ItemChanged - AttributeStructure.DoubleQuotes ComponentAttribute - (23:0,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - ItemChanged - AttributeStructure.DoubleQuotes
CSharpExpression - CSharpExpression -
IntermediateToken - - CSharp - __value => Value = __value IntermediateToken - - CSharp - __value => Value = __value
CSharpCode - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) HtmlContent - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\n IntermediateToken - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
Component - (32:1,0 [30] x:\dir\subdir\Test\TestComponent.cshtml) - MyComponent
ComponentAttribute - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - Item - AttributeStructure.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - Microsoft.AspNetCore.Components.BindMethods.GetValue(
IntermediateToken - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - Value
IntermediateToken - - CSharp - )
ComponentAttribute - (55:1,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - ItemChanged - AttributeStructure.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - __value => Value = __value
CSharpCode - (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\n
NamespaceDeclaration - - __Blazor.Test.TestComponent NamespaceDeclaration - - __Blazor.Test.TestComponent
ClassDeclaration - - internal static - TypeInference - - ClassDeclaration - - internal static - TypeInference - -
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_0 ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_0
ComponentTypeInferenceMethod - - __Blazor.Test.TestComponent.TypeInference - CreateMyComponent_1

View File

@ -1,8 +1,8 @@
Source Location: (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) Source Location: (71:2,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
| |
string Value; string Value;
| |
Generated Location: (973:28,7 [21] ) Generated Location: (1365:38,7 [21] )
| |
string Value; string Value;
| |