Remove unneeded chunk data.

Instead lets keep utilizing the Context's state to properly generate a C# file.
This commit is contained in:
N. Taylor Mullen 2014-02-04 17:10:54 -08:00
parent 47b09a9f31
commit d85927166b
25 changed files with 104 additions and 83 deletions

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Razor.Generator
ns = ns.Substring(1);
}
codeTreeBuilder.AddUsingChunk(ns, target, context);
codeTreeBuilder.AddUsingChunk(ns, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
CodeAttributeChunk chunk = codeTreeBuilder.StartChunkBlock<CodeAttributeChunk>(target, context);
CodeAttributeChunk chunk = codeTreeBuilder.StartChunkBlock<CodeAttributeChunk>(target);
chunk.Attribute = Name;
chunk.Prefix = Prefix;

View File

@ -7,11 +7,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
public class CSharpCodeVisitor : CodeVisitor<CSharpCodeWriter>
{
private const string ValueWriterName = "__razor_attribute_value_writer";
private const string TemplateWriterName = "__razor_template_writer";
public CSharpCodeVisitor(CSharpCodeWriter writer, CodeGeneratorContext context)
: base(writer, context) { }
: base(writer, context)
{
}
protected override void Visit(SetLayoutChunk chunk)
{
@ -29,11 +30,16 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
Writer.Write(TemplateBlockCodeGenerator.ItemParameterName).Write(" => ")
.WriteStartNewObject(Context.Host.GeneratedClassContext.TemplateTypeName);
string currentTargetWriterName = Context.TargetWriterName;
Context.TargetWriterName = TemplateWriterName;
using (Writer.BuildLambda(endLine: false, parameterNames: TemplateBlockCodeGenerator.TemplateWriterName))
{
Visit((ChunkBlock)chunk);
}
Context.TargetWriterName = currentTargetWriterName;
Writer.WriteEndMethodInvocation(false).WriteLine();
}
@ -48,12 +54,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
if (!String.IsNullOrEmpty(chunk.Url) && !Context.Host.DesignTimeMode)
{
if (chunk.RenderingMode == ExpressionRenderingMode.WriteToOutput)
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
if (!String.IsNullOrEmpty(chunk.WriterName))
if (!String.IsNullOrEmpty(Context.TargetWriterName))
{
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralToMethodName)
.Write(chunk.WriterName)
.Write(Context.TargetWriterName)
.WriteParameterSeparator();
}
else
@ -66,7 +72,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
.WriteStringLiteral(chunk.Url)
.WriteEndMethodInvocation(endLine: false);
if (chunk.RenderingMode == ExpressionRenderingMode.WriteToOutput)
if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
Writer.WriteEndMethodInvocation();
}
@ -84,10 +90,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
if (!String.IsNullOrEmpty(chunk.Text) && !Context.Host.DesignTimeMode)
{
if (!String.IsNullOrEmpty(chunk.WriterName))
if (!String.IsNullOrEmpty(Context.TargetWriterName))
{
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteLiteralToMethodName)
.Write(chunk.WriterName)
.Write(Context.TargetWriterName)
.WriteParameterSeparator();
}
else
@ -107,7 +113,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
// TODO: Handle instrumentation
// TODO: Refactor
if (!Context.Host.DesignTimeMode && chunk.RenderingMode == ExpressionRenderingMode.InjectCode)
if (!Context.Host.DesignTimeMode && Context.ExpressionRenderingMode == ExpressionRenderingMode.InjectCode)
{
Visit((ChunkBlock)chunk);
}
@ -117,12 +123,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
{
Writer.WriteStartAssignment("__o");
}
else if (chunk.RenderingMode == ExpressionRenderingMode.WriteToOutput)
else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
if (!String.IsNullOrEmpty(chunk.WriterName))
if (!String.IsNullOrEmpty(Context.TargetWriterName))
{
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteToMethodName)
.Write(chunk.WriterName)
.Write(Context.TargetWriterName)
.WriteParameterSeparator();
}
else
@ -137,7 +143,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
{
Writer.WriteLine(";");
}
else if (chunk.RenderingMode == ExpressionRenderingMode.WriteToOutput)
else if (Context.ExpressionRenderingMode == ExpressionRenderingMode.WriteToOutput)
{
Writer.WriteEndMethodInvocation();
}
@ -170,6 +176,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
}
Chunk code = chunk.Children.FirstOrDefault();
ExpressionRenderingMode currentRenderingMode = Context.ExpressionRenderingMode;
string currentTargetWriterName = Context.TargetWriterName;
Context.TargetWriterName = ValueWriterName;
Writer.WriteParameterSeparator()
.WriteLine();
@ -181,6 +191,8 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
.WriteParameterSeparator()
.WriteStartMethodInvocation("Tuple.Create", new string[] { "System.Object", "System.Int32" });
Context.ExpressionRenderingMode = ExpressionRenderingMode.InjectCode;
Accept(code);
Writer.WriteParameterSeparator()
@ -211,6 +223,9 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
.WriteBooleanLiteral(false)
.WriteEndMethodInvocation(false);
}
Context.TargetWriterName = currentTargetWriterName;
Context.ExpressionRenderingMode = currentRenderingMode;
}
protected override void Visit(LiteralCodeAttributeChunk chunk)
@ -229,8 +244,13 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
{
Writer.WriteStartMethodInvocation("Tuple.Create", new string[] { "System.Object", "System.Int32" });
ExpressionRenderingMode currentRenderingMode = Context.ExpressionRenderingMode;
Context.ExpressionRenderingMode = ExpressionRenderingMode.InjectCode;
Visit((ChunkBlock)chunk);
Context.ExpressionRenderingMode = currentRenderingMode;
Writer.WriteParameterSeparator()
.Write(chunk.ValueLocation.AbsoluteIndex.ToString(CultureInfo.CurrentCulture))
.WriteEndMethodInvocation(false)
@ -255,10 +275,10 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
return; // Don't generate anything!
}
if (!String.IsNullOrEmpty(chunk.WriterName))
if (!String.IsNullOrEmpty(Context.TargetWriterName))
{
Writer.WriteStartMethodInvocation(Context.Host.GeneratedClassContext.WriteAttributeToMethodName)
.Write(chunk.WriterName)
.Write(Context.TargetWriterName)
.WriteParameterSeparator();
}
else

View File

@ -36,9 +36,14 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler.CSharp
lambdaScope = Writer.BuildLambda(endLine: false, parameterNames: HelperWriterName);
}
string currentTargetWriterName = Context.TargetWriterName;
Context.TargetWriterName = HelperWriterName;
// Generate children code
_codeVisitor.Accept(chunk.Children);
Context.TargetWriterName = currentTargetWriterName;
if (chunk.HeaderComplete)
{
lambdaScope.Dispose();

View File

@ -7,6 +7,5 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
{
public SourceLocation Start { get; set; }
public SyntaxTreeNode Association { get; set; }
public string WriterName { get; set; }
}
}

View File

@ -3,6 +3,5 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
{
public class ExpressionBlockChunk : ChunkBlock
{
public ExpressionRenderingMode RenderingMode { get; set; }
}
}

View File

@ -4,7 +4,6 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
public class ExpressionChunk : Chunk
{
public string Code { get; set; }
public ExpressionRenderingMode RenderingMode { get; set; }
public override string ToString()
{

View File

@ -4,6 +4,5 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
public class ResolveUrlChunk : Chunk
{
public string Url { get; set; }
public ExpressionRenderingMode RenderingMode { get; set; }
}
}

View File

@ -17,13 +17,12 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
public CodeTree CodeTree { get; private set; }
public void AddChunk(Chunk chunk, SyntaxTreeNode association, CodeGeneratorContext context, bool topLevel = false)
public void AddChunk(Chunk chunk, SyntaxTreeNode association, bool topLevel = false)
{
_lastChunk = chunk;
chunk.Start = association.Start;
chunk.Association = association;
chunk.WriterName = context.TargetWriterName;
// If we're not in the middle of a chunk block
if (_blockChain.Count == 0 || topLevel == true)
@ -36,7 +35,7 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
}
}
public void AddLiteralChunk(string literal, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddLiteralChunk(string literal, SyntaxTreeNode association)
{
if (_lastChunk is LiteralChunk)
{
@ -47,94 +46,92 @@ namespace Microsoft.AspNet.Razor.Generator.Compiler
AddChunk(new LiteralChunk
{
Text = literal,
}, association, context);
}, association);
}
}
public void AddExpressionChunk(string expression, ExpressionRenderingMode renderingMode, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddExpressionChunk(string expression, SyntaxTreeNode association)
{
AddChunk(new ExpressionChunk
{
Code = expression,
RenderingMode = renderingMode
}, association, context);
Code = expression
}, association);
}
public void AddStatementChunk(string code, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddStatementChunk(string code, SyntaxTreeNode association)
{
AddChunk(new StatementChunk
{
Code = code,
}, association, context);
}, association);
}
public void AddUsingChunk(string usingNamespace, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddUsingChunk(string usingNamespace, SyntaxTreeNode association)
{
AddChunk(new UsingChunk
{
Namespace = usingNamespace,
}, association, context, topLevel: true);
}, association, topLevel: true);
}
public void AddTypeMemberChunk(string code, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddTypeMemberChunk(string code, SyntaxTreeNode association)
{
AddChunk(new TypeMemberChunk
{
Code = code,
}, association, context, topLevel: true);
}, association, topLevel: true);
}
public void AddLiteralCodeAttributeChunk(string code, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddLiteralCodeAttributeChunk(string code, SyntaxTreeNode association)
{
AddChunk(new LiteralCodeAttributeChunk
{
Code = code,
}, association, context);
}, association);
}
public void AddResolveUrlChunk(string url, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddResolveUrlChunk(string url, SyntaxTreeNode association)
{
AddChunk(new ResolveUrlChunk
{
Url = url,
RenderingMode = context.ExpressionRenderingMode
}, association, context);
Url = url
}, association);
}
public void AddSetLayoutChunk(string layout, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddSetLayoutChunk(string layout, SyntaxTreeNode association)
{
AddChunk(new SetLayoutChunk
{
Layout = layout
}, association, context);
}, association);
}
public void AddSetBaseTypeChunk(string typeName, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddSetBaseTypeChunk(string typeName, SyntaxTreeNode association)
{
AddChunk(new SetBaseTypeChunk
{
TypeName = typeName.Trim()
}, association, context, topLevel: true);
}, association, topLevel: true);
}
public void AddSessionStateChunk(string value, SyntaxTreeNode association, CodeGeneratorContext context)
public void AddSessionStateChunk(string value, SyntaxTreeNode association)
{
AddChunk(new SessionStateChunk
{
Value = value
}, association, context, topLevel: true);
}, association, topLevel: true);
}
public T StartChunkBlock<T>(SyntaxTreeNode association, CodeGeneratorContext context) where T : ChunkBlock
public T StartChunkBlock<T>(SyntaxTreeNode association) where T : ChunkBlock
{
return StartChunkBlock<T>(association, context, topLevel: false);
return StartChunkBlock<T>(association, topLevel: false);
}
public T StartChunkBlock<T>(SyntaxTreeNode association, CodeGeneratorContext context, bool topLevel) where T : ChunkBlock
public T StartChunkBlock<T>(SyntaxTreeNode association, bool topLevel) where T : ChunkBlock
{
T chunk = (T)Activator.CreateInstance(typeof(T));
AddChunk(chunk, association, context, topLevel);
AddChunk(chunk, association, topLevel);
_blockChain.Push(chunk);

View File

@ -33,7 +33,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
DynamicCodeAttributeChunk chunk = codeTreeBuilder.StartChunkBlock<DynamicCodeAttributeChunk>(target, context);
DynamicCodeAttributeChunk chunk = codeTreeBuilder.StartChunkBlock<DynamicCodeAttributeChunk>(target);
chunk.Start = ValueStart;
chunk.Prefix = Prefix;
}

View File

@ -11,8 +11,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
ExpressionBlockChunk chunk = codeTreeBuilder.StartChunkBlock<ExpressionBlockChunk>(target, context);
chunk.RenderingMode = context.ExpressionRenderingMode;
ExpressionBlockChunk chunk = codeTreeBuilder.StartChunkBlock<ExpressionBlockChunk>(target);
}
public override void GenerateStartBlockCode(Block target, CodeGeneratorContext context)
@ -113,7 +112,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddExpressionChunk(target.Content, context.ExpressionRenderingMode, target, context);
codeTreeBuilder.AddExpressionChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -30,7 +30,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
HelperChunk chunk = codeTreeBuilder.StartChunkBlock<HelperChunk>(target, context, topLevel: true);
HelperChunk chunk = codeTreeBuilder.StartChunkBlock<HelperChunk>(target, topLevel: true);
chunk.Signature = Signature;
chunk.Footer = Footer;

View File

@ -34,7 +34,7 @@ namespace Microsoft.AspNet.Razor.Generator
return;
}
LiteralCodeAttributeChunk chunk = context.CodeTreeBuilder.StartChunkBlock<LiteralCodeAttributeChunk>(target, context);
LiteralCodeAttributeChunk chunk = context.CodeTreeBuilder.StartChunkBlock<LiteralCodeAttributeChunk>(target);
chunk.Prefix = Prefix;
chunk.Value = Value;

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddLiteralChunk(target.Content, target, context);
codeTreeBuilder.AddLiteralChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
if (Name == SyntaxConstants.CSharp.SessionStateKeyword)
{
codeTreeBuilder.AddSessionStateChunk(Value, target, context);
codeTreeBuilder.AddSessionStateChunk(Value, target);
}
}

View File

@ -10,7 +10,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddResolveUrlChunk(target.Content, target, context);
codeTreeBuilder.AddResolveUrlChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
SectionChunk chunk = codeTreeBuilder.StartChunkBlock<SectionChunk>(target, context);
SectionChunk chunk = codeTreeBuilder.StartChunkBlock<SectionChunk>(target);
chunk.Name = SectionName;
}

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddSetBaseTypeChunk(target.Content, target, context);
codeTreeBuilder.AddSetBaseTypeChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -18,7 +18,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddSetLayoutChunk(LayoutPath, target, context);
codeTreeBuilder.AddSetLayoutChunk(LayoutPath, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -9,7 +9,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddStatementChunk(target.Content, target, context);
codeTreeBuilder.AddStatementChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -14,7 +14,7 @@ namespace Microsoft.AspNet.Razor.Generator
public void GenerateStartBlockCode(SyntaxTreeNode target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.StartChunkBlock<TemplateChunk>(target, context);
codeTreeBuilder.StartChunkBlock<TemplateChunk>(target);
}
public override void GenerateStartBlockCode(Block target, CodeGeneratorContext context)

View File

@ -11,7 +11,7 @@ namespace Microsoft.AspNet.Razor.Generator
{
public void GenerateCode(Span target, CodeTreeBuilder codeTreeBuilder, CodeGeneratorContext context)
{
codeTreeBuilder.AddTypeMemberChunk(target.Content, target, context);
codeTreeBuilder.AddTypeMemberChunk(target.Content, target);
}
public override void GenerateCode(Span target, CodeGeneratorContext context)

View File

@ -16,8 +16,8 @@ namespace Microsoft.AspNet.Razor.Test.Generator.CodeTree
var language = new CSharpRazorCodeLanguage();
RazorEngineHost host = new RazorEngineHost(language);
var context = CodeGeneratorContext.Create(host, "TestClass", "TestNamespace", "Foo.cs", shouldGenerateLinePragmas: false);
context.CodeTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode, context);
context.CodeTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode, context);
context.CodeTreeBuilder.AddUsingChunk("FakeNamespace1", syntaxTreeNode);
context.CodeTreeBuilder.AddUsingChunk("FakeNamespace2.SubNamespace", syntaxTreeNode);
CodeBuilder codeBuilder = language.CreateBuilder(context);
// Act

View File

@ -11,7 +11,10 @@ namespace Microsoft.AspNet.Razor.Test.Generator
{
public static void ValidateResults(string codeTreeCode, string codeDOMCode, IList<LineMapping> codeTreeMappings, IDictionary<int, GeneratedCodeMapping> codeDOMMappings)
{
Assert.Equal(codeTreeMappings.Count, codeDOMMappings.Values.Count);
if (codeDOMMappings != null)
{
Assert.Equal(codeTreeMappings.Count, codeDOMMappings.Values.Count);
}
ValidateNamespace(codeTreeCode, codeDOMCode);
ValidateClass(codeTreeCode, codeDOMCode);

View File

@ -1,14 +1,15 @@
@helper foo(int bar)
{
<div>@bar</div>
}
@helper foo2(string bar)
{
<div>@bar</div>
@{
var ch = true;
var cls = "bar";
<a href="Foo" />
<p class="@cls" />
<p class="foo @cls" />
<p class="@cls foo" />
<input type="checkbox" checked="@ch" />
<input type="checkbox" checked="foo @ch" />
<p class="@if (cls != null) { @cls } />
<a href="~/Foo" />
<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
}
<span>Hello WOrld</span>
<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-2.0.6-development-only.js")" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js" type="text/javascript"></script>
}