Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
Refactor WriteAttribute \ AddHtmlAttribute
Browse files Browse the repository at this point in the history
Fixes #177
  • Loading branch information
pranavkm committed Sep 30, 2015
1 parent ef79922 commit 3e8b7b6
Show file tree
Hide file tree
Showing 11 changed files with 298 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,9 @@ public CSharpCodeWriter WriteStartNewObject(string typeName)

public CSharpCodeWriter WriteLocationTaggedString(LocationTagged<string> value)
{
WriteStartMethodInvocation("Tuple.Create");
WriteStringLiteral(value.Value);
WriteParameterSeparator();
Write(value.Location.AbsoluteIndex.ToString(CultureInfo.CurrentCulture));
WriteEndMethodInvocation(false);
Write(value.Location.AbsoluteIndex.ToString(CultureInfo.InvariantCulture));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using Microsoft.AspNet.Razor.Chunks;
Expand All @@ -26,6 +27,7 @@ public class CSharpTagHelperCodeRenderer
private readonly CodeGeneratorContext _context;
private readonly IChunkVisitor _bodyVisitor;
private readonly IChunkVisitor _literalBodyVisitor;
private readonly TagHelperAttributeCodeVisitor _attributeCodeVisitor;
private readonly GeneratedTagHelperContext _tagHelperContext;
private readonly bool _designTimeMode;

Expand Down Expand Up @@ -63,6 +65,7 @@ public CSharpTagHelperCodeRenderer(
_designTimeMode = context.Host.DesignTimeMode;

_literalBodyVisitor = new CSharpLiteralCodeVisitor(this, writer, context);
_attributeCodeVisitor = new TagHelperAttributeCodeVisitor(writer, context);
AttributeValueCodeRenderer = new TagHelperAttributeValueCodeRenderer();
}

Expand Down Expand Up @@ -467,15 +470,32 @@ private void RenderUnboundAttribute(string attributeName, Chunk attributeValueCh
// Dynamic attribute value should be run through the conditional attribute removal system. It's
// unbound and contains C#.

// TagHelper attribute rendering is buffered by default. We do not want to write to the current
// writer.
var currentTargetWriter = _context.TargetWriterName;
var currentWriteAttributeMethodName = _context.Host.GeneratedClassContext.WriteAttributeValueMethodName;
_context.TargetWriterName = null;

Debug.Assert(attributeValueChunk is ParentChunk);
var children = ((ParentChunk)attributeValueChunk).Children;
var attributeCount = children.Count(c => c is DynamicCodeAttributeChunk || c is LiteralCodeAttributeChunk);

_writer
.WriteStartMethodInvocation(_tagHelperContext.AddHtmlAttributeValuesMethodName)
.WriteStartMethodInvocation(_tagHelperContext.BeginAddHtmlAttributeValuesMethodName)
.Write(ExecutionContextVariableName)
.WriteParameterSeparator()
.WriteStringLiteral(attributeName)
.WriteParameterSeparator()
.Write(ExecutionContextVariableName);
.Write(attributeCount.ToString(CultureInfo.InvariantCulture))
.WriteEndMethodInvocation();

_bodyVisitor.Accept(attributeValueChunk);
_attributeCodeVisitor.Accept(attributeValueChunk);

_writer.WriteMethodInvocation(
_tagHelperContext.EndAddHtmlAttributeValuesMethodName,
ExecutionContextVariableName);

_writer.WriteEndMethodInvocation();
_context.TargetWriterName = currentTargetWriter;
}
else
{
Expand Down Expand Up @@ -722,5 +742,18 @@ protected override string WriteToMethodName
}
}
}

private class TagHelperAttributeCodeVisitor : CSharpCodeVisitor
{
public TagHelperAttributeCodeVisitor(
CSharpCodeWriter writer,
CodeGeneratorContext context)
: base(writer, context)
{
}

protected override string WriteAttributeValueMethodName =>
Context.Host.GeneratedClassContext.GeneratedTagHelperContext.AddHtmlAttributeValueMethodName;
}
}
}
98 changes: 58 additions & 40 deletions src/Microsoft.AspNet.Razor/CodeGenerators/GeneratedClassContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,25 @@ public struct GeneratedClassContext
public static readonly string DefaultWriteMethodName = "Write";
public static readonly string DefaultWriteLiteralMethodName = "WriteLiteral";
public static readonly string DefaultExecuteMethodName = "ExecuteAsync";
public static readonly string DefaultWriteAttributeMethodName = "WriteAttribute";
public static readonly string DefaultWriteAttributeToMethodName = "WriteAttributeTo";
public static readonly string DefaultBeginWriteAttributeMethodName = "BeginWriteAttribute";
public static readonly string DefaultBeginWriteAttributeToMethodName = "BeginWriteAttributeTo";
public static readonly string DefaultEndWriteAttributeMethodName = "EndWriteAttribute";
public static readonly string DefaultEndWriteAttributeToMethodName = "EndWriteAttributeTo";
public static readonly string DefaultWriteAttributeValueMethodName = "WriteAttributeValue";
public static readonly string DefaultWriteAttributeValueToMethodName = "WriteAttributeValueTo";

public static readonly GeneratedClassContext Default =
new GeneratedClassContext(DefaultExecuteMethodName,
DefaultWriteMethodName,
DefaultWriteLiteralMethodName,
new GeneratedTagHelperContext());

public GeneratedClassContext(string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
new GeneratedClassContext(
DefaultExecuteMethodName,
DefaultWriteMethodName,
DefaultWriteLiteralMethodName,
new GeneratedTagHelperContext());

public GeneratedClassContext(
string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
: this()
{
if (generatedTagHelperContext == null)
Expand Down Expand Up @@ -61,17 +67,22 @@ public GeneratedClassContext(string executeMethodName,
TemplateTypeName = null;
DefineSectionMethodName = null;

WriteAttributeMethodName = DefaultWriteAttributeMethodName;
WriteAttributeToMethodName = DefaultWriteAttributeToMethodName;
BeginWriteAttributeMethodName = DefaultBeginWriteAttributeMethodName;
BeginWriteAttributeToMethodName = DefaultBeginWriteAttributeToMethodName;
EndWriteAttributeMethodName = DefaultEndWriteAttributeMethodName;
EndWriteAttributeToMethodName = DefaultEndWriteAttributeToMethodName;
WriteAttributeValueMethodName = DefaultWriteAttributeValueMethodName;
WriteAttributeValueToMethodName = DefaultWriteAttributeValueToMethodName;
}

public GeneratedClassContext(string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
GeneratedTagHelperContext generatedTagHelperContext)
public GeneratedClassContext(
string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
GeneratedTagHelperContext generatedTagHelperContext)
: this(executeMethodName,
writeMethodName,
writeLiteralMethodName,
Expand All @@ -82,14 +93,15 @@ public GeneratedClassContext(string executeMethodName,
TemplateTypeName = templateTypeName;
}

public GeneratedClassContext(string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
string defineSectionMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
public GeneratedClassContext(
string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
string defineSectionMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
: this(executeMethodName,
writeMethodName,
writeLiteralMethodName,
Expand All @@ -101,16 +113,17 @@ public GeneratedClassContext(string executeMethodName,
DefineSectionMethodName = defineSectionMethodName;
}

public GeneratedClassContext(string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
string defineSectionMethodName,
string beginContextMethodName,
string endContextMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
public GeneratedClassContext(
string executeMethodName,
string writeMethodName,
string writeLiteralMethodName,
string writeToMethodName,
string writeLiteralToMethodName,
string templateTypeName,
string defineSectionMethodName,
string beginContextMethodName,
string endContextMethodName,
GeneratedTagHelperContext generatedTagHelperContext)
: this(executeMethodName,
writeMethodName,
writeLiteralMethodName,
Expand All @@ -137,8 +150,13 @@ public GeneratedClassContext(string executeMethodName,
public string EndContextMethodName { get; set; }
public string DefineSectionMethodName { get; set; }
public string TemplateTypeName { get; set; }
public string WriteAttributeMethodName { get; set; }
public string WriteAttributeToMethodName { get; set; }

public string BeginWriteAttributeMethodName { get; set; }
public string BeginWriteAttributeToMethodName { get; set; }
public string EndWriteAttributeMethodName { get; set; }
public string EndWriteAttributeToMethodName { get; set; }
public string WriteAttributeValueMethodName { get; set; }
public string WriteAttributeValueToMethodName { get; set; }

public bool AllowSections
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ public class GeneratedTagHelperContext
/// </summary>
public GeneratedTagHelperContext()
{
AddHtmlAttributeValuesMethodName = "AddHtmlAttributeValues";
BeginAddHtmlAttributeValuesMethodName = "BeginAddHtmlAttributeValues";
EndAddHtmlAttributeValuesMethodName = "EndAddHtmlAttributeValues";
AddHtmlAttributeValueMethodName = "AddHtmlAttributeValue";
CreateTagHelperMethodName = "CreateTagHelper";
RunnerRunAsyncMethodName = "RunAsync";
ScopeManagerBeginMethodName = "Begin";
Expand All @@ -38,18 +40,48 @@ public GeneratedTagHelperContext()
}

/// <summary>
/// The name of the method used to add unbound, complex tag helper attributes to TagHelperExecutionContexts.
/// The name of the method used to begin the addition of unbound, complex tag helper attributes to
/// TagHelperExecutionContexts.
/// </summary>
/// <remarks>
/// Method signature should be
/// <code>
/// public void AddHtmlAttributeValues(
/// string attributeName,
/// public void BeginAddHtmlAttributeValues(
/// TagHelperExecutionContext executionContext,
/// params Microsoft.AspNet.Mvc.Razor.AttributeValue[] values)
/// string attributeName)
/// </code>
/// </remarks>
public string BeginAddHtmlAttributeValuesMethodName { get; set; }

/// <summary>
/// Method name used to end addition of unbound, complex tag helper attributes to TagHelperExecutionContexts.
/// </summary>
/// <remarks>
/// Method signature should be
/// <code>
/// public void EndAddHtmlAttributeValues(
/// TagHelperExecutionContext executionContext)
/// </code>
/// </remarks>
public string EndAddHtmlAttributeValuesMethodName { get; set; }

/// <summary>
/// Method name used to add individual components of an unbound, complex tag helper attribute to
/// TagHelperExecutionContexts.
/// </summary>
/// <remarks>
/// Method signature:
/// <code>
/// public void AddHtmlAttributeValues(
/// string prefix,
/// int prefixOffset,
/// string value,
/// int valueOffset,
/// int valueLength,
/// bool isLiteral)
/// </code>
/// </remarks>
public string AddHtmlAttributeValuesMethodName { get; set; }
public string AddHtmlAttributeValueMethodName { get; set; }

/// <summary>
/// The name of the method used to create a tag helper.
Expand Down
Loading

0 comments on commit 3e8b7b6

Please sign in to comment.