Change TagHelperBlockRewriter's error usage to use RazorDiagnosticFactory.

- Changed `DefaultRazorDiagnostic` to expose a little more information for tests. This info is only available when casted to the `DefaultRazorDiagnostic` type and only available internally.
- Changed parameter order of a `DefaultTagHelperTargetExtension` diagnostic.
- Updated baselines of files in `Razor.Language.Test`.
- Added a new convenience constructor on `SourceSpan`. The ctor is equivalent to calling the class with a SourceLocation.

#1827
This commit is contained in:
N. Taylor Mullen 2017-12-20 16:45:04 -08:00
parent bd03c16ee7
commit 63aceea121
9 changed files with 435 additions and 314 deletions

View File

@ -8,26 +8,29 @@ namespace Microsoft.AspNetCore.Razor.Language
{ {
internal class DefaultRazorDiagnostic : RazorDiagnostic internal class DefaultRazorDiagnostic : RazorDiagnostic
{ {
private readonly RazorDiagnosticDescriptor _descriptor;
private readonly object[] _args;
internal DefaultRazorDiagnostic(RazorDiagnosticDescriptor descriptor, SourceSpan span, object[] args) internal DefaultRazorDiagnostic(RazorDiagnosticDescriptor descriptor, SourceSpan span, object[] args)
{ {
_descriptor = descriptor; Descriptor = descriptor;
Span = span; Span = span;
_args = args; Args = args;
} }
public override string Id => _descriptor.Id; public override string Id => Descriptor.Id;
public override RazorDiagnosticSeverity Severity => _descriptor.Severity; public override RazorDiagnosticSeverity Severity => Descriptor.Severity;
public override SourceSpan Span { get; } public override SourceSpan Span { get; }
// Internal for testing
internal RazorDiagnosticDescriptor Descriptor { get; }
// Internal for testing
internal object[] Args { get; }
public override string GetMessage(IFormatProvider formatProvider) public override string GetMessage(IFormatProvider formatProvider)
{ {
var format = _descriptor.GetMessageFormat(); var format = Descriptor.GetMessageFormat();
return string.Format(formatProvider, format, _args); return string.Format(formatProvider, format, Args);
} }
public override bool Equals(RazorDiagnostic obj) public override bool Equals(RazorDiagnostic obj)
@ -38,7 +41,7 @@ namespace Microsoft.AspNetCore.Razor.Language
return false; return false;
} }
if (!_descriptor.Equals(other._descriptor)) if (!Descriptor.Equals(other.Descriptor))
{ {
return false; return false;
} }
@ -48,14 +51,14 @@ namespace Microsoft.AspNetCore.Razor.Language
return false; return false;
} }
if (_args.Length != other._args.Length) if (Args.Length != other.Args.Length)
{ {
return false; return false;
} }
for (var i = 0; i < _args.Length; i++) for (var i = 0; i < Args.Length; i++)
{ {
if (!_args[i].Equals(other._args[i])) if (!Args[i].Equals(other.Args[i]))
{ {
return false; return false;
} }
@ -67,12 +70,12 @@ namespace Microsoft.AspNetCore.Razor.Language
public override int GetHashCode() public override int GetHashCode()
{ {
var hash = new HashCodeCombiner(); var hash = new HashCodeCombiner();
hash.Add(_descriptor.GetHashCode()); hash.Add(Descriptor.GetHashCode());
hash.Add(Span.GetHashCode()); hash.Add(Span.GetHashCode());
for (var i = 0; i < _args.Length; i++) for (var i = 0; i < Args.Length; i++)
{ {
hash.Add(_args[i]); hash.Add(Args[i]);
} }
return hash; return hash;

View File

@ -581,7 +581,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Extensions
else if (node is TemplateIntermediateNode) else if (node is TemplateIntermediateNode)
{ {
var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName; var expectedTypeName = property.IsIndexerNameMatch ? property.BoundAttribute.IndexerTypeName : property.BoundAttribute.TypeName;
var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(expectedTypeName, span ?? SourceSpan.Undefined); var diagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(span ?? SourceSpan.Undefined, expectedTypeName);
context.Diagnostics.Add(diagnostic); context.Diagnostics.Add(diagnostic);
} }
} }

View File

@ -61,8 +61,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
// Only want to track the attribute if we succeeded in parsing its corresponding Block/Span. // Only want to track the attribute if we succeeded in parsing its corresponding Block/Span.
if (result != null) if (result != null)
{ {
SourceLocation? errorLocation = null;
// Check if it's a non-boolean bound attribute that is minimized or if it's a bound // Check if it's a non-boolean bound attribute that is minimized or if it's a bound
// non-string attribute that has null or whitespace content. // non-string attribute that has null or whitespace content.
var isMinimized = result.AttributeValueNode == null; var isMinimized = result.AttributeValueNode == null;
@ -74,32 +72,19 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
result.IsBoundNonStringAttribute && result.IsBoundNonStringAttribute &&
IsNullOrWhitespaceAttributeValue(result.AttributeValueNode))) IsNullOrWhitespaceAttributeValue(result.AttributeValueNode)))
{ {
errorLocation = GetAttributeNameStartLocation(child); var errorLocation = GetAttributeNameLocation(child, result.AttributeName);
var propertyTypeName = GetPropertyType(result.AttributeName, bindingResult.Descriptors);
errorSink.OnError( var diagnostic = RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(errorLocation, result.AttributeName, tagName, propertyTypeName);
errorLocation.Value, errorSink.OnError(diagnostic);
LegacyResources.FormatRewriterError_EmptyTagHelperBoundAttribute(
result.AttributeName,
tagName,
GetPropertyType(result.AttributeName, bindingResult.Descriptors)),
result.AttributeName.Length);
} }
// Check if the attribute was a prefix match for a tag helper dictionary property but the // Check if the attribute was a prefix match for a tag helper dictionary property but the
// dictionary key would be the empty string. // dictionary key would be the empty string.
if (result.IsMissingDictionaryKey) if (result.IsMissingDictionaryKey)
{ {
if (!errorLocation.HasValue) var errorLocation = GetAttributeNameLocation(child, result.AttributeName);
{ var diagnostic = RazorDiagnosticFactory.CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(errorLocation, result.AttributeName, tagName);
errorLocation = GetAttributeNameStartLocation(child); errorSink.OnError(diagnostic);
}
errorSink.OnError(
errorLocation.Value,
LegacyResources.FormatTagHelperBlockRewriter_IndexerAttributeNameMustIncludeKey(
result.AttributeName,
tagName),
result.AttributeName.Length);
} }
var attributeNode = new TagHelperAttributeNode( var attributeNode = new TagHelperAttributeNode(
@ -299,10 +284,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
// ex: <myTH class="btn"| | // ex: <myTH class="btn"| |
if (!string.IsNullOrWhiteSpace(span.Content)) if (!string.IsNullOrWhiteSpace(span.Content))
{ {
errorSink.OnError( var location = new SourceSpan(span.Start, span.Content.Length);
span.Start, var diagnostic = RazorDiagnosticFactory.CreateParsing_TagHelperAttributeListMustBeWellFormed(location);
LegacyResources.TagHelperBlockRewriter_TagHelperAttributeListMustBeWellFormed, errorSink.OnError(diagnostic);
span.Content.Length);
} }
return null; return null;
@ -341,10 +325,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
if (childSpan == null || childSpan.Kind != SpanKindInternal.Markup) if (childSpan == null || childSpan.Kind != SpanKindInternal.Markup)
{ {
errorSink.OnError( var location = new SourceSpan(block.Start, block.Length);
block.Start, var diagnostic = RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(location, tagName);
LegacyResources.FormatTagHelpers_CannotHaveCSharpInTagDeclaration(tagName), errorSink.OnError(diagnostic);
block.Length);
return null; return null;
} }
@ -368,10 +351,9 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var name = string.Concat(nameSymbols); var name = string.Concat(nameSymbols);
if (string.IsNullOrEmpty(name)) if (string.IsNullOrEmpty(name))
{ {
errorSink.OnError( var location = new SourceSpan(childSpan.Start, childSpan.Length);
childSpan.Start, var diagnostic = RazorDiagnosticFactory.CreateParsing_TagHelperAttributesMustHaveAName(location, tagName);
LegacyResources.FormatTagHelpers_AttributesMustHaveAName(tagName), errorSink.OnError(diagnostic);
childSpan.Length);
return null; return null;
} }
@ -609,7 +591,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
return builder.Build(); return builder.Build();
} }
private static SourceLocation GetAttributeNameStartLocation(SyntaxTreeNode node) private static SourceSpan GetAttributeNameLocation(SyntaxTreeNode node, string attributeName)
{ {
Span span; Span span;
var nodeStart = SourceLocation.Undefined; var nodeStart = SourceLocation.Undefined;
@ -635,7 +617,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
.OfType<HtmlSymbol>() .OfType<HtmlSymbol>()
.First(sym => sym.Type != HtmlSymbolType.WhiteSpace && sym.Type != HtmlSymbolType.NewLine); .First(sym => sym.Type != HtmlSymbolType.WhiteSpace && sym.Type != HtmlSymbolType.NewLine);
return firstNonWhitespaceSymbol.Start; var location = new SourceSpan(firstNonWhitespaceSymbol.Start, attributeName.Length);
return location;
} }
private static Span CreateMarkupAttribute(SpanBuilder builder, TryParseResult result) private static Span CreateMarkupAttribute(SpanBuilder builder, TryParseResult result)

View File

@ -330,6 +330,46 @@ namespace Microsoft.AspNetCore.Razor.Language
return RazorDiagnostic.Create(Parsing_RazorCommentNotTerminated, location); return RazorDiagnostic.Create(Parsing_RazorCommentNotTerminated, location);
} }
internal static readonly RazorDiagnosticDescriptor Parsing_TagHelperIndexerAttributeNameMustIncludeKey =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}1029",
() => LegacyResources.TagHelperBlockRewriter_IndexerAttributeNameMustIncludeKey,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(SourceSpan location, string attributeName, string tagName)
{
return RazorDiagnostic.Create(Parsing_TagHelperIndexerAttributeNameMustIncludeKey, location, attributeName, tagName);
}
internal static readonly RazorDiagnosticDescriptor Parsing_TagHelperAttributeListMustBeWellFormed =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}1030",
() => LegacyResources.TagHelperBlockRewriter_TagHelperAttributeListMustBeWellFormed,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateParsing_TagHelperAttributeListMustBeWellFormed(SourceSpan location)
{
return RazorDiagnostic.Create(Parsing_TagHelperAttributeListMustBeWellFormed, location);
}
internal static readonly RazorDiagnosticDescriptor Parsing_TagHelpersCannotHaveCSharpInTagDeclaration =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}1031",
() => LegacyResources.TagHelpers_CannotHaveCSharpInTagDeclaration,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(SourceSpan location, string tagName)
{
return RazorDiagnostic.Create(Parsing_TagHelpersCannotHaveCSharpInTagDeclaration, location, tagName);
}
internal static readonly RazorDiagnosticDescriptor Parsing_TagHelperAttributesMustHaveAName =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}1032",
() => LegacyResources.TagHelpers_AttributesMustHaveAName,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateParsing_TagHelperAttributesMustHaveAName(SourceSpan location, string tagName)
{
return RazorDiagnostic.Create(Parsing_TagHelperAttributesMustHaveAName, location, tagName);
}
#endregion #endregion
#region Semantic Errors #region Semantic Errors
@ -412,7 +452,7 @@ namespace Microsoft.AspNetCore.Razor.Language
$"{DiagnosticPrefix}2007", $"{DiagnosticPrefix}2007",
() => LegacyResources.TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes, () => LegacyResources.TagHelpers_InlineMarkupBlocks_NotSupported_InAttributes,
RazorDiagnosticSeverity.Error); RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(string expectedTypeName, SourceSpan location) public static RazorDiagnostic CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(SourceSpan location, string expectedTypeName)
{ {
var diagnostic = RazorDiagnostic.Create( var diagnostic = RazorDiagnostic.Create(
TagHelper_InlineMarkupBlocksNotSupportedInAttributes, TagHelper_InlineMarkupBlocksNotSupportedInAttributes,
@ -422,6 +462,16 @@ namespace Microsoft.AspNetCore.Razor.Language
return diagnostic; return diagnostic;
} }
internal static readonly RazorDiagnosticDescriptor TagHelper_EmptyBoundAttribute =
new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}2008",
() => LegacyResources.RewriterError_EmptyTagHelperBoundAttribute,
RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateTagHelper_EmptyBoundAttribute(SourceSpan location, string attributeName, string tagName, string propertyTypeName)
{
return RazorDiagnostic.Create(TagHelper_EmptyBoundAttribute, location, attributeName, tagName, propertyTypeName);
}
#endregion #endregion
#region TagHelper Errors #region TagHelper Errors
@ -625,7 +675,7 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static readonly RazorDiagnosticDescriptor TagHelper_InvalidTargetedAttributeNameNullOrWhitespace = internal static readonly RazorDiagnosticDescriptor TagHelper_InvalidTargetedAttributeNameNullOrWhitespace =
new RazorDiagnosticDescriptor( new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3009", $"{DiagnosticPrefix}3011",
() => Resources.TagHelper_InvalidTargetedAttributeNameNullOrWhitespace, () => Resources.TagHelper_InvalidTargetedAttributeNameNullOrWhitespace,
RazorDiagnosticSeverity.Error); RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace() public static RazorDiagnostic CreateTagHelper_InvalidTargetedAttributeNameNullOrWhitespace()
@ -639,7 +689,7 @@ namespace Microsoft.AspNetCore.Razor.Language
internal static readonly RazorDiagnosticDescriptor TagHelper_InvalidTargetedAttributeName = internal static readonly RazorDiagnosticDescriptor TagHelper_InvalidTargetedAttributeName =
new RazorDiagnosticDescriptor( new RazorDiagnosticDescriptor(
$"{DiagnosticPrefix}3010", $"{DiagnosticPrefix}3012",
() => Resources.TagHelper_InvalidTargetedAttributeName, () => Resources.TagHelper_InvalidTargetedAttributeName,
RazorDiagnosticSeverity.Error); RazorDiagnosticSeverity.Error);
public static RazorDiagnostic CreateTagHelper_InvalidTargetedAttributeName(string invalidAttributeName, char invalidCharacter) public static RazorDiagnostic CreateTagHelper_InvalidTargetedAttributeName(string invalidAttributeName, char invalidCharacter)

View File

@ -30,6 +30,11 @@ namespace Microsoft.AspNetCore.Razor.Language
FilePath = filePath; FilePath = filePath;
} }
public SourceSpan(int absoluteIndex, int lineIndex, int characterIndex, int length)
: this(filePath: null, absoluteIndex: absoluteIndex, lineIndex: lineIndex, characterIndex: characterIndex, length: length)
{
}
public int Length { get; } public int Length { get; }
public int AbsoluteIndex { get; } public int AbsoluteIndex { get; }

View File

@ -393,7 +393,7 @@ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
IsIndexerNameMatch = true, IsIndexerNameMatch = true,
}; };
var expectedLocation = new SourceSpan(100, 10); var expectedLocation = new SourceSpan(100, 10);
var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes("System.Int32", expectedLocation); var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(expectedLocation, "System.Int32");
// Act // Act
extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation); extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation);
@ -416,8 +416,8 @@ EndAddHtmlAttributeValues(__tagHelperExecutionContext);
}; };
var expectedLocation = new SourceSpan(100, 10); var expectedLocation = new SourceSpan(100, 10);
var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes( var expectedDiagnostic = RazorDiagnosticFactory.CreateTagHelper_InlineMarkupBlocksNotSupportedInAttributes(
"System.Collections.Generic.Dictionary<System.String, System.Int32>", expectedLocation,
expectedLocation); "System.Collections.Generic.Dictionary<System.String, System.Int32>");
// Act // Act
extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation); extension.RenderTagHelperAttributeInline(context, node, new TemplateIntermediateNode(), expectedLocation);

View File

@ -346,8 +346,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var errorFormatUnclosed = "Found a malformed '{0}' tag helper. Tag helpers must have a start and " + var errorFormatUnclosed = "Found a malformed '{0}' tag helper. Tag helpers must have a start and " +
"end tag or be self closing."; "end tag or be self closing.";
var errorFormatNoCloseAngle = "Missing close angle for tag helper '{0}'."; var errorFormatNoCloseAngle = "Missing close angle for tag helper '{0}'.";
var errorFormatNoCSharp = "The tag helper '{0}' must not have C# in the element's attribute " +
"declaration area.";
Func<string, Block> createInvalidDoBlock = extraCode => Func<string, Block> createInvalidDoBlock = extraCode =>
{ {
return new MarkupBlock( return new MarkupBlock(
@ -472,10 +470,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"), string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateParsing_TagHelperAttributeListMustBeWellFormed(new SourceSpan(12, 0, 12, 1))
"TagHelper attributes must be well-formed.",
new SourceLocation(12, 0, 12),
length: 1))
} }
}, },
{ {
@ -629,9 +624,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p")), new MarkupTagHelperBlock("p")),
new [] new []
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 13), "p")
string.Format(CultureInfo.InvariantCulture, errorFormatNoCSharp, "p"),
absoluteIndex: 3, lineIndex: 0 , columnIndex: 3, length: 13))
} }
}, },
{ {
@ -640,9 +633,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
new MarkupTagHelperBlock("p")), new MarkupTagHelperBlock("p")),
new [] new []
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 13), "p")
string.Format(CultureInfo.InvariantCulture, errorFormatNoCSharp, "p"),
absoluteIndex: 3, lineIndex: 0 , columnIndex: 3, length: 13))
} }
}, },
{ {
@ -737,9 +728,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"), string.Format(CultureInfo.InvariantCulture, errorFormatUnclosed, "p"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateParsing_TagHelpersCannotHaveCSharpInTagDeclaration(new SourceSpan(3, 0, 3, 30), "p"),
string.Format(CultureInfo.InvariantCulture, errorFormatNoCSharp, "p"),
absoluteIndex: 3, lineIndex: 0 , columnIndex: 3, length: 30)),
RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF( RazorDiagnosticFactory.CreateParsing_ExpectedEndOfBlockBeforeEOF(
new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "do", "}", "{"), new SourceSpan(new SourceLocation(4, 0, 4), contentLength: 1), "do", "}", "{"),
RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag( RazorDiagnosticFactory.CreateParsing_UnexpectedEndTag(
@ -756,10 +745,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new [] new []
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateParsing_TagHelperAttributeListMustBeWellFormed(new SourceSpan(13, 0, 13, 13))
"TagHelper attributes must be well-formed.",
new SourceLocation(13, 0, 13),
length: 13))
} }
}, },
}; };
@ -1920,9 +1906,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
get get
{ {
var factory = new SpanFactory(); var factory = new SpanFactory();
var emptyAttributeError =
"Attribute '{0}' on tag helper element '{1}' requires a value. Tag helper bound attributes of " +
"type '{2}' cannot be empty or contain only whitespace.";
var boolTypeName = typeof(bool).FullName; var boolTypeName = typeof(bool).FullName;
// documentContent, expectedOutput, expectedErrors // documentContent, expectedOutput, expectedErrors
@ -1940,9 +1923,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)) "bound",
"myth",
boolTypeName)
} }
}, },
{ {
@ -1975,9 +1960,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)) "bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -1993,12 +1980,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "bound",
RazorDiagnostic.Create(new RazorError( "myth",
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), boolTypeName),
absoluteIndex: 16, lineIndex: 0, columnIndex: 16, length: 5)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(16, 0, 16, 5),
"bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2019,12 +2010,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "bound",
RazorDiagnostic.Create(new RazorError( "myth",
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), boolTypeName),
absoluteIndex: 17, lineIndex: 0, columnIndex: 17, length: 5)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(17, 0, 17, 5),
"bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2046,9 +2041,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(19, 0, 19, 5),
absoluteIndex: 19, lineIndex: 0, columnIndex: 19, length: 5)) "bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2067,9 +2064,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2088,9 +2087,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2117,9 +2118,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "bound", "myth", boolTypeName), new SourceSpan(31, 0, 31, 5),
absoluteIndex: 31, lineIndex: 0, columnIndex: 31, length: 5)), "bound",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2134,9 +2137,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "BouND", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "BouND",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2152,12 +2157,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "BOUND", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)), "BOUND",
RazorDiagnostic.Create(new RazorError( "myth",
string.Format(emptyAttributeError, "bOUnd", "myth", boolTypeName), boolTypeName),
absoluteIndex: 18, lineIndex: 0, columnIndex: 18, length: 5)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(18, 0, 18, 5),
"bOUnd",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2175,9 +2184,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(emptyAttributeError, "BOUND", "myth", boolTypeName), new SourceSpan(6, 0, 6, 5),
absoluteIndex: 6, lineIndex: 0, columnIndex: 6, length: 5)) "BOUND",
"myth",
boolTypeName),
} }
}, },
{ {
@ -2865,10 +2876,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{ {
var factory = new SpanFactory(); var factory = new SpanFactory();
var noErrors = new RazorDiagnostic[0]; var noErrors = new RazorDiagnostic[0];
var errorFormat = "Attribute '{0}' on tag helper element '{1}' requires a value. Tag helper bound " +
"attributes of type '{2}' cannot be empty or contain only whitespace.";
var emptyKeyFormat = "The tag helper attribute '{0}' in element '{1}' is missing a key. The " +
"syntax is '<{1} {0}{{ key }}=\"value\">'.";
var stringType = typeof(string).FullName; var stringType = typeof(string).FullName;
var intType = typeof(int).FullName; var intType = typeof(int).FullName;
var expressionString = "@DateTime.Now + 1"; var expressionString = "@DateTime.Now + 1";
@ -2921,8 +2928,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-string", "p", stringType), 3, 0, 3, 12)) new SourceSpan(3, 0, 3, 12),
"bound-string",
"p",
stringType),
} }
}, },
{ {
@ -2937,8 +2947,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-string", "input", stringType), 7, 0, 7, 21)) new SourceSpan(7, 0, 7, 21),
"bound-required-string",
"input",
stringType),
} }
}, },
{ {
@ -2953,8 +2966,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-int", "input", intType), 7, 0, 7, 18)) new SourceSpan(7, 0, 7, 18),
"bound-required-int",
"input",
intType),
} }
}, },
{ {
@ -2967,7 +2983,14 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
{ {
new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized), new TagHelperAttributeNode("bound-int", null, AttributeStructure.Minimized),
})), })),
new[] { RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 3, 0, 3, 9)) } new[]
{
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(3, 0, 3, 9),
"bound-int",
"p",
intType),
}
}, },
{ {
"<input int-dictionary/>", "<input int-dictionary/>",
@ -2981,12 +3004,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "int-dictionary", "input", typeof(IDictionary<string, int>).Namespace + ".IDictionary<System.String, System.Int32>"), new SourceSpan(7, 0, 7, 14),
absoluteIndex: 7, "int-dictionary",
lineIndex: 0, "input",
columnIndex: 7, typeof(IDictionary<string, int>).Namespace + ".IDictionary<System.String, System.Int32>"),
length: 14)),
} }
}, },
{ {
@ -3001,12 +3023,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "string-dictionary", "input", typeof(IDictionary<string, string>).Namespace + ".IDictionary<System.String, System.String>"), new SourceSpan(7, 0, 7, 17),
absoluteIndex: 7, "string-dictionary",
lineIndex: 0, "input",
columnIndex: 7, typeof(IDictionary<string, string>).Namespace + ".IDictionary<System.String, System.String>"),
length: 17)),
} }
}, },
{ {
@ -3021,18 +3042,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "int-prefix-", "input", typeof(int).FullName), new SourceSpan(7, 0, 7, 11),
absoluteIndex: 7, "int-prefix-",
lineIndex: 0, "input",
columnIndex: 7, intType),
length: 11)), RazorDiagnosticFactory.CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(
RazorDiagnostic.Create(new RazorError( new SourceSpan(7, 0, 7, 11),
string.Format(emptyKeyFormat, "int-prefix-", "input"), "int-prefix-",
absoluteIndex: 7, "input"),
lineIndex: 0,
columnIndex: 7,
length: 11)),
} }
}, },
{ {
@ -3047,18 +3065,15 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "string-prefix-", "input", typeof(string).FullName), new SourceSpan(7, 0, 7, 14),
absoluteIndex: 7, "string-prefix-",
lineIndex: 0, "input",
columnIndex: 7, stringType),
length: 14)), RazorDiagnosticFactory.CreateParsing_TagHelperIndexerAttributeNameMustIncludeKey(
RazorDiagnostic.Create(new RazorError( new SourceSpan(7, 0, 7, 14),
string.Format(emptyKeyFormat, "string-prefix-", "input"), "string-prefix-",
absoluteIndex: 7, "input"),
lineIndex: 0,
columnIndex: 7,
length: 14)),
} }
}, },
{ {
@ -3073,12 +3088,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "int-prefix-value", "input", typeof(int).FullName), new SourceSpan(7, 0, 7, 16),
absoluteIndex: 7, "int-prefix-value",
lineIndex: 0, "input",
columnIndex: 7, intType),
length: 16)),
} }
}, },
{ {
@ -3093,12 +3107,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "string-prefix-value", "input", typeof(string).FullName), new SourceSpan(7, 0, 7, 19),
absoluteIndex: 7, "string-prefix-value",
lineIndex: 0, "input",
columnIndex: 7, stringType),
length: 19)),
} }
}, },
{ {
@ -3113,12 +3126,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "int-prefix-value", "input", typeof(int).FullName), new SourceSpan(7, 0, 7, 16),
absoluteIndex: 7, "int-prefix-value",
lineIndex: 0, "input",
columnIndex: 7, intType),
length: 16)),
} }
}, },
{ {
@ -3178,12 +3190,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-string", "input", stringType), new SourceSpan(24, 0, 24, 21),
absoluteIndex: 24, "bound-required-string",
lineIndex: 0, "input",
columnIndex: 24, stringType),
length: 21))
} }
}, },
{ {
@ -3199,8 +3210,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 3, 0, 3, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-string", "p", stringType), 13, 0, 13, 12)), new SourceSpan(3, 0, 3, 9),
"bound-int",
"p",
intType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(13, 0, 13, 12),
"bound-string",
"p",
stringType),
} }
}, },
{ {
@ -3217,14 +3236,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-int", "input", intType), 7, 0, 7, 18)), new SourceSpan(7, 0, 7, 18),
RazorDiagnostic.Create(new RazorError( "bound-required-int",
string.Format(errorFormat, "bound-required-string", "input", stringType), "input",
absoluteIndex: 43, intType),
lineIndex: 0, RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
columnIndex: 43, new SourceSpan(43, 0, 43, 21),
length: 21)) "bound-required-string",
"input",
stringType),
} }
}, },
{ {
@ -3241,9 +3262,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 3, 0, 3, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-string", "p", stringType), 13, 0, 13, 12)), new SourceSpan(3, 0, 3, 9),
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-string", "p", stringType), 26, 0, 26, 12)), "bound-int",
"p",
intType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(13, 0, 13, 12),
"bound-string",
"p",
stringType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(26, 0, 26, 12),
"bound-string",
"p",
stringType),
} }
}, },
{ {
@ -3272,12 +3305,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-string", "p", stringType), new SourceSpan(3, 0, 3, 12),
absoluteIndex: 3, "bound-string",
lineIndex: 0, "p",
columnIndex: 3, stringType),
length: 12))
} }
}, },
{ {
@ -3306,12 +3338,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-string", "p", stringType), new SourceSpan(15, 0, 15, 12),
absoluteIndex: 15, "bound-string",
lineIndex: 0, "p",
columnIndex: 15, stringType),
length: 12))
} }
}, },
{ {
@ -3327,12 +3358,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-string", "input", stringType), new SourceSpan(7, 0, 7, 21),
absoluteIndex: 7, "bound-required-string",
lineIndex: 0, "input",
columnIndex: 7, stringType),
length: 21))
} }
}, },
{ {
@ -3348,12 +3378,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-string", "input", stringType), new SourceSpan(19, 0, 19, 21),
absoluteIndex: 19, "bound-required-string",
lineIndex: 0, "input",
columnIndex: 19, stringType),
length: 21))
} }
}, },
{ {
@ -3369,8 +3398,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-int", "input", intType), 7, 0, 7, 18)) new SourceSpan(7, 0, 7, 18),
"bound-required-int",
"input",
intType),
} }
}, },
{ {
@ -3386,7 +3418,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 3, 0, 3, 9)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(3, 0, 3, 9),
"bound-int",
"p",
intType),
} }
}, },
{ {
@ -3402,7 +3438,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-required-int", "input", intType), 19, 0, 19, 18)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(19, 0, 19, 18),
"bound-required-int",
"input",
intType),
} }
}, },
{ {
@ -3418,7 +3458,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 15, 0, 15, 9)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(15, 0, 15, 9),
"bound-int",
"p",
intType),
} }
}, },
{ {
@ -3434,8 +3478,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-int", "input", intType), 33, 0, 33, 18)) new SourceSpan(33, 0, 33, 18),
"bound-required-int",
"input",
intType),
} }
}, },
{ {
@ -3451,7 +3498,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 29, 0, 29, 9)) RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(29, 0, 29, 9),
"bound-int",
"p",
intType),
} }
}, },
{ {
@ -3471,14 +3522,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormat, "bound-required-int", "input", intType), 10, 0, 10, 18)), new SourceSpan(10, 0, 10, 18),
RazorDiagnostic.Create(new RazorError( "bound-required-int",
string.Format(errorFormat, "bound-required-string", "input", stringType), "input",
absoluteIndex: 57, intType),
lineIndex: 0, RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
columnIndex: 57, new SourceSpan(57, 0, 57, 21),
length: 21)), "bound-required-string",
"input",
stringType),
} }
}, },
{ {
@ -3498,9 +3551,21 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
})), })),
new[] new[]
{ {
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-int", "p", intType), 6, 0, 6, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-string", "p", stringType), 44, 0, 44, 12)), new SourceSpan(6, 0, 6, 9),
RazorDiagnostic.Create(new RazorError(string.Format(errorFormat, "bound-string", "p", stringType), 84, 0, 84, 12)), "bound-int",
"p",
intType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(44, 0, 44, 12),
"bound-string",
"p",
stringType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(84, 0, 84, 12),
"bound-string",
"p",
stringType),
} }
}, },
}; };
@ -3611,11 +3676,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
for (var i = 0; i < errors.Length; i++) for (var i = 0; i < errors.Length; i++)
{ {
var error = errors[i]; var error = errors[i] as DefaultRazorDiagnostic;
var currentErrorLocation = new SourceLocation(error.Span.AbsoluteIndex, error.Span.LineIndex, error.Span.CharacterIndex); var currentErrorLocation = new SourceLocation(error.Span.AbsoluteIndex, error.Span.LineIndex, error.Span.CharacterIndex);
var newErrorLocation = SourceLocationTracker.Advance(currentErrorLocation, "@{"); var newErrorLocation = SourceLocationTracker.Advance(currentErrorLocation, "@{");
var newError = new RazorError(error.GetMessage(), newErrorLocation, error.Span.Length); var copiedDiagnostic = new DefaultRazorDiagnostic(error.Descriptor, new SourceSpan(newErrorLocation, error.Span.Length), error.Args);
errors[i] = RazorDiagnostic.Create(newError); errors[i] = copiedDiagnostic;
} }
} }
@ -3632,8 +3697,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var errorFormatUnclosed = "Found a malformed '{0}' tag helper. Tag helpers must have a start and " + var errorFormatUnclosed = "Found a malformed '{0}' tag helper. Tag helpers must have a start and " +
"end tag or be self closing."; "end tag or be self closing.";
var errorFormatNoCloseAngle = "Missing close angle for tag helper '{0}'."; var errorFormatNoCloseAngle = "Missing close angle for tag helper '{0}'.";
var errorFormatNoValue = "Attribute '{0}' on tag helper element '{1}' requires a value. Tag helper bound " +
"attributes of type '{2}' cannot be empty or contain only whitespace.";
var stringType = typeof(string).FullName; var stringType = typeof(string).FullName;
var intType = typeof(int).FullName; var intType = typeof(int).FullName;
@ -3682,12 +3745,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "input"), string.Format(errorFormatUnclosed, "input"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 5)), length: 5)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormatNoValue, "bound-required-string", "input", stringType), new SourceSpan(7, 0, 7, 21),
absoluteIndex: 7, "bound-required-string",
lineIndex: 0, "input",
columnIndex: 7, stringType),
length: 21)),
} }
}, },
{ {
@ -3710,12 +3772,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "input"), string.Format(errorFormatUnclosed, "input"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 5)), length: 5)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormatNoValue, "bound-required-int", "input", intType), new SourceSpan(7, 0, 7, 18),
absoluteIndex: 7, "bound-required-int",
lineIndex: 0, "input",
columnIndex: 7, intType),
length: 18)),
} }
}, },
{ {
@ -3740,18 +3801,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "input"), string.Format(errorFormatUnclosed, "input"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 5)), length: 5)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormatNoValue, "bound-required-int", "input", intType), new SourceSpan(7, 0, 7, 18),
absoluteIndex: 7, "bound-required-int",
lineIndex: 0, "input",
columnIndex: 7, intType),
length: 18)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError( new SourceSpan(43, 0, 43, 21),
string.Format(errorFormatNoValue, "bound-required-string", "input", stringType), "bound-required-string",
absoluteIndex: 43, "input",
lineIndex: 0, stringType),
columnIndex: 43,
length: 21)),
} }
}, },
{ {
@ -3774,8 +3833,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "p"), string.Format(errorFormatUnclosed, "p"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormatNoValue, "bound-string", "p", stringType), 3, 0, 3, 12)), new SourceSpan(3, 0, 3, 12),
"bound-string",
"p",
stringType),
} }
}, },
{ {
@ -3798,7 +3860,11 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "p"), string.Format(errorFormatUnclosed, "p"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError(string.Format(errorFormatNoValue, "bound-int", "p", intType), 3, 0, 3, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(3, 0, 3, 9),
"bound-int",
"p",
intType),
} }
}, },
{ {
@ -3822,9 +3888,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "p"), string.Format(errorFormatUnclosed, "p"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError(string.Format(errorFormatNoValue, "bound-int", "p", intType), 3, 0, 3, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError( new SourceSpan(3, 0, 3, 9),
string.Format(errorFormatNoValue, "bound-string", "p", stringType), 13, 0, 13, 12)), "bound-int",
"p",
intType),
RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceSpan(13, 0, 13, 12),
"bound-string",
"p",
stringType),
} }
}, },
{ {
@ -3857,14 +3930,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "input"), string.Format(errorFormatUnclosed, "input"),
new SourceLocation(1, 0, 1), new SourceLocation(1, 0, 1),
length: 5)), length: 5)),
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
string.Format(errorFormatNoValue, "bound-required-int", "input", intType), 7, 0, 7, 18)), new SourceSpan(7, 0, 7, 18),
RazorDiagnostic.Create(new RazorError( "bound-required-int",
string.Format(errorFormatNoValue, "bound-required-string", "input", stringType), "input",
absoluteIndex: 43, intType),
lineIndex: 0, RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
columnIndex: 43, new SourceSpan(43, 0, 43, 21),
length: 21)), "bound-required-string",
"input",
stringType),
RazorDiagnostic.Create(new RazorError( RazorDiagnostic.Create(new RazorError(
string.Format(errorFormatNoCloseAngle, "p"), string.Format(errorFormatNoCloseAngle, "p"),
new SourceLocation(65, 0, 65), new SourceLocation(65, 0, 65),
@ -3873,13 +3948,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
string.Format(errorFormatUnclosed, "p"), string.Format(errorFormatUnclosed, "p"),
new SourceLocation(65, 0, 65), new SourceLocation(65, 0, 65),
length: 1)), length: 1)),
RazorDiagnostic.Create(new RazorError(string.Format(errorFormatNoValue, "bound-int", "p", intType), 67, 0, 67, 9)), RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
RazorDiagnostic.Create(new RazorError( new SourceSpan(67, 0, 67, 9),
string.Format(errorFormatNoValue, "bound-string", "p", stringType), "bound-int",
absoluteIndex: 77, "p",
lineIndex: 0, intType),
columnIndex: 77, RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
length: 12)), new SourceSpan(77, 0, 77, 12),
"bound-string",
"p",
stringType),
} }
}, },
}; };
@ -4036,14 +4114,16 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
var expectedErrors = new[] var expectedErrors = new[]
{ {
RazorDiagnostic.Create(new RazorError( RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
"Attribute 'boundbool' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.", new SourceSpan(7, 0, 7, 9),
new SourceLocation(7, 0, 7), "boundbool",
length: 9)), "input",
RazorDiagnostic.Create(new RazorError( "System.Boolean"),
"Attribute 'boundbooldict-key' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.", RazorDiagnosticFactory.CreateTagHelper_EmptyBoundAttribute(
new SourceLocation(17, 0, 17), new SourceSpan(17, 0, 17, 17),
length: 17)), "boundbooldict-key",
"input",
"System.Boolean"),
}; };
// Act & Assert // Act & Assert

View File

@ -1,3 +1,3 @@
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ9999: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ9999: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ2008: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ9999: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.

View File

@ -1,3 +1,3 @@
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ9999: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(4,18): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ9999: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(5,8): Error RZ2008: Attribute 'age' on tag helper element 'p' requires a value. Tag helper bound attributes of type 'System.Int32' cannot be empty or contain only whitespace.
TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ9999: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace. TestFiles/IntegrationTests/CodeGenerationIntegrationTest/EmptyAttributeTagHelpers.cshtml(6,23): Error RZ2008: Attribute 'checked' on tag helper element 'input' requires a value. Tag helper bound attributes of type 'System.Boolean' cannot be empty or contain only whitespace.