Fix #1068
This changes the bind lowering pass to be more tolerant of unexpected and invalid content.
This commit is contained in:
parent
844e38e641
commit
8724b84a14
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -478,19 +478,30 @@ namespace Microsoft.AspNetCore.Blazor.Razor
|
||||||
{
|
{
|
||||||
// This case can be hit for a 'string' attribute. We want to turn it into
|
// This case can be hit for a 'string' attribute. We want to turn it into
|
||||||
// an expression.
|
// an expression.
|
||||||
var content = "\"" + ((IntermediateToken)htmlContentNode.Children.Single()).Content + "\"";
|
var content = "\"" + string.Join(string.Empty, htmlContentNode.Children.OfType<IntermediateToken>().Select(t => t.Content)) + "\"";
|
||||||
return new IntermediateToken() { Kind = TokenKind.CSharp, Content = content };
|
return new IntermediateToken() { Kind = TokenKind.CSharp, Content = content };
|
||||||
}
|
}
|
||||||
else if (node.Children[0] is CSharpExpressionIntermediateNode cSharpNode)
|
else if (node.Children[0] is CSharpExpressionIntermediateNode cSharpNode)
|
||||||
{
|
{
|
||||||
// This case can be hit when the attribute has an explicit @ inside, which
|
// This case can be hit when the attribute has an explicit @ inside, which
|
||||||
// 'escapes' any special sugar we provide for codegen.
|
// 'escapes' any special sugar we provide for codegen.
|
||||||
return ((IntermediateToken)cSharpNode.Children.Single());
|
return GetToken(cSharpNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This is the common case for 'mixed' content
|
// This is the common case for 'mixed' content
|
||||||
return ((IntermediateToken)node.Children.Single());
|
return GetToken(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// In error cases we won't have a single token, but we still want to generate the code.
|
||||||
|
IntermediateToken GetToken(IntermediateNode parent)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
parent.Children.Count == 1 ? (IntermediateToken)parent.Children[0] : new IntermediateToken()
|
||||||
|
{
|
||||||
|
Kind = TokenKind.CSharp,
|
||||||
|
Content = string.Join(string.Empty, parent.Children.OfType<IntermediateToken>().Select(t => t.Content)),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright (c) .NET Foundation. All rights reserved.
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -33,20 +33,28 @@ namespace Test
|
||||||
[Parameter] Action<int> ValueChanged { get; set; }
|
[Parameter] Action<int> ValueChanged { get; set; }
|
||||||
[Parameter] string AnotherValue { get; set; }
|
[Parameter] string AnotherValue { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ModelState
|
||||||
|
{
|
||||||
|
public Action<string> Bind(Func<string, string> func) => throw null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"));
|
"));
|
||||||
var text = @"
|
var text = @"
|
||||||
@addTagHelper *, TestAssembly
|
@addTagHelper *, TestAssembly
|
||||||
<div>
|
<div>
|
||||||
<MyComponent bind-Value=""myValue"" AnotherValue=""hi""/>
|
<MyComponent bind-Value=""myValue"" AnotherValue=""hi""/>
|
||||||
<input type=""text"" bind=""@value"" />
|
<input type=""text"" bind=""@this.ModelState.Bind(x => x)"" />
|
||||||
<button ref=""_button"" onsubmit=""@FormSubmitted"">Click me</button>
|
<button ref=""_button"" onsubmit=""@FormSubmitted"">Click me</button>
|
||||||
</div>
|
</div>
|
||||||
<MyComponent
|
<MyComponent
|
||||||
IntProperty=""123""
|
IntProperty=""123""
|
||||||
BoolProperty=""true""
|
BoolProperty=""true""
|
||||||
StringProperty=""My string""
|
StringProperty=""My string""
|
||||||
ObjectProperty=""new SomeType()""/>";
|
ObjectProperty=""new SomeType()""/>
|
||||||
|
@functions {
|
||||||
|
Test.ModelState ModelState { get; set; }
|
||||||
|
}";
|
||||||
|
|
||||||
for (var i = 0; i <= text.Length; i++)
|
for (var i = 0; i <= text.Length; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -66,5 +74,21 @@ Exception:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact] // Regression test for #1068
|
||||||
|
public void Regression_1068()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var generated = CompileToCSharp(@"
|
||||||
|
<input type=""text"" bind="" />
|
||||||
|
@functions {
|
||||||
|
Test.ModelState ModelState { get; set; }
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue