Refactor ParserVisitor

We need the visitor to allow control over whether to recurse or not into
something. This change makes the old ParserVisitor class behave much more
like the newer IR Walkers.

We need this for the tokens refactor because IR lowering will not be just
a trivial visitor anymore in the future.
This commit is contained in:
Ryan Nowak 2017-02-16 14:11:56 -08:00
parent 075771a12d
commit bbeb485405
12 changed files with 103 additions and 174 deletions

View File

@ -38,7 +38,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
tree.Root.Accept(this);
}
public override void VisitStartDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
public override void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
if (_nestedLevel > 0)
{
@ -51,10 +51,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution
}
_nestedLevel++;
}
public override void VisitEndDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
_nestedLevel--;
}
}

View File

@ -96,30 +96,6 @@ namespace Microsoft.AspNetCore.Razor.Evolution
}
}
public override void VisitDirectiveToken(DirectiveTokenChunkGenerator chunkGenerator, Span span)
{
_builder.Add(new DirectiveTokenIRNode()
{
Content = span.Content,
Descriptor = chunkGenerator.Descriptor,
Source = BuildSourceSpanFromNode(span),
});
}
public override void VisitStartDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new DirectiveIRNode()
{
Name = chunkGenerator.Descriptor.Name,
Descriptor = chunkGenerator.Descriptor,
});
}
public override void VisitEndDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
_builder.Pop();
}
public override void VisitAddTagHelperSpan(AddTagHelperChunkGenerator chunkGenerator, Span span)
{
_builder.Push(new DirectiveIRNode()
@ -211,25 +187,32 @@ namespace Microsoft.AspNetCore.Razor.Evolution
{
if (_insideLineDirective)
{
base.VisitDirectiveToken(chunkGenerator, span);
_builder.Add(new DirectiveTokenIRNode()
{
Content = span.Content,
Descriptor = chunkGenerator.Descriptor,
Source = BuildSourceSpanFromNode(span),
});
}
}
public override void VisitStartDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
public override void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
if (chunkGenerator.Descriptor.Kind == DirectiveDescriptorKind.SingleLine)
{
_insideLineDirective = true;
base.VisitStartDirectiveBlock(chunkGenerator, block);
}
}
public override void VisitEndDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
if (_insideLineDirective)
{
_builder.Push(new DirectiveIRNode()
{
Name = chunkGenerator.Descriptor.Name,
Descriptor = chunkGenerator.Descriptor,
});
base.VisitDirectiveBlock(chunkGenerator, block);
_builder.Pop();
_insideLineDirective = false;
base.VisitEndDirectiveBlock(chunkGenerator, block);
}
}
}
@ -243,12 +226,35 @@ namespace Microsoft.AspNetCore.Razor.Evolution
{
}
public override void VisitDirectiveToken(DirectiveTokenChunkGenerator chunkGenerator, Span span)
{
_builder.Add(new DirectiveTokenIRNode()
{
Content = span.Content,
Descriptor = chunkGenerator.Descriptor,
Source = BuildSourceSpanFromNode(span),
});
}
public override void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new DirectiveIRNode()
{
Name = chunkGenerator.Descriptor.Name,
Descriptor = chunkGenerator.Descriptor,
});
VisitDefault(block);
_builder.Pop();
}
// Example
// <input` checked="hello-world @false"`/>
// Name=checked
// Prefix= checked="
// Suffix="
public override void VisitStartAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
public override void VisitAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new HtmlAttributeIRNode()
{
@ -257,10 +263,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution
Suffix = chunkGenerator.Suffix,
Source = BuildSourceSpanFromNode(block),
});
}
public override void VisitEndAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
_builder.Pop();
}
@ -268,17 +273,16 @@ namespace Microsoft.AspNetCore.Razor.Evolution
// <input checked="hello-world `@false`"/>
// Prefix= (space)
// Children will contain a token for @false.
public override void VisitStartDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
public override void VisitDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new CSharpAttributeValueIRNode()
{
Prefix = chunkGenerator.Prefix,
Source = BuildSourceSpanFromNode(block),
});
}
public override void VisitEndDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
_builder.Pop();
}
@ -292,14 +296,15 @@ namespace Microsoft.AspNetCore.Razor.Evolution
});
}
public override void VisitStartTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
public override void VisitTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new TemplateIRNode());
}
var templateNode = new TemplateIRNode();
_builder.Push(templateNode);
public override void VisitEndTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
{
var templateNode = _builder.Pop();
VisitDefault(block);
_builder.Pop();
if (templateNode.Children.Count > 0)
{
var sourceRangeStart = templateNode
@ -327,14 +332,14 @@ namespace Microsoft.AspNetCore.Razor.Evolution
// @DateTime.@*This is a comment*@Now
//
// We need to capture this in the IR so that we can give each piece the correct source mappings
public override void VisitStartExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
public override void VisitExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
{
_builder.Push(new CSharpExpressionIRNode());
}
var expressionNode = new CSharpExpressionIRNode();
_builder.Push(expressionNode);
public override void VisitEndExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
{
var expressionNode = _builder.Pop();
VisitDefault(block);
_builder.Pop();
if (expressionNode.Children.Count > 0)
{
@ -445,7 +450,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution
}
}
public override void VisitStartTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
public override void VisitTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
{
var tagHelperBlock = block as TagHelperBlock;
if (tagHelperBlock == null)
@ -471,15 +476,8 @@ namespace Microsoft.AspNetCore.Razor.Evolution
TagName = tagName,
TagMode = tagHelperBlock.TagMode
});
}
public override void VisitEndTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
{
var tagHelperBlock = block as TagHelperBlock;
if (tagHelperBlock == null)
{
return;
}
VisitDefault(block);
_builder.Pop(); // Pop InitializeTagHelperStructureIRNode

View File

@ -36,14 +36,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
//context.ChunkTreeBuilder.EndParentChunk();
}
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartAttributeBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndAttributeBlock(this, block);
visitor.VisitAttributeBlock(this, block);
}
public override string ToString()

View File

@ -17,15 +17,11 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
public DirectiveDescriptor Descriptor { get; }
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartDirectiveBlock(this, block);
visitor.VisitDirectiveBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndDirectiveBlock(this, block);
}
public override bool Equals(object obj)
{
var other = obj as DirectiveChunkGenerator;

View File

@ -23,14 +23,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
public SourceLocation ValueStart { get; }
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartDynamicAttributeBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndDynamicAttributeBlock(this, block);
visitor.VisitDynamicAttributeBlock(this, block);
}
public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)

View File

@ -29,14 +29,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
visitor.VisitExpressionSpan(this, span);
}
public void AcceptStart(ParserVisitor visitor, Block block)
public void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartExpressionBlock(this, block);
}
public void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndExpressionBlock(this, block);
visitor.VisitExpressionBlock(this, block);
}
public override string ToString()

View File

@ -7,7 +7,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
{
void GenerateStartParentChunk(Block target, ChunkGeneratorContext context);
void GenerateEndParentChunk(Block target, ChunkGeneratorContext context);
void AcceptStart(ParserVisitor visitor, Block block);
void AcceptEnd(ParserVisitor visitor, Block block);
void Accept(ParserVisitor visitor, Block block);
}
}

View File

@ -9,8 +9,7 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
public static readonly IParentChunkGenerator Null = new NullParentChunkGenerator();
public abstract void AcceptStart(ParserVisitor visitor, Block block);
public abstract void AcceptEnd(ParserVisitor visitor, Block block);
public abstract void Accept(ParserVisitor visitor, Block block);
public virtual void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)
{
@ -46,12 +45,12 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
return "None";
}
public void AcceptStart(ParserVisitor visitor, Block block)
{
}
public void AcceptEnd(ParserVisitor visitor, Block block)
public void Accept(ParserVisitor visitor, Block block)
{
for (var i = 0; i < block.Children.Count; i++)
{
block.Children[i].Accept(visitor);
}
}
}
}

View File

@ -5,31 +5,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
{
internal abstract class ParserVisitor
{
public virtual void VisitBlock(Block block)
protected virtual void VisitDefault(Block block)
{
VisitStartBlock(block);
for (var i = 0; i < block.Children.Count; i++)
{
block.Children[i].Accept(this);
}
VisitEndBlock(block);
}
public virtual void VisitStartBlock(Block block)
public virtual void VisitBlock(Block block)
{
if (block.ChunkGenerator != null)
{
block.ChunkGenerator.AcceptStart(this, block);
}
}
public virtual void VisitEndBlock(Block block)
{
if (block.ChunkGenerator != null)
{
block.ChunkGenerator.AcceptEnd(this, block);
block.ChunkGenerator.Accept(this, block);
}
}
@ -41,28 +29,19 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
}
}
public virtual void VisitStartDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
public virtual void VisitDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitEndDynamicAttributeBlock(DynamicAttributeBlockChunkGenerator chunkGenerator, Block block)
public virtual void VisitExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitStartExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitEndExpressionBlock(ExpressionChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitStartAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitEndAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
public virtual void VisitAttributeBlock(AttributeBlockChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitExpressionSpan(ExpressionChunkGenerator chunkGenerator, Span span)
@ -89,36 +68,24 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
{
}
public virtual void VisitEndTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
public virtual void VisitDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitStartDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
public virtual void VisitTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitEndDirectiveBlock(DirectiveChunkGenerator chunkGenerator, Block block)
public virtual void VisitCommentBlock(RazorCommentChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitStartTemplateBlock(TemplateBlockChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitEndCommentBlock(RazorCommentChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitStartCommentBlock(RazorCommentChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitStartTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
{
}
public virtual void VisitEndTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
public virtual void VisitTagHelperBlock(TagHelperChunkGenerator chunkGenerator, Block block)
{
VisitDefault(block);
}
public virtual void VisitAddTagHelperSpan(AddTagHelperChunkGenerator chunkGenerator, Span span)

View File

@ -5,14 +5,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
{
internal class RazorCommentChunkGenerator : ParentChunkGenerator
{
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartCommentBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndCommentBlock(this, block);
visitor.VisitCommentBlock(this, block);
}
}
}

View File

@ -84,14 +84,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
//context.ChunkTreeBuilder.EndParentChunk();
}
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartTagHelperBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndTagHelperBlock(this, block);
visitor.VisitTagHelperBlock(this, block);
}
}
}

View File

@ -5,14 +5,9 @@ namespace Microsoft.AspNetCore.Razor.Evolution.Legacy
{
internal class TemplateBlockChunkGenerator : ParentChunkGenerator
{
public override void AcceptStart(ParserVisitor visitor, Block block)
public override void Accept(ParserVisitor visitor, Block block)
{
visitor.VisitStartTemplateBlock(this, block);
}
public override void AcceptEnd(ParserVisitor visitor, Block block)
{
visitor.VisitEndTemplateBlock(this, block);
visitor.VisitTemplateBlock(this, block);
}
public override void GenerateStartParentChunk(Block target, ChunkGeneratorContext context)