Expose source start/end tags on TagHelperBlocks.
- This is to enable the DesignTime to understand TagHelperBlocks full source structure in order to auto format the document.
This commit is contained in:
parent
44b530dd22
commit
36f02690d2
|
|
@ -32,6 +32,8 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
|||
Attributes = new Dictionary<string, SyntaxTreeNode>(source.Attributes);
|
||||
_start = source.Start;
|
||||
SelfClosing = source.SelfClosing;
|
||||
SourceStartTag = source.SourceStartTag;
|
||||
SourceEndTag = source.SourceEndTag;
|
||||
|
||||
source.Reset();
|
||||
|
||||
|
|
@ -41,6 +43,18 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unrewritten source start tag.
|
||||
/// </summary>
|
||||
/// <remarks>This is used by design time to properly format <see cref="TagHelperBlock"/>s.</remarks>
|
||||
public Block SourceStartTag { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the unrewritten source end tag.
|
||||
/// </summary>
|
||||
/// <remarks>This is used by design time to properly format <see cref="TagHelperBlock"/>s.</remarks>
|
||||
public Block SourceEndTag { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether or not the tag is self closing.
|
||||
/// </summary>
|
||||
|
|
@ -70,6 +84,18 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
|||
/// </summary>
|
||||
public string TagName { get; private set; }
|
||||
|
||||
public override int Length
|
||||
{
|
||||
get
|
||||
{
|
||||
var startTagLength = SourceStartTag?.Length ?? 0;
|
||||
var childrenLength = base.Length;
|
||||
var endTagLength = SourceEndTag?.Length ?? 0;
|
||||
|
||||
return startTagLength + childrenLength + endTagLength;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString()
|
||||
{
|
||||
|
|
@ -99,11 +125,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
|||
/// <inheritdoc />
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCodeCombiner.Start()
|
||||
.Add(TagName)
|
||||
.Add(Attributes)
|
||||
.Add(base.GetHashCode())
|
||||
.CombinedHash;
|
||||
return HashCodeCombiner
|
||||
.Start()
|
||||
.Add(TagName)
|
||||
.Add(Attributes)
|
||||
.Add(base.GetHashCode())
|
||||
.CombinedHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -74,6 +74,18 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the unrewritten source start tag.
|
||||
/// </summary>
|
||||
/// <remarks>This is used by design time to properly format <see cref="TagHelperBlock"/>s.</remarks>
|
||||
public Block SourceStartTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the unrewritten source end tag.
|
||||
/// </summary>
|
||||
/// <remarks>This is used by design time to properly format <see cref="TagHelperBlock"/>s.</remarks>
|
||||
public Block SourceEndTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the tag in the Razor source was self-closing.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -17,11 +17,12 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
{
|
||||
private static readonly string StringTypeName = typeof(string).FullName;
|
||||
|
||||
public static TagHelperBlockBuilder Rewrite(string tagName,
|
||||
bool validStructure,
|
||||
Block tag,
|
||||
IEnumerable<TagHelperDescriptor> descriptors,
|
||||
ParserErrorSink errorSink)
|
||||
public static TagHelperBlockBuilder Rewrite(
|
||||
string tagName,
|
||||
bool validStructure,
|
||||
Block tag,
|
||||
IEnumerable<TagHelperDescriptor> descriptors,
|
||||
ParserErrorSink errorSink)
|
||||
{
|
||||
// There will always be at least one child for the '<'.
|
||||
var start = tag.Children.First().Start;
|
||||
|
|
@ -74,8 +75,8 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
// Check if it's a bound attribute that is not of type string and happens to be null or whitespace.
|
||||
string attributeValueType;
|
||||
if (attributeValueTypes.TryGetValue(attribute.Key, out attributeValueType) &&
|
||||
!IsStringAttribute(attributeValueType) &&
|
||||
IsNullOrWhitespaceAttributeValue(attribute.Value))
|
||||
!IsStringAttribute(attributeValueType) &&
|
||||
IsNullOrWhitespaceAttributeValue(attribute.Value))
|
||||
{
|
||||
var errorLocation = GetAttributeNameStartLocation(child);
|
||||
|
||||
|
|
|
|||
|
|
@ -121,11 +121,16 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
|
||||
var validTagStructure = ValidTagStructure(tagName, tagBlock, context);
|
||||
|
||||
var builder = TagHelperBlockRewriter.Rewrite(tagName,
|
||||
validTagStructure,
|
||||
tagBlock,
|
||||
descriptors,
|
||||
context.ErrorSink);
|
||||
var builder = TagHelperBlockRewriter.Rewrite(
|
||||
tagName,
|
||||
validTagStructure,
|
||||
tagBlock,
|
||||
descriptors,
|
||||
context.ErrorSink);
|
||||
|
||||
// Track the original start tag so the editor knows where each piece of the TagHelperBlock lies
|
||||
// for formatting.
|
||||
builder.SourceStartTag = tagBlock;
|
||||
|
||||
// Found a new tag helper block
|
||||
TrackTagHelperBlock(builder);
|
||||
|
|
@ -134,7 +139,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
// within the tag... complete it.
|
||||
if (builder.SelfClosing)
|
||||
{
|
||||
BuildCurrentlyTrackedTagHelperBlock();
|
||||
BuildCurrentlyTrackedTagHelperBlock(endTag: null);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -149,14 +154,14 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
{
|
||||
ValidTagStructure(tagName, tagBlock, context);
|
||||
|
||||
BuildCurrentlyTrackedTagHelperBlock();
|
||||
BuildCurrentlyTrackedTagHelperBlock(tagBlock);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Current tag helper scope does not match the end tag. Attempt to recover the tag
|
||||
// helper by looking up the previous tag helper scopes for a matching tag. If we
|
||||
// can't recover it means there was no corresponding tag helper begin tag.
|
||||
if (TryRecoverTagHelper(tagName, context))
|
||||
if (TryRecoverTagHelper(tagName, tagBlock, context))
|
||||
{
|
||||
ValidTagStructure(tagName, tagBlock, context);
|
||||
|
||||
|
|
@ -230,9 +235,11 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
}
|
||||
}
|
||||
|
||||
private void BuildCurrentlyTrackedTagHelperBlock()
|
||||
private void BuildCurrentlyTrackedTagHelperBlock(Block endTag)
|
||||
{
|
||||
_tagStack.Pop();
|
||||
// Track the original end tag so the editor knows where each piece of the TagHelperBlock lies
|
||||
// for formatting.
|
||||
_tagStack.Pop().SourceEndTag = endTag;
|
||||
|
||||
BuildCurrentlyTrackedBlock();
|
||||
}
|
||||
|
|
@ -268,7 +275,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
TrackBlock(builder);
|
||||
}
|
||||
|
||||
private bool TryRecoverTagHelper(string tagName, RewritingContext context)
|
||||
private bool TryRecoverTagHelper(string tagName, Block endTag, RewritingContext context)
|
||||
{
|
||||
var malformedTagHelperCount = 0;
|
||||
|
||||
|
|
@ -289,7 +296,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
BuildMalformedTagHelpers(malformedTagHelperCount, context);
|
||||
|
||||
// One final build, this is the build that completes our target tag helper block which is not malformed.
|
||||
BuildCurrentlyTrackedTagHelperBlock();
|
||||
BuildCurrentlyTrackedTagHelperBlock(endTag);
|
||||
|
||||
// We were able to recover
|
||||
return true;
|
||||
|
|
@ -310,7 +317,7 @@ namespace Microsoft.AspNet.Razor.Parser.TagHelpers.Internal
|
|||
RazorResources.FormatTagHelpersParseTreeRewriter_FoundMalformedTagHelper(
|
||||
malformedTagHelper.TagName));
|
||||
|
||||
BuildCurrentlyTrackedTagHelperBlock();
|
||||
BuildCurrentlyTrackedTagHelperBlock(endTag: null);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue