/// <summary> /// Instantiates a new <see cref="TagHelperBlockBuilder"/> instance based on the given /// <paramref name="original"/>. /// </summary> /// <param name="original">The original <see cref="TagHelperBlock"/> to copy data from.</param> public TagHelperBlockBuilder(TagHelperBlock original) : base(original) { TagName = original.TagName; Descriptors = original.Descriptors; Attributes = new List<KeyValuePair<string, SyntaxTreeNode>>(original.Attributes); }
private static void EvaluateTagHelperBlock(ErrorCollector collector, TagHelperBlock actual, TagHelperBlock expected) { if (expected == null) { AddMismatchError(collector, actual, expected); } else { var expectedAttributes = expected.Attributes.GetEnumerator(); var actualAttributes = actual.Attributes.GetEnumerator(); while (expectedAttributes.MoveNext()) { if (!actualAttributes.MoveNext()) { collector.AddError("{0} - FAILED :: No more attributes on this node", expectedAttributes.Current); } else { EvaluateTagHelperAttribute(collector, actualAttributes.Current, expectedAttributes.Current); } } while (actualAttributes.MoveNext()) { collector.AddError("End of Attributes - FAILED :: Found Attribute: {0}", actualAttributes.Current.Key); } } }
/// <summary> /// Instantiates a new <see cref="TagHelperBlockBuilder"/> instance based on the given /// <paramref name="original"/>. /// </summary> /// <param name="original">The original <see cref="TagHelperBlock"/> to copy data from.</param> public TagHelperBlockBuilder(TagHelperBlock original) : base(original) { TagName = original.TagName; Descriptors = original.Descriptors; Attributes = new Dictionary<string, SyntaxTreeNode>(original.Attributes); }
/// <summary> /// Instantiates a new <see cref="TagHelperBlockBuilder"/> instance based on the given /// <paramref name="original"/>. /// </summary> /// <param name="original">The original <see cref="TagHelperBlock"/> to copy data from.</param> public TagHelperBlockBuilder(TagHelperBlock original) : base(original) { TagName = original.TagName; Descriptors = original.Descriptors; Attributes = new List<TagHelperAttributeNode>(original.Attributes); }
public override IReadOnlyList <TagHelperSpan> GetTagHelperSpans(RazorSyntaxTree syntaxTree) { if (syntaxTree == null) { throw new ArgumentNullException(nameof(syntaxTree)); } var results = new List <TagHelperSpan>(); List <Block> toProcess = new List <Block>(); List <Block> blockChildren = new List <Block>(); toProcess.Add(syntaxTree.Root); for (var i = 0; i < toProcess.Count; i++) { var blockNode = toProcess[i]; TagHelperBlock tagHelperNode = blockNode as TagHelperBlock; if (tagHelperNode != null) { results.Add(new TagHelperSpan( new SourceSpan( tagHelperNode.Start.FilePath ?? syntaxTree.Source.FilePath, tagHelperNode.Start.AbsoluteIndex, tagHelperNode.Start.LineIndex, tagHelperNode.Start.CharacterIndex, tagHelperNode.Length), tagHelperNode.Binding)); } // collect all child blocks and inject into toProcess as a single InsertRange foreach (SyntaxTreeNode curNode in blockNode.Children) { Block curBlock = curNode as Block; if (curBlock != null) { blockChildren.Add(curBlock); } } if (blockChildren.Count > 0) { toProcess.InsertRange(i + 1, blockChildren); blockChildren.Clear(); } } return(results); }
private static void EvaluateTagHelperBlock(ErrorCollector collector, TagHelperBlock actual, TagHelperBlock expected) { if (expected == null) { AddMismatchError(collector, actual, expected); } else { if (!string.Equals(expected.TagName, actual.TagName, StringComparison.Ordinal)) { collector.AddError( "{0} - FAILED :: TagName mismatch for TagHelperBlock :: ACTUAL: {1}", expected.TagName, actual.TagName); } if (expected.SelfClosing != actual.SelfClosing) { collector.AddError( "{0} - FAILED :: SelfClosing for TagHelperBlock {1} :: ACTUAL: {2}", expected.SelfClosing, actual.TagName, actual.SelfClosing); } var expectedAttributes = expected.Attributes.GetEnumerator(); var actualAttributes = actual.Attributes.GetEnumerator(); while (expectedAttributes.MoveNext()) { if (!actualAttributes.MoveNext()) { collector.AddError("{0} - FAILED :: No more attributes on this node", expectedAttributes.Current); } else { EvaluateTagHelperAttribute(collector, actualAttributes.Current, expectedAttributes.Current); } } while (actualAttributes.MoveNext()) { collector.AddError("End of Attributes - FAILED :: Found Attribute: {0}", actualAttributes.Current.Key); } } }
private List <Span> Flatten(RazorSyntaxTree syntaxTree) { var result = new List <Span>(); AppendFlattenedSpans(syntaxTree.Root, result); return(result); void AppendFlattenedSpans(SyntaxTreeNode node, List <Span> foundSpans) { Span spanNode = node as Span; if (spanNode != null) { foundSpans.Add(spanNode); } else { TagHelperBlock tagHelperNode = node as TagHelperBlock; if (tagHelperNode != null) { // These aren't in document order, sort them first and then dig in List <SyntaxTreeNode> attributeNodes = tagHelperNode.Attributes.Select(kvp => kvp.Value).Where(att => att != null).ToList(); attributeNodes.Sort((x, y) => x.Start.AbsoluteIndex.CompareTo(y.Start.AbsoluteIndex)); foreach (SyntaxTreeNode curNode in attributeNodes) { AppendFlattenedSpans(curNode, foundSpans); } } Block blockNode = node as Block; if (blockNode != null) { foreach (SyntaxTreeNode curNode in blockNode.Children) { AppendFlattenedSpans(curNode, foundSpans); } } } } }
private Span LocateOwner(Block root, SourceChange change) { // Ask each child recursively Span owner = null; foreach (SyntaxTreeNode element in root.Children) { if (element.Start.AbsoluteIndex > change.Span.AbsoluteIndex) { // too far break; } int elementLen = element.Length; if (element.Start.AbsoluteIndex + elementLen < change.Span.AbsoluteIndex) { // not far enough continue; } if (element.IsBlock) { Block block = element as Block; if (element.Start.AbsoluteIndex + elementLen == change.Span.AbsoluteIndex) { Span lastDescendant = block.FindLastDescendentSpan(); if ((lastDescendant == null) && (block is TagHelperBlock)) { TagHelperBlock tagHelperBlock = (TagHelperBlock)block; if (tagHelperBlock.SourceEndTag != null) { lastDescendant = tagHelperBlock.SourceEndTag.FindLastDescendentSpan(); } else if (tagHelperBlock.SourceStartTag != null) { lastDescendant = tagHelperBlock.SourceStartTag.FindLastDescendentSpan(); } } // Conceptually, lastDescendant should always be non-null, but runtime errs on some // cases and makes empty blocks. Runtime will fix these issues as we find them, but make // no guarantee that they catch them all. if (lastDescendant == null) { owner = LocateOwner(block, change); if (owner != null) { break; } } else if (lastDescendant.EditHandler.OwnsChange(lastDescendant, change)) { owner = lastDescendant; break; } } else { owner = LocateOwner(block, change); if (owner != null) { break; } } } else { Span span = element as Span; if (span.EditHandler.OwnsChange(span, change)) { owner = span; break; } } } if (owner == null) { TagHelperBlock tagHelperNode = root as TagHelperBlock; if (tagHelperNode != null) { Block sourceStartTag = tagHelperNode.SourceStartTag; Block sourceEndTag = tagHelperNode.SourceEndTag; if ((sourceStartTag.Start.AbsoluteIndex <= change.Span.AbsoluteIndex) && (sourceStartTag.Start.AbsoluteIndex + sourceStartTag.Length >= change.Span.AbsoluteIndex)) { // intersects the start tag return(LocateOwner(sourceStartTag, change)); } else if ((sourceEndTag.Start.AbsoluteIndex <= change.Span.AbsoluteIndex) && (sourceEndTag.Start.AbsoluteIndex + sourceEndTag.Length >= change.Span.AbsoluteIndex)) { // intersects the end tag return(LocateOwner(sourceEndTag, change)); } } } return(owner); }
private static void EvaluateTagHelperBlock(ErrorCollector collector, TagHelperBlock actual, TagHelperBlock expected) { if (expected == null) { AddMismatchError(collector, actual, expected); } else { if (!string.Equals(expected.TagName, actual.TagName, StringComparison.Ordinal)) { collector.AddError( "{0} - FAILED :: TagName mismatch for TagHelperBlock :: ACTUAL: {1}", expected.TagName, actual.TagName); } if (expected.TagMode != actual.TagMode) { collector.AddError( $"{expected.TagMode} - FAILED :: {nameof(TagMode)} for {nameof(TagHelperBlock)} " + $"{actual.TagName} :: ACTUAL: {actual.TagMode}"); } var expectedAttributes = expected.Attributes.GetEnumerator(); var actualAttributes = actual.Attributes.GetEnumerator(); while (expectedAttributes.MoveNext()) { if (!actualAttributes.MoveNext()) { collector.AddError("{0} - FAILED :: No more attributes on this node", expectedAttributes.Current); } else { EvaluateTagHelperAttribute(collector, actualAttributes.Current, expectedAttributes.Current); } } while (actualAttributes.MoveNext()) { collector.AddError("End of Attributes - FAILED :: Found Attribute: {0}", actualAttributes.Current.Key); } } }