diff --git a/src/Microsoft.AspNetCore.Razor.Language/Extensions/DefaultTagHelperTargetExtension.cs b/src/Microsoft.AspNetCore.Razor.Language/Extensions/DefaultTagHelperTargetExtension.cs index 3a6247a47e..6311a900d9 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/Extensions/DefaultTagHelperTargetExtension.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/Extensions/DefaultTagHelperTargetExtension.cs @@ -550,7 +550,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions } } - private void RenderTagHelperAttributeInline( + // Internal for testing + internal void RenderTagHelperAttributeInline( CodeRenderingContext context, DefaultTagHelperPropertyIntermediateNode property, IntermediateNode node, @@ -574,20 +575,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions } else if (node is CSharpCodeIntermediateNode) { - var error = new RazorError( - LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes, - SourceLocation.FromSpan(span), - span == null ? -1 : span.Value.Length); - context.Diagnostics.Add(RazorDiagnostic.Create(error)); + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined); + context.Diagnostics.Add(diagnostic); } else if (node is TemplateIntermediateNode) { var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName; - var error = new RazorError( - LegacyResources.FormatTagHelpers_InlineMarkupBlocks_NotSupported_InAttributes(expectedTypeName), - SourceLocation.FromSpan(span), - span == null ? -1 : span.Value.Length); - context.Diagnostics.Add(RazorDiagnostic.Create(error)); + var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(expectedTypeName, span ?? SourceSpan.Undefined); + context.Diagnostics.Add(diagnostic); } } diff --git a/src/Microsoft.AspNetCore.Razor.Language/RazorDiagnosticFactory.cs b/src/Microsoft.AspNetCore.Razor.Language/RazorDiagnosticFactory.cs index b3ff262373..b6b1887b43 100644 --- a/src/Microsoft.AspNetCore.Razor.Language/RazorDiagnosticFactory.cs +++ b/src/Microsoft.AspNetCore.Razor.Language/RazorDiagnosticFactory.cs @@ -85,6 +85,32 @@ namespace Microsoft.AspNetCore.Razor.Language return RazorDiagnostic.Create(Parsing_SectionsCannotBeNested, location, LegacyResources.SectionExample_CS); } + internal static readonly RazorDiagnosticDescriptor TagHelper_CodeBlocksNotSupportedInAttributes = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}2003", + () => LegacyResources.TagHelpers_CodeBlocks_NotSupported_InAttributes, + RazorDiagnosticSeverity.Error); + public static RazorDiagnostic CreateTagHelper_CodeBlocksNotSupportedInAttributes(SourceSpan location) + { + var diagnostic = RazorDiagnostic.Create(TagHelper_CodeBlocksNotSupportedInAttributes, location); + return diagnostic; + } + + internal static readonly RazorDiagnosticDescriptor TagHelper_InlineMarkupBlocksNotSupportedInAttributes = + new RazorDiagnosticDescriptor( + $"{DiagnosticPrefix}2004", + () => LegacyResources.TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes, + RazorDiagnosticSeverity.Error); + public static RazorDiagnostic CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(string expectedTypeName, SourceSpan location) + { + var diagnostic = RazorDiagnostic.Create( + TagHelper_InlineMarkupBlocksNotSupportedInAttributes, + location, + expectedTypeName); + + return diagnostic; + } + #endregion #region TagHelper Errors diff --git a/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs b/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs index 79aba5837c..cbcedb8316 100644 --- a/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs +++ b/test/Microsoft.AspNetCore.Razor.Language.Test/Extensions/DefaultTagHelperTargetExtensionTest.cs @@ -359,6 +359,74 @@ EndAddHtmlAttributeValues(__tagHelperExecutionContext); ignoreLineEndingDifferences: true); } + [Fact] + public void RenderTagHelperAttributeInline_NonString_StatementInAttribute_Errors() + { + // Arrange + var extension = new DefaultTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new DefaultTagHelperPropertyIntermediateNode() + { + BoundAttribute = IntPropertyTagHelper.BoundAttributes.Single(), + IsIndexerNameMatch = false, + }; + var expectedLocation = new SourceSpan(100, 10); + var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_CodeBlocksNotSupportedInAttributes(expectedLocation); + + // Act + extension.RenderTagHelperAttributeInline(context, node, new CSharpCodeIntermediateNode(), expectedLocation); + + // Assert + var diagnostic = Assert.Single(context.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RenderTagHelperAttributeInline_NonStringIndexerMatch_TemplateInAttribute_Errors() + { + // Arrange + var extension = new DefaultTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new DefaultTagHelperPropertyIntermediateNode() + { + BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(), + IsIndexerNameMatch = true, + }; + var expectedLocation = new SourceSpan(100, 10); + var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes("System.Int32", expectedLocation); + + // Act + extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation); + + // Assert + var diagnostic = Assert.Single(context.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + + [Fact] + public void RenderTagHelperAttributeInline_NonString_TemplateInAttribute_Errors() + { + // Arrange + var extension = new DefaultTagHelperTargetExtension(); + var context = TestCodeRenderingContext.CreateRuntime(); + var node = new DefaultTagHelperPropertyIntermediateNode() + { + BoundAttribute = IntIndexerTagHelper.BoundAttributes.Single(), + IsIndexerNameMatch = false, + }; + var expectedLocation = new SourceSpan(100, 10); + var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes( + "System.Collections.Generic.Dictionary", + expectedLocation); + + // Act + extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation); + + // Assert + var diagnostic = Assert.Single(context.Diagnostics); + Assert.Equal(expectedDiagnostic, diagnostic); + } + [Fact] public void WriteTagHelperProperty_DesignTime_StringProperty_HtmlContent_RendersCorrectly() {