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.
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++)
{
var reference = references[i];
var parent = reference.Parent;
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.
continue;
@ -62,7 +66,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
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++)
{
var parameterReference = parameterReferences[i];
var parent = parameterReference.Parent;
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.
continue;
@ -80,7 +85,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Components
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.
parameterReference.Parent.Diagnostics.Add(ComponentDiagnosticFactory.CreateBindAttributeParameter_MissingBind(

View File

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

View File

@ -34,13 +34,30 @@ namespace Test
#line 1 "x:\dir\subdir\Test\TestComponent.cshtml"
__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 hidden
#nullable disable
}
#pragma warning restore 1998
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
string Value;
@ -61,6 +78,13 @@ namespace __Blazor.Test.TestComponent
builder.AddAttribute(__seq1, "ItemChanged", __arg1);
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

View File

@ -25,8 +25,20 @@ Document -
IntermediateToken - - CSharp - __value => Value = __value
HtmlContent - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml) - Html - \n
CSharpCode - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\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
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
ClassDeclaration - - internal static - TypeInference - -
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] )
|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;
|
Generated Location: (1408:43,7 [21] )
Generated Location: (1917:60,7 [21] )
|
string Value;
|

View File

@ -22,10 +22,20 @@ namespace Test
#line hidden
#nullable disable
), 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
#nullable restore
#line 2 "x:\dir\subdir\Test\TestComponent.cshtml"
#line 3 "x:\dir\subdir\Test\TestComponent.cshtml"
string Value;
@ -46,6 +56,13 @@ namespace __Blazor.Test.TestComponent
builder.AddAttribute(__seq1, "ItemChanged", __arg1);
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

View File

@ -16,8 +16,20 @@ Document -
ComponentAttribute - (23:0,23 [5] x:\dir\subdir\Test\TestComponent.cshtml) - ItemChanged - AttributeStructure.DoubleQuotes
CSharpExpression -
IntermediateToken - - CSharp - __value => Value = __value
CSharpCode - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml)
IntermediateToken - (39:1,7 [21] x:\dir\subdir\Test\TestComponent.cshtml) - CSharp - \n string Value;\n
HtmlContent - (30:0,30 [2] x:\dir\subdir\Test\TestComponent.cshtml)
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
ClassDeclaration - - internal static - TypeInference - -
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;
|
Generated Location: (973:28,7 [21] )
Generated Location: (1365:38,7 [21] )
|
string Value;
|