Add indexer null-check for preallocated tag helper attributes
This commit is contained in:
parent
e3287ae672
commit
27ac5da6d5
|
|
@ -1,6 +1,7 @@
|
|||
// 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.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Razor.Language.Intermediate;
|
||||
using Microsoft.AspNetCore.Razor.Language.Legacy;
|
||||
|
||||
|
|
@ -18,6 +19,8 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
|
||||
public string ExecutionContextAddTagHelperAttributeMethodName { get; set; } = "AddTagHelperAttribute";
|
||||
|
||||
public string FormatInvalidIndexerAssignmentMethodName { get; set; } = "InvalidTagHelperIndexerAssignment";
|
||||
|
||||
public void WriteDeclarePreallocatedTagHelperHtmlAttribute(CSharpRenderingContext context, DeclarePreallocatedTagHelperHtmlAttributeIRNode node)
|
||||
{
|
||||
context.Writer
|
||||
|
|
@ -74,8 +77,39 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
public void WriteSetPreallocatedTagHelperProperty(CSharpRenderingContext context, SetPreallocatedTagHelperPropertyIRNode node)
|
||||
{
|
||||
var tagHelperVariableName = GetTagHelperVariableName(node.TagHelperTypeName);
|
||||
var propertyName = node.Descriptor.GetPropertyName();
|
||||
var propertyValueAccessor = GetTagHelperPropertyAccessor(node.IsIndexerNameMatch, tagHelperVariableName, node.AttributeName, node.Descriptor);
|
||||
var attributeValueAccessor = $"{node.VariableName}.Value" /* ORIGINAL: TagHelperAttributeValuePropertyName */;
|
||||
|
||||
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
|
||||
if (node.IsIndexerNameMatch &&
|
||||
context.TagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelperTypeName}.{propertyName}"))
|
||||
{
|
||||
// Throw a reasonable Exception at runtime if the dictionary property is null.
|
||||
context.Writer
|
||||
.Write("if (")
|
||||
.Write(tagHelperVariableName)
|
||||
.Write(".")
|
||||
.Write(propertyName)
|
||||
.WriteLine(" == null)");
|
||||
using (context.Writer.BuildScope())
|
||||
{
|
||||
// System is in Host.NamespaceImports for all MVC scenarios. No need to generate FullName
|
||||
// of InvalidOperationException type.
|
||||
context.Writer
|
||||
.Write("throw ")
|
||||
.WriteStartNewObject(nameof(InvalidOperationException))
|
||||
.WriteStartMethodInvocation(FormatInvalidIndexerAssignmentMethodName)
|
||||
.WriteStringLiteral(node.AttributeName)
|
||||
.WriteParameterSeparator()
|
||||
.WriteStringLiteral(node.TagHelperTypeName)
|
||||
.WriteParameterSeparator()
|
||||
.WriteStringLiteral(propertyName)
|
||||
.WriteEndMethodInvocation(endLine: false) // End of method call
|
||||
.WriteEndMethodInvocation(); // End of new expression / throw statement
|
||||
}
|
||||
}
|
||||
|
||||
context.Writer
|
||||
.WriteStartAssignment(propertyValueAccessor)
|
||||
.Write("(string)")
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ namespace Microsoft.AspNetCore.Razor.Language.CodeGeneration
|
|||
|
||||
// Ensure that the property we're trying to set has initialized its dictionary bound properties.
|
||||
if (node.IsIndexerNameMatch &&
|
||||
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add(propertyName))
|
||||
tagHelperRenderingContext.VerifiedPropertyDictionaries.Add($"{node.TagHelperTypeName}.{propertyName}"))
|
||||
{
|
||||
// Throw a reasonable Exception at runtime if the dictionary property is null.
|
||||
context.Writer
|
||||
|
|
|
|||
|
|
@ -171,7 +171,8 @@ __tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
|
|||
var extension = new PreallocatedAttributeTargetExtension();
|
||||
var context = new CSharpRenderingContext()
|
||||
{
|
||||
Writer = new CSharpCodeWriter()
|
||||
Writer = new CSharpCodeWriter(),
|
||||
TagHelperRenderingContext = new TagHelperRenderingContext()
|
||||
};
|
||||
|
||||
var descriptor = BoundAttributeDescriptorBuilder
|
||||
|
|
@ -197,7 +198,11 @@ __tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
|
|||
// Assert
|
||||
var csharp = context.Writer.Builder.ToString();
|
||||
Assert.Equal(
|
||||
@"__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
|
||||
@"if (__FooTagHelper.FooProp == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment(""pre-Foo"", ""FooTagHelper"", ""FooProp""));
|
||||
}
|
||||
__FooTagHelper.FooProp[""Foo""] = (string)_tagHelper1.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(_tagHelper1);
|
||||
",
|
||||
csharp,
|
||||
|
|
|
|||
|
|
@ -105,6 +105,10 @@ __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"] = 37;
|
|||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-garlic", __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
|
||||
if (__TestNamespace_InputTagHelper2.IntDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-garlic", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper2.IntDictionaryProperty["garlic"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["garlic"];
|
||||
#line 17 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
|
||||
__TestNamespace_InputTagHelper1.IntProperty = 42;
|
||||
|
|
@ -140,6 +144,10 @@ __TestNamespace_InputTagHelper1.IntProperty = 42;
|
|||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-grabber", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper2.IntDictionaryProperty["grabber"] = __TestNamespace_InputTagHelper1.IntProperty;
|
||||
if (__TestNamespace_InputTagHelper1.IntDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-salt", "TestNamespace.InputTagHelper1", "IntDictionaryProperty"));
|
||||
}
|
||||
#line 19 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
|
||||
__TestNamespace_InputTagHelper1.IntDictionaryProperty["salt"] = 37;
|
||||
|
||||
|
|
@ -157,16 +165,20 @@ __TestNamespace_InputTagHelper1.IntDictionaryProperty["pepper"] = 98;
|
|||
__tagHelperExecutionContext.AddHtmlAttribute(__tagHelperAttribute_3);
|
||||
__TestNamespace_InputTagHelper1.StringProperty = (string)__tagHelperAttribute_4.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
|
||||
if (__TestNamespace_InputTagHelper2.StringDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-grabber", "TestNamespace.InputTagHelper2", "StringDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper2.StringDictionaryProperty["grabber"] = (string)__tagHelperAttribute_4.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_4);
|
||||
if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-paprika", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper1.StringDictionaryProperty["paprika"] = (string)__tagHelperAttribute_5.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
|
||||
__TestNamespace_InputTagHelper2.StringDictionaryProperty["paprika"] = (string)__tagHelperAttribute_5.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_5);
|
||||
if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-cumin", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
|
||||
}
|
||||
BeginWriteTagHelperAttribute();
|
||||
WriteLiteral("literate ");
|
||||
#line 21 "TestFiles/IntegrationTests/CodeGenerationIntegrationTest/PrefixedAttributeTagHelpers.cshtml"
|
||||
|
|
@ -204,9 +216,21 @@ __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"] = 37;
|
|||
#line default
|
||||
#line hidden
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute("int-prefix-value", __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"], global::Microsoft.AspNetCore.Razor.TagHelpers.HtmlAttributeValueStyle.DoubleQuotes);
|
||||
if (__TestNamespace_InputTagHelper2.IntDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("int-prefix-value", "TestNamespace.InputTagHelper2", "IntDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper2.IntDictionaryProperty["value"] = __TestNamespace_InputTagHelper1.IntDictionaryProperty["value"];
|
||||
if (__TestNamespace_InputTagHelper1.StringDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-thyme", "TestNamespace.InputTagHelper1", "StringDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper1.StringDictionaryProperty["thyme"] = (string)__tagHelperAttribute_6.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
|
||||
if (__TestNamespace_InputTagHelper2.StringDictionaryProperty == null)
|
||||
{
|
||||
throw new InvalidOperationException(InvalidTagHelperIndexerAssignment("string-prefix-thyme", "TestNamespace.InputTagHelper2", "StringDictionaryProperty"));
|
||||
}
|
||||
__TestNamespace_InputTagHelper2.StringDictionaryProperty["thyme"] = (string)__tagHelperAttribute_6.Value;
|
||||
__tagHelperExecutionContext.AddTagHelperAttribute(__tagHelperAttribute_6);
|
||||
await __tagHelperRunner.RunAsync(__tagHelperExecutionContext);
|
||||
|
|
|
|||
Loading…
Reference in New Issue